fix(shorebird_cli): validate release version number conforms to semver (#406)
This commit is contained in:
@@ -11,6 +11,7 @@ import 'package:shorebird_cli/src/shorebird_config_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_create_app_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validation_mixin.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:version/version.dart';
|
||||
|
||||
/// {@template release_command}
|
||||
/// `shorebird release`
|
||||
@@ -117,11 +118,27 @@ Did you forget to run "shorebird init"?''',
|
||||
|
||||
if (releaseVersionArg == null) logger.info('');
|
||||
|
||||
final releaseVersion = releaseVersionArg ??
|
||||
logger.prompt(
|
||||
'What is the version of this release?',
|
||||
defaultValue: versionString,
|
||||
String? releaseVersion;
|
||||
var releaseVersionInput = releaseVersionArg;
|
||||
while (releaseVersion == null) {
|
||||
releaseVersionInput = releaseVersionInput ??
|
||||
logger.prompt(
|
||||
'What is the version of this release?',
|
||||
defaultValue: versionString,
|
||||
);
|
||||
try {
|
||||
releaseVersion = Version.parse(releaseVersionInput).toString();
|
||||
} catch (error) {
|
||||
final shouldContinue = logger.confirm(
|
||||
'''"$releaseVersionInput" does not look like a version number. Proceed anyways?''',
|
||||
);
|
||||
if (shouldContinue) {
|
||||
releaseVersion = releaseVersionInput;
|
||||
} else {
|
||||
releaseVersionInput = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final platform = results['platform'] as String;
|
||||
final archNames = architectures.keys.map(
|
||||
@@ -154,7 +171,8 @@ ${styleBold.wrap(lightGreen.wrap('🚀 Ready to create a new release!'))}
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
var release = releases.firstWhereOrNull((r) => r.version == releaseVersion);
|
||||
var release = releases
|
||||
.firstWhereOrNull((r) => r.version == releaseVersion.toString());
|
||||
if (release == null) {
|
||||
final createReleaseProgress = logger.progress('Creating release');
|
||||
try {
|
||||
|
||||
@@ -292,7 +292,7 @@ flutter:
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).writeAsStringSync('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
assets:
|
||||
- some/asset.txt
|
||||
''');
|
||||
await IOOverrides.runZoned(
|
||||
@@ -304,7 +304,7 @@ flutter:
|
||||
equals('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
assets:
|
||||
- some/asset.txt
|
||||
- shorebird.yaml
|
||||
'''),
|
||||
|
||||
@@ -253,8 +253,11 @@ Did you forget to run "shorebird init"?''',
|
||||
test('aborts when user opts out', () async {
|
||||
when(() => logger.confirm(any())).thenReturn(false);
|
||||
when(
|
||||
() => logger.prompt(any(), defaultValue: any(named: 'defaultValue')),
|
||||
).thenReturn(appDisplayName);
|
||||
() => logger.prompt(
|
||||
'What is the version of this release?',
|
||||
defaultValue: any(named: 'defaultValue'),
|
||||
),
|
||||
).thenAnswer((_) => '1.0.0');
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -265,6 +268,91 @@ Did you forget to run "shorebird init"?''',
|
||||
verify(() => logger.info('Aborting.')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'prompts user for version until a valid version is provided',
|
||||
() async {
|
||||
final versionNumberResponses = [
|
||||
'asdf',
|
||||
'y',
|
||||
'1.2.3',
|
||||
];
|
||||
when(
|
||||
() => logger.prompt(
|
||||
'What is the version of this release?',
|
||||
defaultValue: any(named: 'defaultValue'),
|
||||
),
|
||||
).thenAnswer((_) => versionNumberResponses.removeAt(0));
|
||||
when(
|
||||
() => logger.confirm(
|
||||
any(that: contains('does not look like a version')),
|
||||
),
|
||||
).thenReturn(false);
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
command.run,
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(
|
||||
() => logger.confirm(
|
||||
any(
|
||||
that: contains(
|
||||
'"asdf" does not look like a version number',
|
||||
),
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.confirm(
|
||||
any(
|
||||
that: contains(
|
||||
'"y" does not look like a version number',
|
||||
),
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'prompts user for version until they choose to proceed anyways',
|
||||
() async {
|
||||
when(
|
||||
() => logger.prompt(
|
||||
'What is the version of this release?',
|
||||
defaultValue: any(named: 'defaultValue'),
|
||||
),
|
||||
).thenReturn('asdf');
|
||||
when(
|
||||
() => logger.confirm(
|
||||
any(that: contains('does not look like a version number')),
|
||||
),
|
||||
).thenReturn(true);
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
command.run,
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(
|
||||
() => logger.confirm(
|
||||
any(
|
||||
that: contains(
|
||||
'"asdf" does not look like a version number',
|
||||
),
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('throws error when fetching releases fails.', () async {
|
||||
const error = 'something went wrong';
|
||||
when(
|
||||
|
||||
Reference in New Issue
Block a user