diff --git a/packages/shorebird_cli/lib/src/commands/release/release_command.dart b/packages/shorebird_cli/lib/src/commands/release/release_command.dart index 5aa90de7..f7aef42a 100644 --- a/packages/shorebird_cli/lib/src/commands/release/release_command.dart +++ b/packages/shorebird_cli/lib/src/commands/release/release_command.dart @@ -420,6 +420,10 @@ For more information see: ${supportedFlutterVersionsUrl.toLink()}'''); Future resolveTargetFlutterRevision() async { if (flutterVersionArg == 'latest') return shorebirdEnv.flutterRevision; + // Fetch the latest remote refs so that release branch pointers + // (e.g. flutter_release/3.38.5) are up to date. + await shorebirdFlutter.fetchRemoteRefs(); + final String? revision; try { revision = await shorebirdFlutter.resolveFlutterRevision( diff --git a/packages/shorebird_cli/lib/src/shorebird_flutter.dart b/packages/shorebird_cli/lib/src/shorebird_flutter.dart index bfba3df2..e741403c 100644 --- a/packages/shorebird_cli/lib/src/shorebird_flutter.dart +++ b/packages/shorebird_cli/lib/src/shorebird_flutter.dart @@ -268,6 +268,19 @@ class ShorebirdFlutter { } } + /// Fetches the latest remote refs for the Flutter clone so that + /// release branch pointers (e.g. `flutter_release/3.38.5`) are up to date. + Future fetchRemoteRefs() async { + try { + await git.fetch(directory: _workingDirectory()); + } on Exception { + logger.warn( + 'Failed to fetch latest Flutter versions. ' + 'Resolving with potentially stale data.', + ); + } + } + /// Returns the git revision for the provided [version]. /// e.g. 3.16.3 -> b9b23902966504a9778f4c07e3a3487fa84dcb2a Future getRevisionForVersion(String version) async { diff --git a/packages/shorebird_cli/test/src/commands/release/release_command_test.dart b/packages/shorebird_cli/test/src/commands/release/release_command_test.dart index 0c21ea49..0ddbc014 100644 --- a/packages/shorebird_cli/test/src/commands/release/release_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/release/release_command_test.dart @@ -192,6 +192,9 @@ void main() { () => shorebirdFlutter.installRevision(revision: any(named: 'revision')), ).thenAnswer((_) async => {}); + when( + () => shorebirdFlutter.fetchRemoteRefs(), + ).thenAnswer((_) async {}); when( () => shorebirdFlutter.resolveFlutterVersion(any()), ).thenAnswer((_) async => flutterVersion); @@ -612,6 +615,17 @@ void main() { when(() => argResults['flutter-version']).thenReturn(flutterVersion); }); + test('fetches remote refs before resolving', () async { + const revision = '771d07b2cf'; + when( + () => shorebirdFlutter.resolveFlutterRevision(any()), + ).thenAnswer((_) async => revision); + + await runWithOverrides(command.run); + + verify(() => shorebirdFlutter.fetchRemoteRefs()).called(1); + }); + group('when unable to determine flutter revision', () { final exception = Exception('oops'); setUp(() { diff --git a/packages/shorebird_cli/test/src/shorebird_flutter_test.dart b/packages/shorebird_cli/test/src/shorebird_flutter_test.dart index 43acaa6a..68a15e91 100644 --- a/packages/shorebird_cli/test/src/shorebird_flutter_test.dart +++ b/packages/shorebird_cli/test/src/shorebird_flutter_test.dart @@ -77,6 +77,9 @@ void main() { args: ['--untracked-files=no', '--porcelain'], ), ).thenAnswer((_) async => ''); + when( + () => git.fetch(directory: any(named: 'directory')), + ).thenAnswer((_) async {}); when( () => git.revParse( revision: any(named: 'revision'), @@ -452,6 +455,40 @@ Tools • Dart 3.0.6 • DevTools 2.23.1'''); }); }); + group('fetchRemoteRefs', () { + test('fetches from remote', () async { + when( + () => git.fetch(directory: any(named: 'directory')), + ).thenAnswer((_) async {}); + + await runWithOverrides( + () => shorebirdFlutter.fetchRemoteRefs(), + ); + + verify( + () => git.fetch(directory: any(named: 'directory')), + ).called(1); + }); + + group('when fetch fails', () { + setUp(() { + when( + () => git.fetch(directory: any(named: 'directory')), + ).thenThrow(Exception('no network')); + }); + + test('logs a warning', () async { + await runWithOverrides( + () => shorebirdFlutter.fetchRemoteRefs(), + ); + + verify( + () => logger.warn(any(that: contains('stale'))), + ).called(1); + }); + }); + }); + group('getRevisionForVersion', () { const version = '3.16.3'; const exception = ProcessException('git', ['rev-parse']);