fix(shorebird_cli): ensure all release artifacts are built using the same flutter revision (#1911)
This commit is contained in:
@@ -245,6 +245,17 @@ Use `shorebird flutter versions list` to list available versions.
|
||||
release: existingRelease,
|
||||
platform: releasePlatform,
|
||||
);
|
||||
|
||||
// All artifacts associated with a given release must be built
|
||||
// with the same Flutter revision.
|
||||
if (existingRelease.flutterRevision != flutterRevisionForRelease) {
|
||||
ReleaseCommand.printConflictingFlutterRevisionError(
|
||||
existingFlutterRevision: existingRelease.flutterRevision,
|
||||
currentFlutterRevision: flutterRevisionForRelease,
|
||||
releaseVersion: releaseVersion,
|
||||
);
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
}
|
||||
|
||||
final archNames = architectures.map((a) => a.name);
|
||||
|
||||
@@ -22,6 +22,27 @@ class ReleaseCommand extends ShorebirdCommand {
|
||||
@override
|
||||
String get name => 'release';
|
||||
|
||||
static void printConflictingFlutterRevisionError({
|
||||
required String existingFlutterRevision,
|
||||
required String currentFlutterRevision,
|
||||
required String releaseVersion,
|
||||
}) {
|
||||
logger.err(
|
||||
'''
|
||||
${styleBold.wrap(lightRed.wrap('A release with version $releaseVersion already exists but was built using a different Flutter revision.'))}
|
||||
|
||||
Existing release built with: ${lightCyan.wrap(existingFlutterRevision)}
|
||||
Current release built with: ${lightCyan.wrap(currentFlutterRevision)}
|
||||
|
||||
${styleBold.wrap(lightRed.wrap('All platforms for a given release must be built using the same Flutter revision.'))}
|
||||
|
||||
To resolve this issue, you can:
|
||||
* Re-run the release command with "${lightCyan.wrap('--flutter-version=$existingFlutterRevision')}".
|
||||
* Delete the existing release and re-run the release command with the desired Flutter version.
|
||||
* Bump the release version and re-run the release command with the desired Flutter version.''',
|
||||
);
|
||||
}
|
||||
|
||||
static void printPatchInstructions({
|
||||
required String name,
|
||||
required String releaseVersion,
|
||||
|
||||
@@ -255,6 +255,17 @@ Use `shorebird flutter versions list` to list available versions.
|
||||
release: existingRelease,
|
||||
platform: releasePlatform,
|
||||
);
|
||||
|
||||
// All artifacts associated with a given release must be built
|
||||
// with the same Flutter revision.
|
||||
if (existingRelease.flutterRevision != flutterRevisionForRelease) {
|
||||
ReleaseCommand.printConflictingFlutterRevisionError(
|
||||
existingFlutterRevision: existingRelease.flutterRevision,
|
||||
currentFlutterRevision: flutterRevisionForRelease,
|
||||
releaseVersion: releaseVersion,
|
||||
);
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
}
|
||||
|
||||
final summary = [
|
||||
|
||||
@@ -836,6 +836,58 @@ Note: ${lightCyan.wrap('shorebird patch android --flavor=$flavor --target=$targe
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'does not upload artifacts if an existing release is present '
|
||||
'with a different flutter revision', () async {
|
||||
when(
|
||||
() => codePushClientWrapper.maybeGetRelease(
|
||||
appId: any(named: 'appId'),
|
||||
releaseVersion: any(named: 'releaseVersion'),
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => Release(
|
||||
id: release.id,
|
||||
appId: release.appId,
|
||||
version: release.version,
|
||||
flutterRevision: 'different-revision',
|
||||
displayName: release.displayName,
|
||||
createdAt: release.createdAt.add(const Duration(minutes: 1)),
|
||||
updatedAt: release.createdAt.add(const Duration(minutes: 1)),
|
||||
platformStatuses: release.platformStatuses,
|
||||
),
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => logger.err(
|
||||
any(
|
||||
that: contains(
|
||||
'''All platforms for a given release must be built using the same Flutter revision.''',
|
||||
),
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.createRelease(
|
||||
appId: any(named: 'appId'),
|
||||
version: any(named: 'version'),
|
||||
flutterRevision: any(named: 'flutterRevision'),
|
||||
platform: any(named: 'platform'),
|
||||
),
|
||||
);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.createAndroidReleaseArtifacts(
|
||||
appId: any(named: 'appId'),
|
||||
releaseId: any(named: 'releaseId'),
|
||||
projectRoot: any(named: 'projectRoot'),
|
||||
aabPath: any(named: 'aabPath'),
|
||||
platform: any(named: 'platform'),
|
||||
architectures: any(named: 'architectures'),
|
||||
flavor: any(named: 'flavor'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('does not prompt if unable to accept user input', () async {
|
||||
when(() => shorebirdEnv.canAcceptUserInput).thenReturn(false);
|
||||
|
||||
|
||||
@@ -1083,6 +1083,69 @@ Note: ${lightCyan.wrap('shorebird patch ios --flavor=$flavor --target=$target')}
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'does not upload artifacts if an existing release is present '
|
||||
'with a different flutter revision', () async {
|
||||
when(
|
||||
() => codePushClientWrapper.maybeGetRelease(
|
||||
appId: any(named: 'appId'),
|
||||
releaseVersion: any(named: 'releaseVersion'),
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => Release(
|
||||
id: release.id,
|
||||
appId: release.appId,
|
||||
version: release.version,
|
||||
flutterRevision: 'different-revision',
|
||||
displayName: release.displayName,
|
||||
createdAt: release.createdAt.add(const Duration(minutes: 1)),
|
||||
updatedAt: release.createdAt.add(const Duration(minutes: 1)),
|
||||
platformStatuses: release.platformStatuses,
|
||||
),
|
||||
);
|
||||
setUpProjectRoot();
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
|
||||
verify(
|
||||
() => logger.err(
|
||||
any(
|
||||
that: contains(
|
||||
'''All platforms for a given release must be built using the same Flutter revision.''',
|
||||
),
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.createRelease(
|
||||
appId: any(named: 'appId'),
|
||||
version: any(named: 'version'),
|
||||
flutterRevision: any(named: 'flutterRevision'),
|
||||
platform: any(named: 'platform'),
|
||||
),
|
||||
);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.createIosReleaseArtifacts(
|
||||
appId: any(named: 'appId'),
|
||||
releaseId: any(named: 'releaseId'),
|
||||
xcarchivePath:
|
||||
any(named: 'xcarchivePath', that: endsWith('.xcarchive')),
|
||||
runnerPath: any(named: 'runnerPath', that: endsWith('Runner.app')),
|
||||
isCodesigned: any(named: 'isCodesigned'),
|
||||
),
|
||||
);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.updateReleaseStatus(
|
||||
appId: any(named: 'appId'),
|
||||
releaseId: any(named: 'releaseId'),
|
||||
platform: any(named: 'platform'),
|
||||
status: any(named: 'status'),
|
||||
metadata: any(named: 'metadata'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('does not provide export options when codesign is false', () async {
|
||||
when(() => argResults['codesign']).thenReturn(false);
|
||||
setUpProjectRoot();
|
||||
|
||||
Reference in New Issue
Block a user