diff --git a/dev/bots/prepare_package.dart b/dev/bots/prepare_package.dart index adf334428a..449a9256ee 100644 --- a/dev/bots/prepare_package.dart +++ b/dev/bots/prepare_package.dart @@ -11,6 +11,7 @@ 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:meta/meta.dart' show required; import 'package:path/path.dart' as path; import 'package:platform/platform.dart' show Platform, LocalPlatform; import 'package:process/process.dart'; @@ -26,6 +27,7 @@ const String oldBaseUrl = 'https://storage.googleapis.com/flutter_infra'; const String newGsBase = 'gs://flutter_infra_release'; const String newGsReleaseFolder = '$newGsBase$releaseFolder'; const String newBaseUrl = 'https://storage.googleapis.com/flutter_infra_release'; +const int shortCacheSeconds = 60; /// Exception class for when a process fails to run, so we can catch /// it and provide something more readable than a stack trace. @@ -547,7 +549,10 @@ class ArchivePublisher { ); } } - await _cloudCopy(outputFile.absolute.path, destGsPath); + await _cloudCopy( + src: outputFile.absolute.path, + dest: destGsPath, + ); assert(tempDir.existsSync()); await _updateMetadata('$releaseFolder/${getMetadataFilename(platform)}', newBucket: false); } @@ -614,7 +619,14 @@ class ArchivePublisher { const JsonEncoder encoder = JsonEncoder.withIndent(' '); metadataFile.writeAsStringSync(encoder.convert(jsonData)); } - await _cloudCopy(metadataFile.absolute.path, gsPath); + await _cloudCopy( + src: metadataFile.absolute.path, + dest: gsPath, + // This metadata file is used by the website, so we don't want a long + // latency between publishing a release and it being available on the + // site. + cacheSeconds: shortCacheSeconds, + ); } Future _runGsUtil( @@ -655,7 +667,11 @@ class ArchivePublisher { return true; } - Future _cloudCopy(String src, String dest) async { + Future _cloudCopy({ + @required String src, + @required String dest, + int cacheSeconds, + }) async { // We often don't have permission to overwrite, but // we have permission to remove, so that's what we do. await _runGsUtil(['rm', dest], failOk: true); @@ -673,6 +689,7 @@ class ArchivePublisher { // Use our preferred MIME type for the files we care about // and let gsutil figure it out for anything else. if (mimeType != null) ...['-h', 'Content-Type:$mimeType'], + if (cacheSeconds != null) ...['-h', 'Cache-Control:max-age=$cacheSeconds'], 'cp', src, dest, @@ -804,7 +821,7 @@ Future main(List rawArguments) async { branch, version, outputFile, - parsedArguments['dry_run'] as bool, + parsedArguments['dry_run'] as bool, ); await publisher.publishArchive(parsedArguments['force'] as bool); } diff --git a/dev/bots/test/prepare_package_test.dart b/dev/bots/test/prepare_package_test.dart index 4b19ef4104..828d8cc8f1 100644 --- a/dev/bots/test/prepare_package_test.dart +++ b/dev/bots/test/prepare_package_test.dart @@ -301,13 +301,13 @@ void main() { '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null, '$gsutilCall -- cp $gsJsonPath $jsonPath': null, '$gsutilCall -- rm $gsJsonPath': null, - '$gsutilCall -- -h Content-Type:application/json cp $jsonPath $gsJsonPath': null, + '$gsutilCall -- -h Content-Type:application/json -h Cache-Control:max-age=60 cp $jsonPath $gsJsonPath': null, '$gsutilCall -- stat $newGsArchivePath': [ProcessResult(0, 1, '', '')], '$gsutilCall -- rm $newGsArchivePath': null, '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $newGsArchivePath': null, '$gsutilCall -- cp $newGsJsonPath $jsonPath': null, '$gsutilCall -- rm $newGsJsonPath': null, - '$gsutilCall -- -h Content-Type:application/json cp $jsonPath $newGsJsonPath': null, + '$gsutilCall -- -h Content-Type:application/json -h Cache-Control:max-age=60 cp $jsonPath $newGsJsonPath': null, }; processManager.addCommands(convertResults(calls)); final File outputFile = File(path.join(tempDir.absolute.path, archiveName)); @@ -437,12 +437,12 @@ void main() { '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null, '$gsutilCall -- cp $gsJsonPath $jsonPath': null, '$gsutilCall -- rm $gsJsonPath': null, - '$gsutilCall -- -h Content-Type:application/json cp $jsonPath $gsJsonPath': null, + '$gsutilCall -- -h Content-Type:application/json -h Cache-Control:max-age=60 cp $jsonPath $gsJsonPath': null, '$gsutilCall -- rm $newGsArchivePath': null, '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $newGsArchivePath': null, '$gsutilCall -- cp $newGsJsonPath $jsonPath': null, '$gsutilCall -- rm $newGsJsonPath': null, - '$gsutilCall -- -h Content-Type:application/json cp $jsonPath $newGsJsonPath': null, + '$gsutilCall -- -h Content-Type:application/json -h Cache-Control:max-age=60 cp $jsonPath $newGsJsonPath': null, }; processManager.addCommands(convertResults(calls)); assert(tempDir.existsSync());