ensure we always log all certificates
Bug: b/333426905
Change-Id: I13104465114db9d8f702f42b1b9e001e67f70e06
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/57180
Reviewed-by: Xilai Zhang <xilaizhang@google.com>
Commit-Queue: Christopher Fujino <fujino@google.com>
diff --git a/recipe_modules/signing/resources/setup_keychain.sh b/recipe_modules/signing/resources/setup_keychain.sh
index e4f6634..97027fc 100755
--- a/recipe_modules/signing/resources/setup_keychain.sh
+++ b/recipe_modules/signing/resources/setup_keychain.sh
@@ -1,5 +1,4 @@
#!/usr/bin/env dart
-
// Helper script to import a flutter p12 identity.
import 'dart:io' as io;
@@ -9,7 +8,8 @@
const int totalRetryAttempts = 3;
Future<void> main() async {
- final io.File logFile = io.File(io.Platform.environment['SETUP_KEYCHAIN_LOGS_PATH']!);
+ final io.File logFile =
+ io.File(io.Platform.environment['SETUP_KEYCHAIN_LOGS_PATH']!);
final logSink = logFile.openWrite();
void log(String line) {
logSink.writeln('$line\n');
@@ -38,7 +38,7 @@
required String codesignPath,
required void Function(String) log,
}) async {
- String security(List<String> args) {
+ String security(List<String> args, {bool allowNonzero = false}) {
log('Executing ${<String>['/usr/bin/security', ...args]}');
final io.ProcessResult result =
@@ -48,7 +48,7 @@
log('STDOUT:\n\n${result.stdout}');
log('STDERR:\n\n${result.stderr}');
- if (result.exitCode != 0) {
+ if (!allowNonzero && result.exitCode != 0) {
throw io.ProcessException(
'/usr/bin/security', args, 'failed', result.exitCode);
}
@@ -56,96 +56,99 @@
return result.stdout as String;
}
- final String rawPassword = io.File(passwordPath).readAsStringSync();
+ try {
+ final String rawPassword = io.File(passwordPath).readAsStringSync();
- // Only filepath with a .p12 suffix will be recognized
- io.File(flutterP12Path).renameSync(p12SuffixFilePath);
+ // Only filepath with a .p12 suffix will be recognized
+ io.File(flutterP12Path).renameSync(p12SuffixFilePath);
- // Delete build.keychain if it exists
- security(const <String>['delete-keychain', keychainName]);
+ // Delete build.keychain if it exists
+ security(const <String>['delete-keychain', keychainName], allowNonzero: true);
- // Create keychain.
- security(const <String>[
- 'create-keychain',
- '-p',
- keychainPassword,
- keychainName,
- ]);
-
- // Retrieve current list of keychains on the search list of current machine.
- final keychains = security(const <String>['list-keychains', '-d', 'user'])
- .split('\n')
- .map<String?>((String line) {
- final RegExp pattern = RegExp(r'^\s*".*\/([a-zA-Z0-9.]+)-db"');
- final RegExpMatch? match = pattern.firstMatch(line);
- if (match == null) {
- return null;
- }
- // The first (and only) capture group is the name of the keychain
- return match.group(1);
- }).whereType<String>();
-
- print('User keychains on this machine: $keychains');
-
- // Add keychain name to search list.
- // Without this, future commands such as `security import`,
- // `security find-identity` and `codesign ...` will fail to find the cert
- // in our newly created keychain.
- security(<String>[
- '-v',
- 'list-keychains',
- // TODO(fujino): we probably don't need $keychains here, only keychainName should be required
- '-s', ...keychains, keychainName,
- ]);
-
- // Set $keychainName as default.
- security(<String>[
- 'default-keychain',
- '-s',
- keychainName,
- ]);
-
- // Unlock keychainName to allow sign commands to use its certs.
- security(<String>['unlock-keychain', '-p', keychainPassword, keychainName]);
-
- // This will be exponentially increased on retries
- int sleepSeconds = 2;
-
- for (int attempt = 0; attempt < totalRetryAttempts; attempt++) {
- security(<String>[
- 'import',
- p12SuffixFilePath,
- '-k', keychainName,
- '-P', rawPassword,
- // -T allows the specified program to access this identity
- '-T', codesignPath,
- '-T', '/usr/bin/codesign',
- ]);
- security(<String>[
- 'set-key-partition-list',
- '-S',
- 'apple-tool:,apple:,codesign:',
- '-s',
- '-k',
- '',
+ // Create keychain.
+ security(const <String>[
+ 'create-keychain',
+ '-p',
+ keychainPassword,
keychainName,
]);
- final String identities =
- security(const <String>['find-identity', '-v', keychainName]);
- if (identities.contains('FLUTTER.IO LLC')) {
- log('successfully found a Flutter identity in the $keychainName keychain');
- return 0;
+ // Retrieve current list of keychains on the search list of current machine.
+ final keychains = security(const <String>['list-keychains', '-d', 'user'])
+ .split('\n')
+ .map<String?>((String line) {
+ final RegExp pattern = RegExp(r'^\s*".*\/([a-zA-Z0-9.]+)-db"');
+ final RegExpMatch? match = pattern.firstMatch(line);
+ if (match == null) {
+ return null;
+ }
+ // The first (and only) capture group is the name of the keychain
+ return match.group(1);
+ }).whereType<String>();
+
+ print('User keychains on this machine: $keychains');
+
+ // Add keychain name to search list.
+ // Without this, future commands such as `security import`,
+ // `security find-identity` and `codesign ...` will fail to find the cert
+ // in our newly created keychain.
+ security(<String>[
+ '-v',
+ 'list-keychains',
+ // TODO(fujino): we probably don't need $keychains here, only keychainName should be required
+ '-s', ...keychains, keychainName,
+ ]);
+
+ // Set $keychainName as default.
+ security(<String>[
+ 'default-keychain',
+ '-s',
+ keychainName,
+ ]);
+
+ // Unlock keychainName to allow sign commands to use its certs.
+ security(<String>['unlock-keychain', '-p', keychainPassword, keychainName]);
+
+ // This will be exponentially increased on retries
+ int sleepSeconds = 2;
+
+ for (int attempt = 0; attempt < totalRetryAttempts; attempt++) {
+ security(<String>[
+ 'import',
+ p12SuffixFilePath,
+ '-k', keychainName,
+ '-P', rawPassword,
+ // -T allows the specified program to access this identity
+ '-T', codesignPath,
+ '-T', '/usr/bin/codesign',
+ ]);
+ security(<String>[
+ 'set-key-partition-list',
+ '-S',
+ 'apple-tool:,apple:,codesign:',
+ '-s',
+ '-k',
+ '',
+ keychainName,
+ ]);
+
+ final String identities =
+ security(const <String>['find-identity', '-v', keychainName]);
+ if (identities.contains('FLUTTER.IO LLC')) {
+ log('successfully found a Flutter identity in the $keychainName keychain');
+ return 0;
+ }
+ log('failed to find a Flutter identity in the $keychainName keychain on attempt $attempt');
+ await Future<void>.delayed(Duration(seconds: sleepSeconds));
+ sleepSeconds *= sleepSeconds;
}
- log('failed to find a Flutter identity in the $keychainName keychain on attempt $attempt');
- await Future<void>.delayed(Duration(seconds: sleepSeconds));
- sleepSeconds *= sleepSeconds;
+ } finally {
+ security(const <String>[
+ 'find-certificate',
+ // Find all matching certificates, not just the first
+ '-a',
+ ]);
}
log('failed to find a Flutter identity after $totalRetryAttempts attempts.');
- security(const <String>[
- 'find-certificate',
- // Find all matching certificates, not just the first
- '-a',
- ]);
return 1;
}