fix(shorebird_cli): handle case where IPA generation failed with exit code 0 (#618)

This commit is contained in:
Bryan Oltman
2023-06-09 12:28:03 -04:00
committed by GitHub
parent 95cbde5894
commit a2352fab4e
4 changed files with 92 additions and 6 deletions
+4 -4
View File
@@ -64,10 +64,10 @@ runs:
dart pub global activate coverage
dart test -j ${{inputs.concurrency}} --coverage=coverage --platform=${{inputs.platform}} && dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=${{inputs.report_on}} --check-ignore
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
# - name: Upload Coverage
# uses: codecov/codecov-action@v3
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
- uses: VeryGoodOpenSource/very_good_coverage@v2
with:
@@ -75,7 +75,11 @@ make smaller updates to your app.
try {
await buildIpa(flavor: flavor);
} on ProcessException catch (error) {
buildProgress.fail('Failed to build: ${error.message}');
buildProgress.fail('Failed to build IPA: ${error.message}');
return ExitCode.software.code;
} on BuildException catch (error) {
buildProgress.fail('Failed to build IPA');
logger.err(error.message);
return ExitCode.software.code;
}
@@ -24,6 +24,17 @@ class ArchMetadata {
final String enginePath;
}
/// {@template build_exception}
/// Thrown when a build fails.
/// {@endtemplate}
class BuildException implements Exception {
/// {@macro build_exception}
BuildException(this.message);
/// Information about the build failure.
final String message;
}
mixin ShorebirdBuildMixin on ShorebirdCommand {
// This exists only so tests can get the full list.
static const allAndroidArchitectures = <Arch, ArchMetadata>{
@@ -182,9 +193,42 @@ mixin ShorebirdBuildMixin on ShorebirdCommand {
result.stderr.toString(),
result.exitCode,
);
} else if (result.stderr
.toString()
.contains('Encountered error while creating the IPA')) {
final errorMessage = _failedToCreateIpaErrorMessage(
stderr: result.stderr.toString(),
);
throw BuildException(errorMessage);
}
}
String _failedToCreateIpaErrorMessage({required String stderr}) {
// The full error text consists of many repeated lines of the format:
// (newlines added for line length)
//
// error: exportArchive: No signing certificate "iOS Distribution" found
// error: exportArchive: Communication with Apple failed
// error: exportArchive: No signing certificate "iOS Distribution" found
// error: exportArchive: Team "My Team" does not have permission to
// create "iOS App Store" provisioning profiles.
// error: exportArchive: No profiles for 'com.example.demo' were found
// error: exportArchive: Communication with Apple failed
// error: exportArchive: No signing certificate "iOS Distribution" found
// error: exportArchive: Communication with Apple failed
final exportArchiveRegex = RegExp(r'^error: exportArchive: (.+)$');
return stderr
.split('\n')
.map((l) => l.trim())
.toSet()
.map(exportArchiveRegex.firstMatch)
.whereType<Match>()
.map((m) => ' ${m.group(1)!}')
.join('\n');
}
Future<String> createDiff({
required String releaseArtifactPath,
required String patchArtifactPath,
@@ -227,7 +227,8 @@ flutter:
expect(exitCode, equals(ExitCode.noUser.code));
});
test('exits with code 70 when building fails', () async {
test('exits with code 70 when build fails with non-zero exit code',
() async {
when(() => flutterBuildProcessResult.exitCode).thenReturn(1);
when(() => flutterBuildProcessResult.stderr).thenReturn('oops');
@@ -243,6 +244,43 @@ flutter:
).called(1);
});
test('exits with code 70 when building fails with 0 exit code', () async {
when(() => flutterBuildProcessResult.exitCode).thenReturn(0);
when(() => flutterBuildProcessResult.stderr).thenReturn('''
Encountered error while creating the IPA:
error: exportArchive: Communication with Apple failed
error: exportArchive: No signing certificate "iOS Distribution" found
error: exportArchive: Communication with Apple failed
error: exportArchive: No signing certificate "iOS Distribution" found
error: exportArchive: Team "My Team" does not have permission to create "iOS App Store" provisioning profiles.
error: exportArchive: No profiles for 'com.example.co' were found
error: exportArchive: Communication with Apple failed
error: exportArchive: No signing certificate "iOS Distribution" found
error: exportArchive: Communication with Apple failed
error: exportArchive: No signing certificate "iOS Distribution" found
error: exportArchive: Communication with Apple failed
error: exportArchive: No signing certificate "iOS Distribution" found
''');
final tempDir = setUpTempDir();
final exitCode = await IOOverrides.runZoned(
() => runWithOverrides(command.run),
getCurrentDirectory: () => tempDir,
);
expect(exitCode, equals(ExitCode.software.code));
verify(
() => progress.fail(any(that: contains('Failed to build'))),
).called(1);
verify(
() => logger.err('''
Communication with Apple failed
No signing certificate "iOS Distribution" found
Team "My Team" does not have permission to create "iOS App Store" provisioning profiles.
No profiles for 'com.example.co' were found'''),
).called(1);
});
test('exits with code 70 when release version cannot be determiend',
() async {
when(() => ipa.versionNumber).thenThrow(Exception('oops'));