From a8bfdfc394deaed5c57bd45a64ac4294dc976a72 Mon Sep 17 00:00:00 2001 From: flutteractionsbot <154381524+flutteractionsbot@users.noreply.github.com> Date: Fri, 22 Aug 2025 16:51:12 -0700 Subject: [PATCH] [CP-stable]`_downloadArtifacts` (Web SDK) uses content-aware hashing in post-submit (#174309) This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: What is the link to the issue this cherry-pick is addressing? < Replace with issue link here > ### Changelog Description: Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examples < Replace with changelog description here > ### Impact Description: What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch) < Replace with impact description here > ### Workaround: Is there a workaround for this issue? < Replace with workaround here > ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: What are the steps to validate that this fix works? < Replace with validation steps here > --- engine/src/flutter/lib/web_ui/dev/common.dart | 25 +++++++++++++++++++ .../flutter/lib/web_ui/dev/environment.dart | 6 +++++ .../web_ui/dev/steps/copy_artifacts_step.dart | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/lib/web_ui/dev/common.dart b/engine/src/flutter/lib/web_ui/dev/common.dart index 6c9ecfab227..4a4af8f414b 100644 --- a/engine/src/flutter/lib/web_ui/dev/common.dart +++ b/engine/src/flutter/lib/web_ui/dev/common.dart @@ -258,6 +258,31 @@ final String gitRevision = () { return (result.stdout as String).trim(); }(); +final String contentHash = () { + final String executable; + final List args; + if (io.Platform.isWindows) { + executable = 'powershell'; + args = [path.join('bin', 'internal', 'content_aware_hash.ps1')]; + } else { + executable = path.join('bin', 'internal', 'content_aware_hash.sh'); + args = []; + } + final result = io.Process.runSync( + executable, + args, + workingDirectory: environment.flutterRootDir.path, + stderrEncoding: utf8, + stdoutEncoding: utf8, + ); + if (result.exitCode != 0) { + throw ToolExit( + 'Failed to get content hash. Exit code: ${result.exitCode} Error: ${result.stderr}', + ); + } + return (result.stdout as String).trim(); +}(); + const String kChrome = 'chrome'; const String kEdge = 'edge'; const String kFirefox = 'firefox'; diff --git a/engine/src/flutter/lib/web_ui/dev/environment.dart b/engine/src/flutter/lib/web_ui/dev/environment.dart index 47a7255f8af..19b6629cd3b 100644 --- a/engine/src/flutter/lib/web_ui/dev/environment.dart +++ b/engine/src/flutter/lib/web_ui/dev/environment.dart @@ -24,6 +24,7 @@ class Environment { final io.File self = io.File.fromUri(io.Platform.script); final io.Directory engineSrcDir = self.parent.parent.parent.parent.parent; + final io.Directory flutterRootDir = engineSrcDir.parent.parent; final io.Directory engineToolsDir = io.Directory( pathlib.join(engineSrcDir.path, 'flutter', 'tools'), ); @@ -52,6 +53,7 @@ class Environment { isMacosArm: isMacosArm, webUiRootDir: webUiRootDir, engineSrcDir: engineSrcDir, + flutterRootDir: flutterRootDir, engineToolsDir: engineToolsDir, outDir: outDir, wasmReleaseOutDir: wasmReleaseOutDir, @@ -67,6 +69,7 @@ class Environment { required this.isMacosArm, required this.webUiRootDir, required this.engineSrcDir, + required this.flutterRootDir, required this.engineToolsDir, required this.outDir, required this.wasmReleaseOutDir, @@ -137,6 +140,9 @@ class Environment { 'dart2wasm.dart', ); + /// Path to the root flutter directory (which itself contains `engine/src/flutter`). + final io.Directory flutterRootDir; + /// Path to where github.com/flutter/engine is checked out inside the engine workspace. io.Directory get flutterDirectory => io.Directory(pathlib.join(engineSrcDir.path, 'flutter')); io.Directory get webSdkRootDir => io.Directory(pathlib.join(flutterDirectory.path, 'web_sdk')); diff --git a/engine/src/flutter/lib/web_ui/dev/steps/copy_artifacts_step.dart b/engine/src/flutter/lib/web_ui/dev/steps/copy_artifacts_step.dart index 56918bec5dd..d0629b34a67 100644 --- a/engine/src/flutter/lib/web_ui/dev/steps/copy_artifacts_step.dart +++ b/engine/src/flutter/lib/web_ui/dev/steps/copy_artifacts_step.dart @@ -57,7 +57,7 @@ class CopyArtifactsStep implements PipelineStep { }; final Uri url = Uri.https( 'storage.googleapis.com', - '${realmComponent}flutter_infra_release/flutter/$gitRevision/flutter-web-sdk.zip', + '${realmComponent}flutter_infra_release/flutter/${realm == LuciRealm.Try ? gitRevision : contentHash}/flutter-web-sdk.zip', ); final http.Response response = await http.Client().get(url); if (response.statusCode != 200) {