Add SHA256 checksums to published metadata (#28472)
Adds SHA256 checksums to the released package database, in preparation for showing them on the download website. (I'll update the existing data by hand). Fixes #28465
This commit is contained in:
parent
d2a76414f4
commit
c940088985
@ -8,10 +8,12 @@ import 'dart:io' hide Platform;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:crypto/src/digest_sink.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:process/process.dart';
|
||||
import 'package:platform/platform.dart' show Platform, LocalPlatform;
|
||||
import 'package:process/process.dart';
|
||||
|
||||
const String chromiumRepo = 'https://chromium.googlesource.com/external/github.com/flutter/flutter';
|
||||
const String githubRepo = 'https://github.com/flutter/flutter.git';
|
||||
@ -196,14 +198,14 @@ class ArchiveCreator {
|
||||
bool subprocessOutput = true,
|
||||
this.platform = const LocalPlatform(),
|
||||
HttpReader httpReader,
|
||||
}) : assert(revision.length == 40),
|
||||
flutterRoot = Directory(path.join(tempDir.path, 'flutter')),
|
||||
httpReader = httpReader ?? http.readBytes,
|
||||
_processRunner = ProcessRunner(
|
||||
processManager: processManager,
|
||||
subprocessOutput: subprocessOutput,
|
||||
platform: platform,
|
||||
) {
|
||||
}) : assert(revision.length == 40),
|
||||
flutterRoot = Directory(path.join(tempDir.path, 'flutter')),
|
||||
httpReader = httpReader ?? http.readBytes,
|
||||
_processRunner = ProcessRunner(
|
||||
processManager: processManager,
|
||||
subprocessOutput: subprocessOutput,
|
||||
platform: platform,
|
||||
) {
|
||||
_flutter = path.join(
|
||||
flutterRoot.absolute.path,
|
||||
'bin',
|
||||
@ -311,8 +313,7 @@ class ArchiveCreator {
|
||||
final File gitFile = File(path.join(tempDir.absolute.path, 'mingit.zip'));
|
||||
await gitFile.writeAsBytes(data, flush: true);
|
||||
|
||||
final Directory minGitPath =
|
||||
Directory(path.join(flutterRoot.absolute.path, 'bin', 'mingit'));
|
||||
final Directory minGitPath = Directory(path.join(flutterRoot.absolute.path, 'bin', 'mingit'));
|
||||
await minGitPath.create(recursive: true);
|
||||
await _unzipArchive(gitFile, workingDirectory: minGitPath);
|
||||
}
|
||||
@ -435,13 +436,13 @@ class ArchivePublisher {
|
||||
ProcessManager processManager,
|
||||
bool subprocessOutput = true,
|
||||
this.platform = const LocalPlatform(),
|
||||
}) : assert(revision.length == 40),
|
||||
platformName = platform.operatingSystem.toLowerCase(),
|
||||
metadataGsPath = '$gsReleaseFolder/${getMetadataFilename(platform)}',
|
||||
_processRunner = ProcessRunner(
|
||||
processManager: processManager,
|
||||
subprocessOutput: subprocessOutput,
|
||||
);
|
||||
}) : assert(revision.length == 40),
|
||||
platformName = platform.operatingSystem.toLowerCase(),
|
||||
metadataGsPath = '$gsReleaseFolder/${getMetadataFilename(platform)}',
|
||||
_processRunner = ProcessRunner(
|
||||
processManager: processManager,
|
||||
subprocessOutput: subprocessOutput,
|
||||
);
|
||||
|
||||
final Platform platform;
|
||||
final String platformName;
|
||||
@ -456,6 +457,18 @@ class ArchivePublisher {
|
||||
String get destinationArchivePath => '$branchName/$platformName/${path.basename(outputFile.path)}';
|
||||
static String getMetadataFilename(Platform platform) => 'releases_${platform.operatingSystem.toLowerCase()}.json';
|
||||
|
||||
Future<String> _getChecksum(File archiveFile) async {
|
||||
final DigestSink digestSink = DigestSink();
|
||||
final ByteConversionSink sink = sha256.startChunkedConversion(digestSink);
|
||||
|
||||
final Stream<List<int>> stream = archiveFile.openRead();
|
||||
await stream.forEach((List<int> chunk) {
|
||||
sink.add(chunk);
|
||||
});
|
||||
sink.close();
|
||||
return digestSink.value.toString();
|
||||
}
|
||||
|
||||
/// Publish the archive to Google Storage.
|
||||
Future<void> publishArchive() async {
|
||||
final String destGsPath = '$gsReleaseFolder/$destinationArchivePath';
|
||||
@ -464,7 +477,7 @@ class ArchivePublisher {
|
||||
await _updateMetadata();
|
||||
}
|
||||
|
||||
Map<String, dynamic> _addRelease(Map<String, dynamic> jsonData) {
|
||||
Future<Map<String, dynamic>> _addRelease(Map<String, dynamic> jsonData) async {
|
||||
jsonData['base_url'] = '$baseUrl$releaseFolder';
|
||||
if (!jsonData.containsKey('current_release')) {
|
||||
jsonData['current_release'] = <String, String>{};
|
||||
@ -480,6 +493,7 @@ class ArchivePublisher {
|
||||
newEntry['version'] = version;
|
||||
newEntry['release_date'] = DateTime.now().toUtc().toIso8601String();
|
||||
newEntry['archive'] = destinationArchivePath;
|
||||
newEntry['sha256'] = await _getChecksum(outputFile);
|
||||
|
||||
// Search for any entries with the same hash and channel and remove them.
|
||||
final List<dynamic> releases = jsonData['releases'];
|
||||
@ -521,7 +535,7 @@ class ArchivePublisher {
|
||||
throw ProcessRunnerException('Unable to parse JSON metadata received from cloud: $e');
|
||||
}
|
||||
|
||||
jsonData = _addRelease(jsonData);
|
||||
jsonData = await _addRelease(jsonData);
|
||||
|
||||
const JsonEncoder encoder = JsonEncoder.withIndent(' ');
|
||||
metadataFile.writeAsStringSync(encoder.convert(jsonData));
|
||||
|
@ -238,26 +238,30 @@ void main() {
|
||||
"channel": "dev",
|
||||
"version": "v0.2.3",
|
||||
"release_date": "2018-03-20T01:47:02.851729Z",
|
||||
"archive": "dev/$platformName/flutter_${platformName}_v0.2.3-dev.zip"
|
||||
"archive": "dev/$platformName/flutter_${platformName}_v0.2.3-dev.zip",
|
||||
"sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8"
|
||||
},
|
||||
{
|
||||
"hash": "b9bd51cc36b706215915711e580851901faebb40",
|
||||
"channel": "beta",
|
||||
"version": "v0.2.2",
|
||||
"release_date": "2018-03-16T18:48:13.375013Z",
|
||||
"archive": "dev/$platformName/flutter_${platformName}_v0.2.2-dev.zip"
|
||||
"archive": "dev/$platformName/flutter_${platformName}_v0.2.2-dev.zip",
|
||||
"sha256": "6073331168cdb37a4637a5dc073d6a7ef4e466321effa2c529fa27d2253a4d4b"
|
||||
},
|
||||
{
|
||||
"hash": "$testRef",
|
||||
"channel": "stable",
|
||||
"version": "v0.0.0",
|
||||
"release_date": "2018-03-20T01:47:02.851729Z",
|
||||
"archive": "stable/$platformName/flutter_${platformName}_v0.0.0-dev.zip"
|
||||
"archive": "stable/$platformName/flutter_${platformName}_v0.0.0-dev.zip",
|
||||
"sha256": "5dd34873b3a3e214a32fd30c2c319a0f46e608afb72f0d450b2d621a6d02aebd"
|
||||
}
|
||||
]
|
||||
}
|
||||
''';
|
||||
File(jsonPath).writeAsStringSync(releasesJson);
|
||||
File(archivePath).writeAsStringSync('archive contents');
|
||||
final String gsutilCall = platform.isWindows
|
||||
? 'python ${path.join("D:", "depot_tools", "gsutil.py")}'
|
||||
: 'gsutil.py';
|
||||
@ -291,6 +295,7 @@ void main() {
|
||||
expect(contents, contains('"hash": "$testRef"'));
|
||||
expect(contents, contains('"channel": "stable"'));
|
||||
expect(contents, contains('"archive": "stable/$platformName/$archiveName"'));
|
||||
expect(contents, contains('"sha256": "f69f4865f861193a91d1c5544a894167a7137b788d10bac8edbf5d095f45cb4d"'));
|
||||
// Make sure existing entries are preserved.
|
||||
expect(contents, contains('"hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"'));
|
||||
expect(contents, contains('"hash": "b9bd51cc36b706215915711e580851901faebb40"'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user