Output Dart SDK version in published metadata (#96302)
diff --git a/dev/bots/prepare_package.dart b/dev/bots/prepare_package.dart index 433b7be..01a5625 100644 --- a/dev/bots/prepare_package.dart +++ b/dev/bots/prepare_package.dart
@@ -24,6 +24,8 @@ const String gsReleaseFolder = '$gsBase$releaseFolder'; const String baseUrl = 'https://storage.googleapis.com/flutter_infra_release'; const int shortCacheSeconds = 60; +const String frameworkVersionTag = 'frameworkVersionFromGit'; +const String dartVersionTag = 'dartSdkVersion'; /// Exception class for when a process fails to run, so we can catch /// it and provide something more readable than a stack trace. @@ -251,7 +253,7 @@ final HttpReader httpReader; late File _outputFile; - late String _version; + final Map<String, String> _version = <String, String>{}; late String _flutter; /// Get the name of the channel as a string. @@ -269,21 +271,24 @@ // unpacking it!) So, we use .zip for Mac, and the files are about // 220MB larger than they need to be. :-( final String suffix = platform.isLinux ? 'tar.xz' : 'zip'; - return 'flutter_${os}_$_version-$branchName.$suffix'; + return 'flutter_${os}_${_version[frameworkVersionTag]}-$branchName.$suffix'; } /// Checks out the flutter repo and prepares it for other operations. /// - /// Returns the version for this release, as obtained from the git tags. - Future<String> initializeRepo() async { + /// Returns the version for this release as obtained from the git tags, and + /// the dart version as obtained from `flutter --version`. + Future<Map<String, String>> initializeRepo() async { await _checkoutFlutter(); - _version = await _getVersion(); + if (_version.isEmpty) { + _version.addAll(await _getVersion()); + } return _version; } /// Performs all of the steps needed to create an archive. Future<File> createArchive() async { - assert(_version != null, 'Must run initializeRepo before createArchive'); + assert(_version.isNotEmpty, 'Must run initializeRepo before createArchive'); _outputFile = File(path.join(outputDir.absolute.path, _archiveName)); await _installMinGitIfNeeded(); await _populateCaches(); @@ -328,8 +333,8 @@ } } - /// Returns the version number of this release, according the to tags in the - /// repo. + /// Returns the version map of this release, according the to tags in the + /// repo and the output of `flutter --version --machine`. /// /// This looks for the tag attached to [revision] and, if it doesn't find one, /// git will give an error. @@ -337,10 +342,15 @@ /// If [strict] is true, the exact [revision] must be tagged to return the /// version. If [strict] is not true, will look backwards in time starting at /// [revision] to find the most recent version tag. - Future<String> _getVersion() async { + /// + /// The version found as a git tag is added to the information given by + /// `flutter --version --machine` with the `frameworkVersionFromGit` tag, and + /// returned. + Future<Map<String, String>> _getVersion() async { + String gitVersion; if (strict) { try { - return _runGit(<String>['describe', '--tags', '--exact-match', revision]); + gitVersion = await _runGit(<String>['describe', '--tags', '--exact-match', revision]); } on PreparePackageException catch (exception) { throw PreparePackageException( 'Git error when checking for a version tag attached to revision $revision.\n' @@ -349,8 +359,18 @@ ); } } else { - return _runGit(<String>['describe', '--tags', '--abbrev=0', revision]); + gitVersion = await _runGit(<String>['describe', '--tags', '--abbrev=0', revision]); } + // Run flutter command twice, once to make sure the flutter command is built + // and ready (and thus won't output any junk on stdout the second time), and + // once to capture theJSON output. The second run should be fast. + await _runFlutter(<String>['--version', '--machine']); + final String versionJson = await _runFlutter(<String>['--version', '--machine']); + final Map<String, String> versionMap = <String, String>{}; + final Map<String, dynamic> result = json.decode(versionJson) as Map<String, dynamic>; + result.forEach((String key, dynamic value) => versionMap[key] = value.toString()); + versionMap[frameworkVersionTag] = gitVersion; + return versionMap; } /// Clone the Flutter repo and make sure that the git environment is sane @@ -546,7 +566,7 @@ final String metadataGsPath; final Branch branch; final String revision; - final String version; + final Map<String, String> version; final Directory tempDir; final File outputFile; final ProcessRunner _processRunner; @@ -601,7 +621,8 @@ final Map<String, dynamic> newEntry = <String, dynamic>{}; newEntry['hash'] = revision; newEntry['channel'] = branchName; - newEntry['version'] = version; + newEntry['version'] = version[frameworkVersionTag]; + newEntry['dart_sdk_version'] = version[dartVersionTag]; newEntry['release_date'] = DateTime.now().toUtc().toIso8601String(); newEntry['archive'] = destinationArchivePath; newEntry['sha256'] = await _getChecksum(outputFile); @@ -630,24 +651,25 @@ path.join(tempDir.absolute.path, getMetadataFilename(platform)), ); await _runGsUtil(<String>['cp', gsPath, metadataFile.absolute.path]); + Map<String, dynamic> jsonData = <String, dynamic>{}; if (!dryRun) { final String currentMetadata = metadataFile.readAsStringSync(); if (currentMetadata.isEmpty) { throw PreparePackageException('Empty metadata received from server'); } - - Map<String, dynamic> jsonData; try { jsonData = json.decode(currentMetadata) as Map<String, dynamic>; } on FormatException catch (e) { throw PreparePackageException('Unable to parse JSON metadata received from cloud: $e'); } - - jsonData = await _addRelease(jsonData); - - const JsonEncoder encoder = JsonEncoder.withIndent(' '); - metadataFile.writeAsStringSync(encoder.convert(jsonData)); } + // Run _addRelease, even on a dry run, so we can inspect the metadata on a + // dry run. On a dry run, the only thing in the metadata file be the new + // release. + jsonData = await _addRelease(jsonData); + + const JsonEncoder encoder = JsonEncoder.withIndent(' '); + metadataFile.writeAsStringSync(encoder.convert(jsonData)); await _cloudCopy( src: metadataFile.absolute.path, dest: gsPath, @@ -832,7 +854,7 @@ int exitCode = 0; late String message; try { - final String version = await creator.initializeRepo(); + final Map<String, String> version = await creator.initializeRepo(); final File outputFile = await creator.createArchive(); if (parsedArguments['publish'] as bool) { final ArchivePublisher publisher = ArchivePublisher(
diff --git a/dev/bots/test/prepare_package_test.dart b/dev/bots/test/prepare_package_test.dart index d1f89ae..2c4e9cd 100644 --- a/dev/bots/test/prepare_package_test.dart +++ b/dev/bots/test/prepare_package_test.dart
@@ -7,7 +7,7 @@ import 'dart:typed_data'; import 'package:path/path.dart' as path; -import 'package:platform/platform.dart' show FakePlatform; +import 'package:platform/platform.dart' show FakePlatform, Platform; import '../../../packages/flutter_tools/test/src/fake_process_manager.dart'; import '../prepare_package.dart'; @@ -34,7 +34,7 @@ )), ); }); - for (final String platformName in <String>['macos', 'linux', 'windows']) { + for (final String platformName in <String>[Platform.macOS, Platform.linux, Platform.windows]) { final FakePlatform platform = FakePlatform( operatingSystem: platformName, environment: <String, String>{ @@ -123,6 +123,10 @@ 'git reset --hard $testRef': null, 'git remote set-url origin https://github.com/flutter/flutter.git': null, 'git describe --tags --exact-match $testRef': <ProcessResult>[ProcessResult(0, 0, 'v1.2.3', '')], + '$flutter --version --machine': <ProcessResult>[ + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ], if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null, '$flutter doctor': null, '$flutter update-packages': null, @@ -152,6 +156,10 @@ 'git reset --hard $testRef': null, 'git remote set-url origin https://github.com/flutter/flutter.git': null, 'git describe --tags --exact-match $testRef': <ProcessResult>[ProcessResult(0, 0, 'v1.2.3', '')], + '$flutter --version --machine': <ProcessResult>[ + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ], if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null, '$flutter doctor': null, '$flutter update-packages': null, @@ -202,6 +210,10 @@ 'git reset --hard $testRef': null, 'git remote set-url origin https://github.com/flutter/flutter.git': null, 'git describe --tags --abbrev=0 $testRef': <ProcessResult>[ProcessResult(0, 0, 'v1.2.3', '')], + '$flutter --version --machine': <ProcessResult>[ + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ], if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null, '$flutter doctor': null, '$flutter update-packages': null, @@ -244,6 +256,10 @@ 'git reset --hard $testRef': null, 'git remote set-url origin https://github.com/flutter/flutter.git': null, 'git describe --tags --exact-match $testRef': <ProcessResult>[ProcessResult(0, 0, 'v1.2.3', '')], + '$flutter --version --machine': <ProcessResult>[ + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''), + ], if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null, '$flutter doctor': null, '$flutter update-packages': null, @@ -362,7 +378,7 @@ tempDir, testRef, Branch.stable, - 'v1.2.3', + <String, String>{'frameworkVersionFromGit': 'v1.2.3', 'dartSdkVersion': '3.2.1'}, outputFile, false, processManager: processManager, @@ -458,7 +474,7 @@ tempDir, testRef, Branch.stable, - 'v1.2.3', + <String, String>{'frameworkVersionFromGit': 'v1.2.3', 'dartSdkVersion': '3.2.1'}, outputFile, false, processManager: processManager, @@ -482,7 +498,7 @@ tempDir, testRef, Branch.stable, - 'v1.2.3', + <String, String>{'frameworkVersionFromGit': 'v1.2.3', 'dartSdkVersion': '3.2.1'}, outputFile, false, processManager: processManager, @@ -504,7 +520,7 @@ tempDir, testRef, Branch.stable, - 'v1.2.3', + <String, String>{'frameworkVersionFromGit': 'v1.2.3', 'dartSdkVersion': '3.2.1'}, outputFile, false, processManager: processManager,