refactor(shorebird_cli): Add IosFrameworkReleaser for new release command (#2013)
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
import 'package:io/io.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/artifact_manager.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/release_type.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/releaser.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/executables/xcodebuild.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_flutter.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
|
||||
import 'package:shorebird_cli/src/version.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template ios_framework_releaser}
|
||||
/// Functions to create an iOS framework release.
|
||||
/// {@endtemplate}
|
||||
class IosFrameworkReleaser extends Releaser {
|
||||
/// {@macro ios_framework_releaser}
|
||||
IosFrameworkReleaser({
|
||||
required super.argResults,
|
||||
required super.flavor,
|
||||
required super.target,
|
||||
});
|
||||
|
||||
Directory get releaseDirectory => Directory(
|
||||
p.join(shorebirdEnv.getShorebirdProjectRoot()!.path, 'release'),
|
||||
);
|
||||
|
||||
@override
|
||||
bool get requiresReleaseVersionArg => true;
|
||||
|
||||
@override
|
||||
ReleaseType get releaseType => ReleaseType.iosFramework;
|
||||
|
||||
@override
|
||||
Future<void> assertArgsAreValid() async {
|
||||
if (!argResults.wasParsed('release-version')) {
|
||||
logger.err('Missing required argument: --release-version');
|
||||
exit(ExitCode.usage.code);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> assertPreconditions() async {
|
||||
try {
|
||||
await shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
supportedOperatingSystems: {Platform.macOS},
|
||||
validators: doctor.iosCommandValidators,
|
||||
);
|
||||
} on PreconditionFailedException catch (e) {
|
||||
exit(e.exitCode.code);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<FileSystemEntity> buildReleaseArtifacts() async {
|
||||
final flutterVersionString = await shorebirdFlutter.getVersionAndRevision();
|
||||
|
||||
final buildProgress = logger.progress(
|
||||
'Building iOS framework with Flutter $flutterVersionString',
|
||||
);
|
||||
|
||||
try {
|
||||
await artifactBuilder.buildIosFramework();
|
||||
} catch (error) {
|
||||
buildProgress.fail('Failed to build iOS framework: $error');
|
||||
exit(ExitCode.software.code);
|
||||
}
|
||||
|
||||
buildProgress.complete();
|
||||
|
||||
// Copy release xcframework to a new directory to avoid overwriting with
|
||||
// subsequent patch builds.
|
||||
final sourceLibraryDirectory = artifactManager.getAppXcframeworkDirectory();
|
||||
final targetLibraryDirectory = Directory(
|
||||
p.join(shorebirdEnv.getShorebirdProjectRoot()!.path, 'release'),
|
||||
);
|
||||
if (targetLibraryDirectory.existsSync()) {
|
||||
targetLibraryDirectory.deleteSync(recursive: true);
|
||||
}
|
||||
await copyPath(
|
||||
sourceLibraryDirectory.path,
|
||||
targetLibraryDirectory.path,
|
||||
);
|
||||
|
||||
return targetLibraryDirectory;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getReleaseVersion({
|
||||
required FileSystemEntity releaseArtifactRoot,
|
||||
}) async {
|
||||
return argResults['release-version'] as String;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> uploadReleaseArtifacts({
|
||||
required Release release,
|
||||
required String appId,
|
||||
}) {
|
||||
return codePushClientWrapper.createIosFrameworkReleaseArtifacts(
|
||||
appId: appId,
|
||||
releaseId: release.id,
|
||||
appFrameworkPath: p.join(releaseDirectory.path, 'App.xcframework'),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String get postReleaseInstructions {
|
||||
final relativeFrameworkDirectoryPath = p.relative(releaseDirectory.path);
|
||||
return '''
|
||||
|
||||
Your next step is to add the .xcframework files found in the ${lightCyan.wrap(relativeFrameworkDirectoryPath)} directory to your iOS app.
|
||||
|
||||
To do this:
|
||||
1. Add the relative path to the ${lightCyan.wrap(relativeFrameworkDirectoryPath)} directory to your app's Framework Search Paths in your Xcode build settings.
|
||||
2. Embed the App.xcframework and ShorebirdFlutter.framework in your Xcode project.
|
||||
|
||||
Instructions for these steps can be found at https://docs.flutter.dev/add-to-app/ios/project-setup#option-b---embed-frameworks-in-xcode.
|
||||
''';
|
||||
}
|
||||
|
||||
@override
|
||||
Future<UpdateReleaseMetadata> releaseMetadata() async =>
|
||||
UpdateReleaseMetadata(
|
||||
releasePlatform: releaseType.releasePlatform,
|
||||
flutterVersionOverride: argResults['flutter-version'] as String?,
|
||||
generatedApks: false,
|
||||
environment: BuildEnvironmentMetadata(
|
||||
operatingSystem: platform.operatingSystem,
|
||||
operatingSystemVersion: platform.operatingSystemVersion,
|
||||
shorebirdVersion: packageVersion,
|
||||
xcodeVersion: await xcodeBuild.version(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export 'aar_releaser.dart';
|
||||
export 'android_releaser.dart';
|
||||
export 'ios_framework_releaser.dart';
|
||||
export 'ios_releaser.dart';
|
||||
export 'release_new_command.dart';
|
||||
export 'releaser.dart';
|
||||
|
||||
@@ -5,11 +5,8 @@ import 'package:meta/meta.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/aar_releaser.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/android_releaser.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/ios_releaser.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/release_new.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/release_type.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/releaser.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
@@ -136,9 +133,17 @@ of the iOS app that is using this module.''',
|
||||
target: target,
|
||||
);
|
||||
case ReleaseType.ios:
|
||||
return IosReleaser(argResults: results, flavor: flavor, target: target);
|
||||
return IosReleaser(
|
||||
argResults: results,
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
);
|
||||
case ReleaseType.iosFramework:
|
||||
throw UnimplementedError();
|
||||
return IosFrameworkReleaser(
|
||||
argResults: results,
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
);
|
||||
case ReleaseType.aar:
|
||||
return AarReleaser(
|
||||
argResults: results,
|
||||
|
||||
+418
@@ -0,0 +1,418 @@
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/artifact_manager.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/ios_framework_releaser.dart';
|
||||
import 'package:shorebird_cli/src/commands/release_new/release_type.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/executables/executables.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/os/operating_system_interface.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_flutter.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:shorebird_cli/src/version.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../matchers.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
group(
|
||||
IosFrameworkReleaser,
|
||||
() {
|
||||
late ArgResults argResults;
|
||||
late ArtifactBuilder artifactBuilder;
|
||||
late ArtifactManager artifactManager;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late Doctor doctor;
|
||||
late Platform platform;
|
||||
late Directory projectRoot;
|
||||
late Logger logger;
|
||||
late OperatingSystemInterface operatingSystemInterface;
|
||||
late Progress progress;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdFlutter shorebirdFlutter;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late XcodeBuild xcodeBuild;
|
||||
late IosFrameworkReleaser iosFrameworkReleaser;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
artifactBuilderRef.overrideWith(() => artifactBuilder),
|
||||
artifactManagerRef.overrideWith(() => artifactManager),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
osInterfaceRef.overrideWith(() => operatingSystemInterface),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdFlutterRef.overrideWith(() => shorebirdFlutter),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
xcodeBuildRef.overrideWith(() => xcodeBuild),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(Directory(''));
|
||||
registerFallbackValue(ReleasePlatform.ios);
|
||||
setExitFunctionForTests();
|
||||
});
|
||||
|
||||
tearDownAll(restoreExitFunction);
|
||||
|
||||
setUp(() {
|
||||
argResults = MockArgResults();
|
||||
artifactBuilder = MockArtifactBuilder();
|
||||
artifactManager = MockArtifactManager();
|
||||
codePushClientWrapper = MockCodePushClientWrapper();
|
||||
doctor = MockDoctor();
|
||||
operatingSystemInterface = MockOperatingSystemInterface();
|
||||
platform = MockPlatform();
|
||||
progress = MockProgress();
|
||||
projectRoot = Directory.systemTemp.createTempSync();
|
||||
logger = MockLogger();
|
||||
shorebirdProcess = MockShorebirdProcess();
|
||||
shorebirdEnv = MockShorebirdEnv();
|
||||
flutterValidator = MockShorebirdFlutterValidator();
|
||||
shorebirdFlutter = MockShorebirdFlutter();
|
||||
shorebirdValidator = MockShorebirdValidator();
|
||||
xcodeBuild = MockXcodeBuild();
|
||||
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
|
||||
when(
|
||||
() => shorebirdEnv.getShorebirdProjectRoot(),
|
||||
).thenReturn(projectRoot);
|
||||
|
||||
iosFrameworkReleaser = IosFrameworkReleaser(
|
||||
argResults: argResults,
|
||||
flavor: null,
|
||||
target: null,
|
||||
);
|
||||
});
|
||||
|
||||
group('requiresReleaseVersionArg', () {
|
||||
test('is true', () {
|
||||
expect(iosFrameworkReleaser.requiresReleaseVersionArg, isTrue);
|
||||
});
|
||||
});
|
||||
|
||||
group('releaseType', () {
|
||||
test('is xcframework', () {
|
||||
expect(iosFrameworkReleaser.releaseType, ReleaseType.iosFramework);
|
||||
});
|
||||
});
|
||||
|
||||
group('assertArgsAreValid', () {
|
||||
group('when split-per-abi is true', () {
|
||||
setUp(() {
|
||||
when(() => argResults.wasParsed('release-version'))
|
||||
.thenReturn(false);
|
||||
});
|
||||
|
||||
test('exits with code 64', () async {
|
||||
await expectLater(
|
||||
() => runWithOverrides(iosFrameworkReleaser.assertArgsAreValid),
|
||||
exitsWithCode(ExitCode.usage),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('when arguments are valid', () {
|
||||
setUp(() {
|
||||
when(() => argResults.wasParsed('release-version'))
|
||||
.thenReturn(true);
|
||||
});
|
||||
|
||||
test('returns normally', () {
|
||||
expect(
|
||||
() => runWithOverrides(iosFrameworkReleaser.assertArgsAreValid),
|
||||
returnsNormally,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('assertPreconditions', () {
|
||||
setUp(() {
|
||||
when(() => doctor.iosCommandValidators)
|
||||
.thenReturn([flutterValidator]);
|
||||
when(flutterValidator.validate).thenAnswer((_) async => []);
|
||||
});
|
||||
|
||||
group('when validation succeeds', () {
|
||||
setUp(() {
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated:
|
||||
any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized:
|
||||
any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
supportedOperatingSystems:
|
||||
any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
});
|
||||
|
||||
test('returns normally', () async {
|
||||
await expectLater(
|
||||
() => runWithOverrides(iosFrameworkReleaser.assertPreconditions),
|
||||
returnsNormally,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('when validation fails', () {
|
||||
final exception = ValidationFailedException();
|
||||
|
||||
setUp(() {
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated:
|
||||
any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized:
|
||||
any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
supportedOperatingSystems:
|
||||
any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenThrow(exception);
|
||||
});
|
||||
|
||||
test('exits with code 70', () async {
|
||||
await expectLater(
|
||||
() => runWithOverrides(iosFrameworkReleaser.assertPreconditions),
|
||||
exitsWithCode(exception.exitCode),
|
||||
);
|
||||
verify(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: [flutterValidator],
|
||||
supportedOperatingSystems: {Platform.macOS},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('buildReleaseArtifacts', () {
|
||||
const flutterVersionAndRevision = '3.10.6 (83305b5088)';
|
||||
|
||||
void setUpProjectRootArtifacts() {
|
||||
// Create an xcframework in the release directory to simulate running
|
||||
// this command a subsequent time.
|
||||
Directory(p.join(projectRoot.path, 'release', 'Flutter.xcframework'))
|
||||
.createSync(recursive: true);
|
||||
Directory(
|
||||
p.join(
|
||||
projectRoot.path,
|
||||
'build',
|
||||
'ios',
|
||||
'framework',
|
||||
'Release',
|
||||
'Flutter.xcframework',
|
||||
),
|
||||
).createSync(recursive: true);
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
when(
|
||||
() => artifactBuilder.buildIosFramework(),
|
||||
).thenAnswer(
|
||||
(_) async => File(''),
|
||||
);
|
||||
when(() => artifactManager.getAppXcframeworkDirectory()).thenReturn(
|
||||
Directory(
|
||||
p.join(
|
||||
projectRoot.path,
|
||||
'build',
|
||||
'ios',
|
||||
'framework',
|
||||
'Release',
|
||||
'Flutter.xcframework',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(
|
||||
() => shorebirdFlutter.getVersionAndRevision(),
|
||||
).thenAnswer((_) async => flutterVersionAndRevision);
|
||||
|
||||
setUpProjectRootArtifacts();
|
||||
});
|
||||
|
||||
group('when build succeeds', () {
|
||||
test('produces aar in release directory', () async {
|
||||
final xcframework = await runWithOverrides(
|
||||
iosFrameworkReleaser.buildReleaseArtifacts,
|
||||
);
|
||||
|
||||
expect(xcframework.path, p.join(projectRoot.path, 'release'));
|
||||
verify(artifactBuilder.buildIosFramework).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('when build fails', () {
|
||||
setUp(() {
|
||||
when(
|
||||
() => artifactBuilder.buildIosFramework(),
|
||||
).thenThrow(Exception('build failed'));
|
||||
});
|
||||
|
||||
test('logs error and exits with code 70', () async {
|
||||
await expectLater(
|
||||
() => runWithOverrides(
|
||||
iosFrameworkReleaser.buildReleaseArtifacts,
|
||||
),
|
||||
exitsWithCode(ExitCode.software),
|
||||
);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Failed to build iOS framework: Exception: build failed',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('getReleaseVersion', () {
|
||||
const releaseVersion = '1.0.0';
|
||||
setUp(() {
|
||||
when(() => argResults['release-version']).thenReturn(releaseVersion);
|
||||
});
|
||||
|
||||
test('returns value from argResults', () async {
|
||||
final result = await runWithOverrides(
|
||||
() => iosFrameworkReleaser.getReleaseVersion(
|
||||
releaseArtifactRoot: Directory(''),
|
||||
),
|
||||
);
|
||||
expect(result, releaseVersion);
|
||||
});
|
||||
});
|
||||
|
||||
group('uploadReleaseArtifacts', () {
|
||||
const releaseVersion = '1.0.0';
|
||||
const appId = 'appId';
|
||||
const flutterRevision = 'deadbeef';
|
||||
|
||||
final release = Release(
|
||||
id: 42,
|
||||
appId: appId,
|
||||
version: releaseVersion,
|
||||
flutterRevision: flutterRevision,
|
||||
displayName: '1.2.3+1',
|
||||
platformStatuses: {},
|
||||
createdAt: DateTime(2023),
|
||||
updatedAt: DateTime(2023),
|
||||
);
|
||||
|
||||
setUp(() {
|
||||
when(
|
||||
() => codePushClientWrapper.createIosFrameworkReleaseArtifacts(
|
||||
appId: any(named: 'appId'),
|
||||
releaseId: any(named: 'releaseId'),
|
||||
appFrameworkPath: any(named: 'appFrameworkPath'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
});
|
||||
|
||||
test('uploads artifacts', () async {
|
||||
await runWithOverrides(
|
||||
() => iosFrameworkReleaser.uploadReleaseArtifacts(
|
||||
release: release,
|
||||
appId: appId,
|
||||
),
|
||||
);
|
||||
|
||||
verify(
|
||||
() => codePushClientWrapper.createIosFrameworkReleaseArtifacts(
|
||||
appId: appId,
|
||||
releaseId: release.id,
|
||||
appFrameworkPath: p.join(
|
||||
projectRoot.path,
|
||||
'release',
|
||||
ArtifactManager.appXcframeworkName,
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('releaseMetadata', () {
|
||||
const operatingSystem = 'macos';
|
||||
const operatingSystemVersion = '11.0.0';
|
||||
const xcodeVersion = '123';
|
||||
|
||||
setUp(() {
|
||||
when(() => platform.operatingSystem).thenReturn(operatingSystem);
|
||||
when(() => platform.operatingSystemVersion)
|
||||
.thenReturn(operatingSystemVersion);
|
||||
when(() => xcodeBuild.version())
|
||||
.thenAnswer((_) async => xcodeVersion);
|
||||
});
|
||||
|
||||
test('returns expected metadata', () async {
|
||||
expect(
|
||||
await runWithOverrides(iosFrameworkReleaser.releaseMetadata),
|
||||
equals(
|
||||
const UpdateReleaseMetadata(
|
||||
releasePlatform: ReleasePlatform.ios,
|
||||
flutterVersionOverride: null,
|
||||
generatedApks: false,
|
||||
environment: BuildEnvironmentMetadata(
|
||||
operatingSystem: operatingSystem,
|
||||
operatingSystemVersion: operatingSystemVersion,
|
||||
shorebirdVersion: packageVersion,
|
||||
xcodeVersion: xcodeVersion,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('postReleaseInstructions', () {
|
||||
test('returns expected instructions', () {
|
||||
final relativeFrameworkDirectoryPath = p.relative(
|
||||
p.join(projectRoot.path, 'release'),
|
||||
);
|
||||
expect(
|
||||
runWithOverrides(
|
||||
() => iosFrameworkReleaser.postReleaseInstructions,
|
||||
),
|
||||
equals('''
|
||||
|
||||
Your next step is to add the .xcframework files found in the ${lightCyan.wrap(relativeFrameworkDirectoryPath)} directory to your iOS app.
|
||||
|
||||
To do this:
|
||||
1. Add the relative path to the ${lightCyan.wrap(relativeFrameworkDirectoryPath)} directory to your app's Framework Search Paths in your Xcode build settings.
|
||||
2. Embed the App.xcframework and ShorebirdFlutter.framework in your Xcode project.
|
||||
|
||||
Instructions for these steps can be found at https://docs.flutter.dev/add-to-app/ios/project-setup#option-b---embed-frameworks-in-xcode.
|
||||
'''),
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
testOn: 'mac-os',
|
||||
);
|
||||
}
|
||||
@@ -190,8 +190,8 @@ void main() {
|
||||
isA<IosReleaser>(),
|
||||
);
|
||||
expect(
|
||||
() => command.getReleaser(ReleaseType.iosFramework),
|
||||
throwsA(isA<UnimplementedError>()),
|
||||
command.getReleaser(ReleaseType.iosFramework),
|
||||
isA<IosFrameworkReleaser>(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user