Add CI steps to test iOS and macOS plugins with both CocoaPods and Swift Package Manager (#6557)
Tests new Swift Package Manager feature added in https://github.com/flutter/flutter/pull/146256.
Fixes https://github.com/flutter/flutter/issues/146901.
diff --git a/.ci/targets/ios_platform_tests.yaml b/.ci/targets/ios_platform_tests.yaml
index b961b67..e679834 100644
--- a/.ci/targets/ios_platform_tests.yaml
+++ b/.ci/targets/ios_platform_tests.yaml
@@ -11,7 +11,7 @@
infra_step: true
- name: build examples
script: .ci/scripts/tool_runner.sh
- args: ["build-examples", "--ios"]
+ args: ["build-examples", "--ios", "--swift-package-manager"]
- name: xcode analyze
script: .ci/scripts/tool_runner.sh
args: ["xcode-analyze", "--ios"]
diff --git a/.ci/targets/macos_platform_tests.yaml b/.ci/targets/macos_platform_tests.yaml
index bc1b915..1dd105f 100644
--- a/.ci/targets/macos_platform_tests.yaml
+++ b/.ci/targets/macos_platform_tests.yaml
@@ -8,7 +8,7 @@
infra_step: true
- name: build examples
script: .ci/scripts/tool_runner.sh
- args: ["build-examples", "--macos"]
+ args: ["build-examples", "--macos", "--swift-package-manager"]
- name: xcode analyze
script: .ci/scripts/tool_runner.sh
args: ["xcode-analyze", "--macos"]
diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart
index 0f78d39..d8d1613 100644
--- a/script/tool/lib/src/build_examples_command.dart
+++ b/script/tool/lib/src/build_examples_command.dart
@@ -38,6 +38,9 @@
const String _flutterBuildTypeAndroidAlias = 'android';
+/// Key for Swift Package Manager.
+const String _swiftPackageManagerFlag = 'swift-package-manager';
+
/// A command to build the example applications for packages.
class BuildExamplesCommand extends PackageLoopingCommand {
/// Creates an instance of the build command.
@@ -58,6 +61,7 @@
defaultsTo: '',
help: 'Enables the given Dart SDK experiments.',
);
+ argParser.addFlag(_swiftPackageManagerFlag);
}
// Maps the switch this command uses to identify a platform to information
@@ -111,6 +115,15 @@
'single key "$_pluginToolsConfigGlobalKey" containing a list of build '
'arguments.';
+ /// Returns true if `--swift-package-manager` flag was passed along with
+ /// either `--ios` or `--macos`.
+ bool get usingSwiftPackageManager {
+ final List<String> platformFlags = _platforms.keys.toList();
+ return getBoolArg(_swiftPackageManagerFlag) &&
+ (platformFlags.contains(platformIOS) ||
+ platformFlags.contains(platformMacOS));
+ }
+
@override
Future<void> initializeRun() async {
final List<String> platformFlags = _platforms.keys.toList();
@@ -121,6 +134,17 @@
'were specified. At least one platform must be provided.');
throw ToolExit(_exitNoPlatformFlags);
}
+
+ // TODO(vashworth): Enable on stable once Swift Package Manager feature is
+ // available on stable.
+ if (usingSwiftPackageManager &&
+ platform.environment['CHANNEL'] != 'stable') {
+ await processRunner.runAndStream(
+ flutterCommand,
+ <String>['config', '--enable-swift-package-manager'],
+ exitOnError: true,
+ );
+ }
}
@override
diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart
index 2f58dac..0c99bfb 100644
--- a/script/tool/test/build_examples_command_test.dart
+++ b/script/tool/test/build_examples_command_test.dart
@@ -164,6 +164,98 @@
]));
});
+ test('building for iOS with Swift Package Manager on master channel',
+ () async {
+ mockPlatform.isMacOS = true;
+ mockPlatform.environment['CHANNEL'] = 'master';
+
+ final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir,
+ platformSupport: <String, PlatformDetails>{
+ platformIOS: const PlatformDetails(PlatformSupport.inline),
+ });
+
+ final Directory pluginExampleDirectory = getExampleDir(plugin);
+
+ final List<String> output = await runCapturingPrint(runner, <String>[
+ 'build-examples',
+ '--ios',
+ '--enable-experiment=exp1',
+ '--swift-package-manager',
+ ]);
+
+ expect(
+ output,
+ containsAllInOrder(<String>[
+ '\nBUILDING plugin/example for iOS',
+ ]),
+ );
+
+ expect(
+ processRunner.recordedCalls,
+ orderedEquals(<ProcessCall>[
+ ProcessCall(
+ getFlutterCommand(mockPlatform),
+ const <String>['config', '--enable-swift-package-manager'],
+ null,
+ ),
+ ProcessCall(
+ getFlutterCommand(mockPlatform),
+ const <String>[
+ 'build',
+ 'ios',
+ '--no-codesign',
+ '--enable-experiment=exp1'
+ ],
+ pluginExampleDirectory.path,
+ ),
+ ]),
+ );
+ });
+
+ test(
+ 'building for iOS with Swift Package Manager on stable channel does not enable SPM',
+ () async {
+ mockPlatform.isMacOS = true;
+ mockPlatform.environment['CHANNEL'] = 'stable';
+
+ final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir,
+ platformSupport: <String, PlatformDetails>{
+ platformIOS: const PlatformDetails(PlatformSupport.inline),
+ });
+
+ final Directory pluginExampleDirectory = getExampleDir(plugin);
+
+ final List<String> output = await runCapturingPrint(runner, <String>[
+ 'build-examples',
+ '--ios',
+ '--enable-experiment=exp1',
+ '--swift-package-manager',
+ ]);
+
+ expect(
+ output,
+ containsAllInOrder(<String>[
+ '\nBUILDING plugin/example for iOS',
+ ]),
+ );
+
+ expect(
+ processRunner.recordedCalls,
+ orderedEquals(<ProcessCall>[
+ ProcessCall(
+ getFlutterCommand(mockPlatform),
+ const <String>[
+ 'build',
+ 'ios',
+ '--no-codesign',
+ '--enable-experiment=exp1'
+ ],
+ pluginExampleDirectory.path,
+ ),
+ ]),
+ );
+ });
+
test(
'building for Linux when plugin is not set up for Linux results in no-op',
() async {
@@ -261,6 +353,86 @@
]));
});
+ test('building for macOS with Swift Package Manager on master channel',
+ () async {
+ mockPlatform.isMacOS = true;
+ mockPlatform.environment['CHANNEL'] = 'master';
+
+ final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir,
+ platformSupport: <String, PlatformDetails>{
+ platformMacOS: const PlatformDetails(PlatformSupport.inline),
+ });
+
+ final Directory pluginExampleDirectory = getExampleDir(plugin);
+
+ final List<String> output = await runCapturingPrint(runner,
+ <String>['build-examples', '--macos', '--swift-package-manager']);
+
+ expect(
+ output,
+ containsAllInOrder(<String>[
+ '\nBUILDING plugin/example for macOS',
+ ]),
+ );
+
+ expect(
+ processRunner.recordedCalls,
+ orderedEquals(<ProcessCall>[
+ ProcessCall(
+ getFlutterCommand(mockPlatform),
+ const <String>['config', '--enable-swift-package-manager'],
+ null,
+ ),
+ ProcessCall(
+ getFlutterCommand(mockPlatform),
+ const <String>[
+ 'build',
+ 'macos',
+ ],
+ pluginExampleDirectory.path,
+ ),
+ ]),
+ );
+ });
+
+ test(
+ 'building for macOS with Swift Package Manager on stable channel does not enable SPM',
+ () async {
+ mockPlatform.isMacOS = true;
+ mockPlatform.environment['CHANNEL'] = 'stable';
+
+ final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir,
+ platformSupport: <String, PlatformDetails>{
+ platformMacOS: const PlatformDetails(PlatformSupport.inline),
+ });
+
+ final Directory pluginExampleDirectory = getExampleDir(plugin);
+
+ final List<String> output = await runCapturingPrint(runner,
+ <String>['build-examples', '--macos', '--swift-package-manager']);
+
+ expect(
+ output,
+ containsAllInOrder(<String>[
+ '\nBUILDING plugin/example for macOS',
+ ]),
+ );
+
+ expect(
+ processRunner.recordedCalls,
+ orderedEquals(<ProcessCall>[
+ ProcessCall(
+ getFlutterCommand(mockPlatform),
+ const <String>[
+ 'build',
+ 'macos',
+ ],
+ pluginExampleDirectory.path,
+ ),
+ ]),
+ );
+ });
+
test('building for web with no implementation results in no-op', () async {
createFakePlugin('plugin', packagesDir);