fix: remove confirmation in shorebird release (#3452)

Co-authored-by: Bryan Oltman <bryan@shorebird.dev>
This commit is contained in:
Eric Seidel
2026-01-06 07:07:24 -08:00
committed by GitHub
parent 93cfec7474
commit e6701242d7
4 changed files with 21 additions and 76 deletions
@@ -186,9 +186,6 @@ NOTE: this is ${styleBold.wrap('not')} recommended. Asset changes cannot be incl
/// Whether to allow changes in native code (--allow-native-diffs).
bool get allowNativeDiffs => results['allow-native-diffs'] == true;
/// Whether --no-confirm was passed.
bool get noConfirm => results['no-confirm'] == true;
/// Whether the patch is for the staging environment.
bool get isStaging => track == DeploymentTrack.staging;
@@ -433,7 +430,7 @@ Building patch with Flutter $flutterVersionString
throw ProcessExit(ExitCode.success.code);
}
await confirmCreatePatch(
await logPatchSummary(
app: app,
releaseVersion: release.version,
patcher: patcher,
@@ -548,8 +545,14 @@ Please re-run the release command for this version or create a new release.''');
}
}
/// Confirms the patch creation (including a summary).
Future<void> confirmCreatePatch({
/// Logs a summary of the patch to be created, including:
/// - The app name and ID
/// - The release version
/// - The platform
/// - The track
/// - The link percentage (if iOS)
/// - The debug info file (if iOS)
Future<void> logPatchSummary({
required AppMetadata app,
required String releaseVersion,
required Patcher patcher,
@@ -596,15 +599,6 @@ ${styleBold.wrap(lightGreen.wrap('🚀 Ready to publish a new patch!'))}
${summary.join('\n')}
''');
if (shorebirdEnv.canAcceptUserInput && !noConfirm) {
final confirm = logger.confirm('Would you like to continue?');
if (!confirm) {
logger.info('Aborting.');
throw ProcessExit(ExitCode.success.code);
}
}
}
/// Downloads the given [releaseArtifact].
@@ -230,9 +230,6 @@ of the iOS app that is using this module. (aar and ios-framework only)''',
/// The target script, if provided.
String? get target => results.findOption('target', argParser: argParser);
/// Whether --no-confirm was passed.
bool get noConfirm => results['no-confirm'] == true;
/// The flutter version specified.
String get flutterVersionArg => results['flutter-version'] as String;
@@ -335,8 +332,7 @@ of the iOS app that is using this module. (aar and ios-framework only)''',
throw ProcessExit(ExitCode.success.code);
}
// Ask the user to proceed (this is skipped when running via CI).
await confirmCreateRelease(
await printReleaseSummary(
app: app,
releaseVersion: releaseVersion,
flutterVersion: targetFlutterRevision,
@@ -486,12 +482,8 @@ To resolve this issue, you can:
}
}
/// Prints a confirmation prompt with details about the release to be created.
/// If the user confirms, the release will be created. If the user cancels,
/// the command will exit with a success code. When running in a headless
/// or CI environment, this prompt will print but will not wait for user
/// confirmation.
Future<void> confirmCreateRelease({
/// Prints a summary of the release to be created.
Future<void> printReleaseSummary({
required AppMetadata app,
required String releaseVersion,
required String flutterVersion,
@@ -514,15 +506,6 @@ ${styleBold.wrap(lightGreen.wrap('🚀 Ready to create a new release!'))}
${summary.join('\n')}
''');
if (shorebirdEnv.canAcceptUserInput && !noConfirm) {
final confirm = logger.confirm('Would you like to continue?');
if (!confirm) {
logger.info('Aborting.');
throw ProcessExit(ExitCode.success.code);
}
}
}
/// Fetches the release with version [version] from the server or creates a
@@ -266,7 +266,6 @@ void main() {
display: any(named: 'display'),
),
).thenReturn(release);
when(() => logger.confirm(any())).thenReturn(true);
when(() => logger.progress(any())).thenReturn(progress);
when(() => patcher.assertArgsAreValid()).thenAnswer((_) async {});
@@ -599,7 +598,7 @@ void main() {
];
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -630,7 +629,7 @@ void main() {
];
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -665,7 +664,7 @@ void main() {
];
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -696,7 +695,7 @@ void main() {
];
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -734,7 +733,7 @@ void main() {
];
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -761,7 +760,7 @@ void main() {
test('completes, does not print error message', () async {
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -791,7 +790,7 @@ void main() {
test('prints error message and exits', () async {
await expectLater(
runWithOverrides(
() => command.confirmCreatePatch(
() => command.logPatchSummary(
app: appMetadata,
releaseVersion: releaseVersion,
patcher: patcher,
@@ -870,7 +869,6 @@ void main() {
releaseId: release.id,
releaseArtifact: any(named: 'releaseArtifact'),
),
() => logger.confirm('Would you like to continue?'),
() => patcher.updatedCreatePatchMetadata(
any(
that: isA<CreatePatchMetadata>().having(
@@ -1069,7 +1067,6 @@ void main() {
releaseId: release.id,
releaseArtifact: any(named: 'releaseArtifact'),
),
() => logger.confirm('Would you like to continue?'),
() => patcher.uploadPatchArtifacts(
appId: appId,
releaseId: release.id,
@@ -1298,20 +1295,6 @@ void main() {
});
});
group('when user declines to continue', () {
setUp(() {
when(() => logger.confirm(any())).thenReturn(false);
});
test('exits with message and success code', () async {
await expectLater(
() => runWithOverrides(command.run),
exitsWithCode(ExitCode.success),
);
verify(() => logger.info('Aborting.')).called(1);
});
});
group('when the target release is in a draft state', () {
setUp(() {
when(
@@ -138,7 +138,6 @@ void main() {
).thenAnswer((_) async {});
when(() => logger.progress(any())).thenReturn(progress);
when(() => logger.confirm(any())).thenReturn(true);
when(() => releaser.artifactDisplayName).thenReturn(artifactDisplayName);
when(() => releaser.assertPreconditions()).thenAnswer((_) async => {});
@@ -181,7 +180,6 @@ void main() {
() => shorebirdEnv.getShorebirdProjectRoot(),
).thenReturn(projectRoot);
when(() => shorebirdEnv.flutterRevision).thenReturn(flutterRevision);
when(() => shorebirdEnv.canAcceptUserInput).thenReturn(true);
when(() => shorebirdEnv.usesShorebirdCodePushPackage).thenReturn(true);
when(
@@ -389,7 +387,6 @@ void main() {
verify(() => logger.info('No issues detected.')).called(1);
verifyNever(() => logger.confirm(any()));
verifyNever(
() => codePushClientWrapper.createRelease(
appId: appId,
@@ -401,6 +398,8 @@ void main() {
});
});
// This isn't really needed anymore since we don't prompt for confirmation.
// but we do accept a --no-confirm argument for backwards compatibility.
group('when --no-confirm is specified', () {
setUp(() {
when(() => argResults['no-confirm']).thenReturn(true);
@@ -541,20 +540,6 @@ void main() {
});
});
group('when the user does not confirm the release', () {
setUp(() {
when(() => logger.confirm(any())).thenReturn(false);
});
test('exits with code 0', () async {
await expectLater(
() => runWithOverrides(command.run),
exitsWithCode(ExitCode.success),
);
verify(() => logger.info('Aborting.')).called(1);
});
});
group('when flutter-version is provided', () {
const flutterVersion = '3.16.3';
setUp(() {