feat(shorebird_cli): shorebird release includes flutter_revision (#478)

This commit is contained in:
Felix Angelov
2023-05-12 11:40:43 -07:00
committed by GitHub
parent 01df7ed3ee
commit 3cf1198371
7 changed files with 95 additions and 2 deletions
@@ -191,11 +191,24 @@ ${summary.join('\n')}
var release = releases.firstWhereOrNull((r) => r.version == releaseVersion);
if (release == null) {
final flutterRevisionProgress = logger.progress(
'Fetching Flutter revision',
);
final String shorebirdFlutterRevision;
try {
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
flutterRevisionProgress.complete();
} catch (error) {
flutterRevisionProgress.fail('$error');
return ExitCode.software.code;
}
final createReleaseProgress = logger.progress('Creating release');
try {
release = await codePushClient.createRelease(
appId: app.id,
version: releaseVersion,
flutterRevision: shorebirdFlutterRevision,
);
createReleaseProgress.complete();
} catch (error) {
@@ -10,6 +10,7 @@ import 'package:shorebird_cli/src/auth/auth.dart';
import 'package:shorebird_cli/src/cache.dart';
import 'package:shorebird_cli/src/commands/commands.dart';
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
import 'package:shorebird_cli/src/shorebird_environment.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -41,6 +42,7 @@ class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
void main() {
group(ReleaseCommand, () {
const appId = 'test-app-id';
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
const versionName = '1.2.3';
const versionCode = '1';
const version = '$versionName+$versionCode';
@@ -52,7 +54,7 @@ void main() {
id: 0,
appId: appId,
version: version,
flutterRevision: '83305b5088e6fe327fb3334a73ff190828d85713',
flutterRevision: flutterRevision,
displayName: '1.2.3+1',
);
const releaseArtifact = ReleaseArtifact(
@@ -77,11 +79,14 @@ flutter:
late ArgResults argResults;
late http.Client httpClient;
late Directory shorebirdRoot;
late Platform environmentPlatform;
late Auth auth;
late Cache cache;
late Progress progress;
late Logger logger;
late ProcessResult flutterBuildProcessResult;
late ProcessResult flutterRevisionProcessResult;
late ProcessResult releaseVersionNameProcessResult;
late ProcessResult releaseVersionCodeProcessResult;
late CodePushClient codePushClient;
@@ -123,11 +128,14 @@ flutter:
setUp(() {
argResults = _MockArgResults();
httpClient = _MockHttpClient();
environmentPlatform = _MockPlatform();
shorebirdRoot = Directory.systemTemp.createTempSync();
auth = _MockAuth();
cache = _MockCache();
progress = _MockProgress();
logger = _MockLogger();
flutterBuildProcessResult = _MockProcessResult();
flutterRevisionProcessResult = _MockProcessResult();
releaseVersionNameProcessResult = _MockProcessResult();
releaseVersionCodeProcessResult = _MockProcessResult();
codePushClient = _MockCodePushClient();
@@ -152,6 +160,17 @@ flutter:
registerFallbackValue(shorebirdProcess);
ShorebirdEnvironment.platform = environmentPlatform;
when(() => environmentPlatform.script).thenReturn(
Uri.file(
p.join(
shorebirdRoot.path,
'bin',
'cache',
'shorebird.snapshot',
),
),
);
when(
() => shorebirdProcess.run(
'flutter',
@@ -159,6 +178,14 @@ flutter:
runInShell: any(named: 'runInShell'),
),
).thenAnswer((_) async => flutterBuildProcessResult);
when(
() => shorebirdProcess.run(
'git',
any(),
runInShell: any(named: 'runInShell'),
workingDirectory: any(named: 'workingDirectory'),
),
).thenAnswer((_) async => flutterRevisionProcessResult);
when(
() => shorebirdProcess.run(
'java',
@@ -189,12 +216,18 @@ flutter:
when(
() => flutterBuildProcessResult.exitCode,
).thenReturn(ExitCode.success.code);
when(
() => flutterRevisionProcessResult.exitCode,
).thenReturn(ExitCode.success.code);
when(
() => releaseVersionNameProcessResult.exitCode,
).thenReturn(ExitCode.success.code);
when(
() => releaseVersionCodeProcessResult.exitCode,
).thenReturn(ExitCode.success.code);
when(
() => flutterRevisionProcessResult.stdout,
).thenReturn(flutterRevision);
when(
() => releaseVersionNameProcessResult.stdout,
).thenReturn(versionName);
@@ -211,6 +244,7 @@ flutter:
() => codePushClient.createRelease(
appId: any(named: 'appId'),
version: any(named: 'version'),
flutterRevision: any(named: 'flutterRevision'),
),
).thenAnswer((_) async => release);
when(
@@ -385,6 +419,27 @@ Did you forget to run "shorebird init"?''',
expect(exitCode, ExitCode.software.code);
});
test('throws error when unable to detect flutter revision', () async {
const error = 'oops';
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
when(
() => codePushClient.getReleases(appId: any(named: 'appId')),
).thenAnswer((_) async => []);
final tempDir = setUpTempDir();
setUpTempArtifacts(tempDir);
final exitCode = await IOOverrides.runZoned(
command.run,
getCurrentDirectory: () => tempDir,
);
expect(exitCode, ExitCode.software.code);
verify(
() => progress.fail(
'Exception: Unable to determine flutter revision: $error',
),
).called(1);
});
test('throws error when creating release fails.', () async {
const error = 'something went wrong';
when(
@@ -394,6 +449,7 @@ Did you forget to run "shorebird init"?''',
() => codePushClient.createRelease(
appId: any(named: 'appId'),
version: any(named: 'version'),
flutterRevision: any(named: 'flutterRevision'),
displayName: any(named: 'displayName'),
),
).thenThrow(error);
@@ -23,6 +23,8 @@ Future<void> main() async {
final release = await client.createRelease(
appId: app.id,
version: '<VERSION>', // e.g. '1.0.0'
flutterRevision:
'<FLUTTER_REVISION>', // e.g. 83305b5088e6fe327fb3334a73ff190828d85713,
displayName: '<DISPLAY NAME>', // e.g. 'v1.0.0'
);
@@ -177,6 +177,7 @@ class CodePushClient {
Future<Release> createRelease({
required String appId,
required String version,
required String flutterRevision,
String? displayName,
}) async {
final response = await _httpClient.post(
@@ -184,6 +185,7 @@ class CodePushClient {
body: json.encode({
'app_id': appId,
'version': version,
'flutter_revision': flutterRevision,
if (displayName != null) 'display_name': displayName,
}),
);
@@ -682,6 +682,7 @@ void main() {
codePushClient.createRelease(
appId: appId,
version: version,
flutterRevision: flutterRevision,
displayName: displayName,
),
throwsA(
@@ -712,6 +713,7 @@ void main() {
codePushClient.createRelease(
appId: appId,
version: version,
flutterRevision: flutterRevision,
displayName: displayName,
),
throwsA(
@@ -751,6 +753,7 @@ void main() {
codePushClient.createRelease(
appId: appId,
version: version,
flutterRevision: flutterRevision,
displayName: displayName,
),
completion(
@@ -759,6 +762,11 @@ void main() {
.having((r) => r.id, 'id', releaseId)
.having((r) => r.appId, 'appId', appId)
.having((r) => r.version, 'version', version)
.having(
(r) => r.flutterRevision,
'flutterRevision',
flutterRevision,
)
.having((r) => r.displayName, 'displayName', displayName),
),
),
@@ -11,6 +11,7 @@ class CreateReleaseRequest {
const CreateReleaseRequest({
required this.appId,
required this.version,
this.flutterRevision,
this.displayName,
});
@@ -27,6 +28,10 @@ class CreateReleaseRequest {
/// The release version.
final String version;
/// The Flutter revision used to create the release.
/// This is nullable for backward compatibility.
final String? flutterRevision;
/// The display name for the release.
final String? displayName;
}
@@ -17,11 +17,17 @@ CreateReleaseRequest _$CreateReleaseRequestFromJson(
final val = CreateReleaseRequest(
appId: $checkedConvert('app_id', (v) => v as String),
version: $checkedConvert('version', (v) => v as String),
flutterRevision:
$checkedConvert('flutter_revision', (v) => v as String?),
displayName: $checkedConvert('display_name', (v) => v as String?),
);
return val;
},
fieldKeyMap: const {'appId': 'app_id', 'displayName': 'display_name'},
fieldKeyMap: const {
'appId': 'app_id',
'flutterRevision': 'flutter_revision',
'displayName': 'display_name'
},
);
Map<String, dynamic> _$CreateReleaseRequestToJson(
@@ -29,5 +35,6 @@ Map<String, dynamic> _$CreateReleaseRequestToJson(
<String, dynamic>{
'app_id': instance.appId,
'version': instance.version,
'flutter_revision': instance.flutterRevision,
'display_name': instance.displayName,
};