Unverified Commit 01dc19b9 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Pass environment variables through to xcodebuild (#43553)

parent 19e551c7
......@@ -464,6 +464,7 @@ Future<XcodeBuildResult> buildXcodeProject({
// e.g. `flutter build bundle`.
buildCommands.add('FLUTTER_SUPPRESS_ANALYTICS=true');
buildCommands.add('COMPILER_INDEX_STORE_ENABLE=NO');
buildCommands.addAll(environmentVariablesAsXcodeBuildSettings());
final Stopwatch sw = Stopwatch()..start();
initialBuildStatus = logger.startProgress('Running Xcode build...', timeout: timeoutConfiguration.fastOperation);
......
......@@ -293,9 +293,10 @@ class XcodeProjectInterpreter {
'-target',
target,
'-showBuildSettings',
...environmentVariablesAsXcodeBuildSettings()
];
try {
// showBuildSettings is reported to ocassionally timeout. Here, we give it
// showBuildSettings is reported to occasionally timeout. Here, we give it
// a lot of wiggle room (locally on Flutter Gallery, this takes ~1s).
// When there is a timeout, we retry once.
final RunResult result = await processUtils.run(
......@@ -329,6 +330,7 @@ class XcodeProjectInterpreter {
scheme,
'-quiet',
'clean',
...environmentVariablesAsXcodeBuildSettings()
], workingDirectory: fs.currentDirectory.path);
}
......@@ -354,6 +356,21 @@ class XcodeProjectInterpreter {
}
}
/// Environment variables prefixed by FLUTTER_XCODE_ will be passed as build configurations to xcodebuild.
/// This allows developers to pass arbitrary build settings in without the tool needing to make a flag
/// for or be aware of each one. This could be used to set code signing build settings in a CI
/// environment without requiring settings changes in the Xcode project.
List<String> environmentVariablesAsXcodeBuildSettings() {
const String xcodeBuildSettingPrefix = 'FLUTTER_XCODE_';
return platform.environment.entries.where((MapEntry<String, String> mapEntry) {
return mapEntry.key.startsWith(xcodeBuildSettingPrefix);
}).expand<String>((MapEntry<String, String> mapEntry) {
// Remove FLUTTER_XCODE_ prefix from the environment variable to get the build setting.
final String trimmedBuildSettingKey = mapEntry.key.substring(xcodeBuildSettingPrefix.length);
return <String>['$trimmedBuildSettingKey=${mapEntry.value}'];
}).toList();
}
Map<String, String> parseXcodeBuildSettings(String showBuildSettingsOutput) {
final Map<String, String> settings = <String, String>{};
for (Match match in showBuildSettingsOutput.split('\n').map<Match>(_settingExpr.firstMatch)) {
......
......@@ -79,6 +79,7 @@ Future<void> buildMacOS({
'OBJROOT=${fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Intermediates.noindex')}',
'SYMROOT=${fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Products')}',
'COMPILER_INDEX_STORE_ENABLE=NO',
...environmentVariablesAsXcodeBuildSettings()
], trace: true);
} finally {
status.cancel();
......
......@@ -23,7 +23,7 @@ import '../../src/pubspec_schema.dart';
const String xcodebuild = '/usr/bin/xcodebuild';
void main() {
group('xcodebuild versioning', () {
group('xcodebuild commands', () {
mocks.MockProcessManager mockProcessManager;
XcodeProjectInterpreter xcodeProjectInterpreter;
FakePlatform macOS;
......@@ -172,6 +172,54 @@ void main() {
FileSystem: () => fs,
ProcessManager: () => mockProcessManager,
});
testUsingOsxContext('build settings contains Flutter Xcode environment variables', () async {
macOS.environment = Map<String, String>.unmodifiable(<String, String>{
'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
'FLUTTER_XCODE_ARCHS': 'arm64'
});
when(mockProcessManager.runSync(<String>[
xcodebuild,
'-project',
macOS.pathSeparator,
'-target',
'',
'-showBuildSettings',
'CODE_SIGN_STYLE=Manual',
'ARCHS=arm64'
],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment')))
.thenReturn(ProcessResult(1, 0, '', ''));
expect(await xcodeProjectInterpreter.getBuildSettings('', ''), const <String, String>{});
});
testUsingOsxContext('clean contains Flutter Xcode environment variables', () async {
macOS.environment = Map<String, String>.unmodifiable(<String, String>{
'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
'FLUTTER_XCODE_ARCHS': 'arm64'
});
when(mockProcessManager.runSync(
any,
workingDirectory: anyNamed('workingDirectory')))
.thenReturn(ProcessResult(1, 0, '', ''));
xcodeProjectInterpreter.cleanWorkspace('workspace_path', 'Runner');
final List<dynamic> captured = verify(mockProcessManager.runSync(
captureAny,
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'))).captured;
expect(captured.first, <String>[
xcodebuild,
'-workspace',
'workspace_path',
'-scheme',
'Runner',
'-quiet',
'clean',
'CODE_SIGN_STYLE=Manual',
'ARCHS=arm64'
]);
});
});
group('xcodebuild -list', () {
......@@ -338,6 +386,27 @@ Information about project "Runner":
});
});
group('environmentVariablesAsXcodeBuildSettings', () {
FakePlatform platform;
setUp(() {
platform = fakePlatform('ignored');
});
testUsingContext('environment variables as Xcode build settings', () {
platform.environment = Map<String, String>.unmodifiable(<String, String>{
'Ignored': 'Bogus',
'FLUTTER_NOT_XCODE': 'Bogus',
'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
'FLUTTER_XCODE_ARCHS': 'arm64'
});
final List<String> environmentVariablesAsBuildSettings = environmentVariablesAsXcodeBuildSettings();
expect(environmentVariablesAsBuildSettings, <String>['CODE_SIGN_STYLE=Manual', 'ARCHS=arm64']);
}, overrides: <Type, Generator>{
Platform: () => platform
});
});
group('updateGeneratedXcodeProperties', () {
MockLocalEngineArtifacts mockArtifacts;
MockProcessManager mockProcessManager;
......
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