feat(shorebird_cli): add release-version flag to iOS and Android patch commands (#1400)

This commit is contained in:
Bryan Oltman
2023-10-16 17:20:57 -04:00
committed by GitHub
parent 27dd48f8d3
commit 37b3a1d792
4 changed files with 121 additions and 20 deletions
@@ -50,6 +50,13 @@ class PatchAndroidCommand extends ShorebirdCommand
'flavor',
help: 'The product flavor to use when building the app.',
)
..addOption(
'release-version',
help: '''
The version of the release being patched (e.g. "1.0.0+1").
If this option is not provided, the version number will be determined from the patch artifact.''',
)
..addFlag(
'force',
abbr: 'f',
@@ -125,19 +132,26 @@ class PatchAndroidCommand extends ShorebirdCommand
? './build/app/outputs/bundle/${flavor}Release/app-$flavor-release.aab'
: './build/app/outputs/bundle/release/app-release.aab';
final detectReleaseVersionProgress = logger.progress(
'Detecting release version',
);
final String releaseVersion;
try {
releaseVersion = await extractReleaseVersionFromAppBundle(bundlePath);
detectReleaseVersionProgress.complete(
'Detected release version $releaseVersion',
final argReleaseVersion = results['release-version'] as String?;
if (argReleaseVersion != null) {
logger.detail('Using release version $argReleaseVersion from argument.');
releaseVersion = argReleaseVersion;
} else {
logger.detail('No release version provided. Determining from bundle.');
final detectReleaseVersionProgress = logger.progress(
'Detecting release version',
);
} catch (error) {
detectReleaseVersionProgress.fail('$error');
return ExitCode.software.code;
try {
releaseVersion = await extractReleaseVersionFromAppBundle(bundlePath);
detectReleaseVersionProgress.complete(
'Detected release version $releaseVersion',
);
} catch (error) {
detectReleaseVersionProgress.fail('$error');
return ExitCode.software.code;
}
}
final release = await codePushClientWrapper.getRelease(
@@ -43,6 +43,13 @@ class PatchIosCommand extends ShorebirdCommand
'flavor',
help: 'The product flavor to use when building the app.',
)
..addOption(
'release-version',
help: '''
The version of the release being patched (e.g. "1.0.0+1").
If this option is not provided, the version number will be determined from the patch artifact.''',
)
..addFlag(
'codesign',
help: 'Codesign the application bundle.',
@@ -129,14 +136,21 @@ class PatchIosCommand extends ShorebirdCommand
final plist = Plist(file: plistFile);
final String releaseVersion;
try {
releaseVersion = plist.versionNumber;
} catch (error) {
logger.err('Failed to determine release version: $error');
return ExitCode.software.code;
}
final argReleaseVersion = results['release-version'] as String?;
if (argReleaseVersion != null) {
logger.detail('Using release version $argReleaseVersion from argument.');
releaseVersion = argReleaseVersion;
} else {
logger.detail('No release version provided. Determining from archive.');
try {
releaseVersion = plist.versionNumber;
} catch (error) {
logger.err('Failed to determine release version: $error');
return ExitCode.software.code;
}
logger.info('Detected release version $releaseVersion');
logger.info('Detected release version $releaseVersion');
}
final release = await codePushClientWrapper.getRelease(
appId: appId,
@@ -270,7 +270,6 @@ flutter:
when(() => argResults['staging']).thenReturn(false);
when(() => argResults['dry-run']).thenReturn(false);
when(() => argResults['force']).thenReturn(false);
when(() => argResults['release-version']).thenReturn(release.version);
when(() => auth.isAuthenticated).thenReturn(true);
when(() => auth.client).thenReturn(httpClient);
when(() => logger.progress(any())).thenReturn(progress);
@@ -530,6 +529,38 @@ Please re-run the release command for this version or create a new release.'''),
},
);
group('when release-version option is provided', () {
setUp(() {
when(() => argResults['release-version']).thenReturn(release.version);
});
test('does not extract release version from app bundle', () async {
final tempDir = setUpTempDir();
setUpTempArtifacts(tempDir);
await IOOverrides.runZoned(
() => runWithOverrides(command.run),
getCurrentDirectory: () => tempDir,
);
verifyNever(() => bundletool.getVersionName(any()));
verifyNever(() => bundletool.getVersionCode(any()));
verifyNever(() => logger.progress('Detecting release version'));
});
});
group('when release-version option is not provided', () {
test('extracts release version from app bundle', () async {
final tempDir = setUpTempDir();
setUpTempArtifacts(tempDir);
await IOOverrides.runZoned(
() => runWithOverrides(command.run),
getCurrentDirectory: () => tempDir,
);
verify(() => bundletool.getVersionName(any())).called(1);
verify(() => bundletool.getVersionCode(any())).called(1);
verify(() => logger.progress('Detecting release version')).called(1);
});
});
test('errors when detecting release version name fails', () async {
final exception = Exception(
'Failed to extract version name from app bundle: oops',
@@ -254,7 +254,6 @@ flutter:
when(() => argResults['arch']).thenReturn(arch);
when(() => argResults['dry-run']).thenReturn(false);
when(() => argResults['force']).thenReturn(false);
when(() => argResults['release-version']).thenReturn(release.version);
when(() => argResults['codesign']).thenReturn(true);
when(() => argResults['staging']).thenReturn(false);
when(() => argResults.rest).thenReturn([]);
@@ -669,6 +668,49 @@ Please re-run the release command for this version or create a new release.'''),
},
);
group('when release-version option is provided', () {
const customReleaseVersion = 'custom-release-version';
setUp(() {
when(() => argResults['release-version'])
.thenReturn(customReleaseVersion);
});
test('does not extract release version from archive', () async {
final tempDir = setUpTempDir();
setUpTempArtifacts(tempDir);
await IOOverrides.runZoned(
() => runWithOverrides(command.run),
getCurrentDirectory: () => tempDir,
);
verify(
() => codePushClientWrapper.getRelease(
appId: appId,
releaseVersion: customReleaseVersion,
),
).called(1);
});
});
group('when release-version option is not provided', () {
test('extracts release version from app bundle', () async {
final tempDir = setUpTempDir();
setUpTempArtifacts(tempDir);
await IOOverrides.runZoned(
() => runWithOverrides(command.run),
getCurrentDirectory: () => tempDir,
);
verify(
() => codePushClientWrapper.getRelease(
appId: appId,
releaseVersion: release.version,
),
).called(1);
});
});
test('exits with code 70 when release version cannot be determiend',
() async {
final tempDir = setUpTempDir();