Unverified Commit 45653956 authored by xster's avatar xster Committed by GitHub

Let iOS auto-signing tool handle Googler scenario (#16010)

* Let iOS auto-signing tool handle Googler scenario

* Forgot to update tests
parent fb37bd13
...@@ -83,9 +83,15 @@ final RegExp _certificateOrganizationalUnitExtractionPattern = new RegExp(r'OU=( ...@@ -83,9 +83,15 @@ final RegExp _certificateOrganizationalUnitExtractionPattern = new RegExp(r'OU=(
/// signing identities in the user's keychain prompting a choice if multiple /// signing identities in the user's keychain prompting a choice if multiple
/// are found. /// are found.
/// ///
/// Returns a set of build configuration settings that uses the selected
/// signing identities.
///
/// Will return null if none are found, if the user cancels or if the Xcode /// Will return null if none are found, if the user cancels or if the Xcode
/// project has a development team set in the project's build settings. /// project has a development team set in the project's build settings.
Future<String> getCodeSigningIdentityDevelopmentTeam({BuildableIOSApp iosApp, bool usesTerminalUi: true}) async{ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({
BuildableIOSApp iosApp,
bool usesTerminalUi: true
}) async{
if (iosApp.buildSettings == null) if (iosApp.buildSettings == null)
return null; return null;
...@@ -154,9 +160,19 @@ Future<String> getCodeSigningIdentityDevelopmentTeam({BuildableIOSApp iosApp, bo ...@@ -154,9 +160,19 @@ Future<String> getCodeSigningIdentityDevelopmentTeam({BuildableIOSApp iosApp, bo
if (await opensslProcess.exitCode != 0) if (await opensslProcess.exitCode != 0)
return null; return null;
return _certificateOrganizationalUnitExtractionPattern final Map<String, String> signingConfigs = <String, String> {
'DEVELOPMENT_TEAM': _certificateOrganizationalUnitExtractionPattern
.firstMatch(opensslOutput) .firstMatch(opensslOutput)
?.group(1); ?.group(1),
};
if (opensslOutput.contains('iPhone Developer: Google Development')) {
signingConfigs['PROVISIONING_PROFILE_SPECIFIER'] = 'Google Development';
signingConfigs['CODE_SIGN_STYLE'] = 'Manual';
printStatus("Manually selecting Google's mobile provisioning profile (see go/google-flutter-signing).");
}
return signingConfigs;
} }
Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, bool usesTerminalUi) async { Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, bool usesTerminalUi) async {
......
...@@ -225,9 +225,9 @@ Future<XcodeBuildResult> buildXcodeProject({ ...@@ -225,9 +225,9 @@ Future<XcodeBuildResult> buildXcodeProject({
return new XcodeBuildResult(success: false); return new XcodeBuildResult(success: false);
} }
String developmentTeam; Map<String, String> autoSigningConfigs;
if (codesign && buildForDevice) if (codesign && buildForDevice)
developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app, usesTerminalUi: usesTerminalUi); autoSigningConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app, usesTerminalUi: usesTerminalUi);
// Before the build, all service definitions must be updated and the dylibs // Before the build, all service definitions must be updated and the dylibs
// copied over to a location that is suitable for Xcodebuild to find them. // copied over to a location that is suitable for Xcodebuild to find them.
...@@ -287,8 +287,10 @@ Future<XcodeBuildResult> buildXcodeProject({ ...@@ -287,8 +287,10 @@ Future<XcodeBuildResult> buildXcodeProject({
buildCommands.add('-quiet'); buildCommands.add('-quiet');
} }
if (developmentTeam != null) { if (autoSigningConfigs != null) {
buildCommands.add('DEVELOPMENT_TEAM=$developmentTeam'); for (MapEntry<String, String> signingConfig in autoSigningConfigs.entries) {
buildCommands.add('${signingConfig.key}=${signingConfig.value}');
}
buildCommands.add('-allowProvisioningUpdates'); buildCommands.add('-allowProvisioningUpdates');
buildCommands.add('-allowProvisioningDeviceRegistration'); buildCommands.add('-allowProvisioningDeviceRegistration');
} }
......
...@@ -38,8 +38,8 @@ void main() { ...@@ -38,8 +38,8 @@ void main() {
testUsingContext('No auto-sign if Xcode project settings are not available', () async { testUsingContext('No auto-sign if Xcode project settings are not available', () async {
app = new BuildableIOSApp(projectBundleId: 'test.app'); app = new BuildableIOSApp(projectBundleId: 'test.app');
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect(developmentTeam, isNull); expect(signingConfigs, isNull);
}); });
testUsingContext('No discovery if development team specified in Xcode project', () async { testUsingContext('No discovery if development team specified in Xcode project', () async {
...@@ -49,8 +49,8 @@ void main() { ...@@ -49,8 +49,8 @@ void main() {
'DEVELOPMENT_TEAM': 'abc', 'DEVELOPMENT_TEAM': 'abc',
}, },
); );
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect(developmentTeam, isNull); expect(signingConfigs, isNull);
expect(testLogger.statusText, equals( expect(testLogger.statusText, equals(
'Automatically signing iOS for device deployment using specified development team in Xcode project: abc\n' 'Automatically signing iOS for device deployment using specified development team in Xcode project: abc\n'
)); ));
...@@ -59,8 +59,8 @@ void main() { ...@@ -59,8 +59,8 @@ void main() {
testUsingContext('No auto-sign if security or openssl not available', () async { testUsingContext('No auto-sign if security or openssl not available', () async {
when(mockProcessManager.runSync(<String>['which', 'security'])) when(mockProcessManager.runSync(<String>['which', 'security']))
.thenReturn(exitsFail); .thenReturn(exitsFail);
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect(developmentTeam, isNull); expect(signingConfigs, isNull);
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
...@@ -75,12 +75,12 @@ void main() { ...@@ -75,12 +75,12 @@ void main() {
argThat(contains('find-identity')), environment: any, workingDirectory: any) argThat(contains('find-identity')), environment: any, workingDirectory: any)
).thenReturn(exitsHappy); ).thenReturn(exitsHappy);
String developmentTeam; Map<String, String> signingConfigs;
try { try {
developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
fail('No identity should throw tool error'); fail('No identity should throw tool error');
} on ToolExit { } on ToolExit {
expect(developmentTeam, isNull); expect(signingConfigs, isNull);
expect(testLogger.errorText, contains('No valid code signing certificates were found')); expect(testLogger.errorText, contains('No valid code signing certificates were found'));
} }
}, },
...@@ -132,12 +132,71 @@ void main() { ...@@ -132,12 +132,71 @@ void main() {
when(mockProcess.stderr).thenAnswer((Invocation invocation) => mockStdErr); when(mockProcess.stderr).thenAnswer((Invocation invocation) => mockStdErr);
when(mockProcess.exitCode).thenReturn(0); when(mockProcess.exitCode).thenReturn(0);
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect(testLogger.statusText, contains('iPhone Developer: Profile 1 (1111AAAA11)')); expect(testLogger.statusText, contains('iPhone Developer: Profile 1 (1111AAAA11)'));
expect(testLogger.errorText, isEmpty); expect(testLogger.errorText, isEmpty);
verify(mockStdIn.write('This is a mock certificate')); verify(mockStdIn.write('This is a mock certificate'));
expect(developmentTeam, '3333CCCC33'); expect(signingConfigs, <String, String> {'DEVELOPMENT_TEAM': '3333CCCC33'});
},
overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
});
testUsingContext('Test Google cert also manually selects a provisioning profile', () async {
when(mockProcessManager.runSync(<String>['which', 'security']))
.thenReturn(exitsHappy);
when(mockProcessManager.runSync(<String>['which', 'openssl']))
.thenReturn(exitsHappy);
when(mockProcessManager.runSync(
argThat(contains('find-identity')), environment: any, workingDirectory: any,
)).thenReturn(new ProcessResult(
1, // pid
0, // exitCode
'''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "iPhone Developer: Google Development (1111AAAA11)"
1 valid identities found''',
''
));
when(mockProcessManager.runSync(
<String>['security', 'find-certificate', '-c', '1111AAAA11', '-p'],
environment: any,
workingDirectory: any,
)).thenReturn(new ProcessResult(
1, // pid
0, // exitCode
'This is a mock certificate',
'',
));
final MockProcess mockProcess = new MockProcess();
final MockStdIn mockStdIn = new MockStdIn();
final MockStream mockStdErr = new MockStream();
when(mockProcessManager.start(
argThat(contains('openssl')), environment: any, workingDirectory: any,
)).thenAnswer((Invocation invocation) => new Future<Process>.value(mockProcess));
when(mockProcess.stdin).thenReturn(mockStdIn);
when(mockProcess.stdout)
.thenAnswer((Invocation invocation) => new Stream<List<int>>.fromFuture(
new Future<List<int>>.value(utf8.encode(
'subject= /CN=iPhone Developer: Google Development (1111AAAA11)/OU=3333CCCC33/O=My Team/C=US'
))
));
when(mockProcess.stderr).thenAnswer((Invocation invocation) => mockStdErr);
when(mockProcess.exitCode).thenReturn(0);
final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect(testLogger.statusText, contains('iPhone Developer: Google Development (1111AAAA11)'));
expect(testLogger.errorText, isEmpty);
verify(mockStdIn.write('This is a mock certificate'));
expect(signingConfigs, <String, String> {
'DEVELOPMENT_TEAM': '3333CCCC33',
'PROVISIONING_PROFILE_SPECIFIER': 'Google Development',
'CODE_SIGN_STYLE': 'Manual',
});
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
...@@ -191,7 +250,7 @@ void main() { ...@@ -191,7 +250,7 @@ void main() {
when(mockOpenSslProcess.stderr).thenAnswer((Invocation invocation) => mockOpenSslStdErr); when(mockOpenSslProcess.stderr).thenAnswer((Invocation invocation) => mockOpenSslStdErr);
when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0)); when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0));
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect( expect(
testLogger.statusText, testLogger.statusText,
...@@ -203,7 +262,7 @@ void main() { ...@@ -203,7 +262,7 @@ void main() {
); );
expect(testLogger.errorText, isEmpty); expect(testLogger.errorText, isEmpty);
verify(mockOpenSslStdIn.write('This is a mock certificate')); verify(mockOpenSslStdIn.write('This is a mock certificate'));
expect(developmentTeam, '4444DDDD44'); expect(signingConfigs, <String, String> {'DEVELOPMENT_TEAM':'4444DDDD44'});
verify(config.setValue('ios-signing-cert', 'iPhone Developer: Profile 3 (3333CCCC33)')); verify(config.setValue('ios-signing-cert', 'iPhone Developer: Profile 3 (3333CCCC33)'));
}, },
...@@ -261,7 +320,7 @@ void main() { ...@@ -261,7 +320,7 @@ void main() {
when(mockOpenSslProcess.stderr).thenAnswer((Invocation invocation) => mockOpenSslStdErr); when(mockOpenSslProcess.stderr).thenAnswer((Invocation invocation) => mockOpenSslStdErr);
when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0)); when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0));
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app, usesTerminalUi: false); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app, usesTerminalUi: false);
expect( expect(
testLogger.statusText, testLogger.statusText,
...@@ -269,7 +328,7 @@ void main() { ...@@ -269,7 +328,7 @@ void main() {
); );
expect(testLogger.errorText, isEmpty); expect(testLogger.errorText, isEmpty);
verify(mockOpenSslStdIn.write('This is a mock certificate')); verify(mockOpenSslStdIn.write('This is a mock certificate'));
expect(developmentTeam, '5555EEEE55'); expect(signingConfigs, <String, String> {'DEVELOPMENT_TEAM':'5555EEEE55'});
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
...@@ -324,7 +383,7 @@ void main() { ...@@ -324,7 +383,7 @@ void main() {
when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0)); when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0));
when<String>(mockConfig.getValue('ios-signing-cert')).thenReturn('iPhone Developer: Profile 3 (3333CCCC33)'); when<String>(mockConfig.getValue('ios-signing-cert')).thenReturn('iPhone Developer: Profile 3 (3333CCCC33)');
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect( expect(
testLogger.statusText, testLogger.statusText,
...@@ -336,7 +395,7 @@ void main() { ...@@ -336,7 +395,7 @@ void main() {
); );
expect(testLogger.errorText, isEmpty); expect(testLogger.errorText, isEmpty);
verify(mockOpenSslStdIn.write('This is a mock certificate')); verify(mockOpenSslStdIn.write('This is a mock certificate'));
expect(developmentTeam, '4444DDDD44'); expect(signingConfigs, <String, String> {'DEVELOPMENT_TEAM':'4444DDDD44'});
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
...@@ -393,7 +452,7 @@ void main() { ...@@ -393,7 +452,7 @@ void main() {
when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0)); when(mockOpenSslProcess.exitCode).thenAnswer((_) => new Future<int>.value(0));
when<String>(mockConfig.getValue('ios-signing-cert')).thenReturn('iPhone Developer: Invalid Profile'); when<String>(mockConfig.getValue('ios-signing-cert')).thenReturn('iPhone Developer: Invalid Profile');
final String developmentTeam = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app);
expect( expect(
testLogger.errorText, testLogger.errorText,
...@@ -403,7 +462,7 @@ void main() { ...@@ -403,7 +462,7 @@ void main() {
testLogger.statusText, testLogger.statusText,
contains('Certificate choice "iPhone Developer: Profile 3 (3333CCCC33)"') contains('Certificate choice "iPhone Developer: Profile 3 (3333CCCC33)"')
); );
expect(developmentTeam, '4444DDDD44'); expect(signingConfigs, <String, String> {'DEVELOPMENT_TEAM':'4444DDDD44'});
verify(config.setValue('ios-signing-cert', 'iPhone Developer: Profile 3 (3333CCCC33)')); verify(config.setValue('ios-signing-cert', 'iPhone Developer: Profile 3 (3333CCCC33)'));
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment