flutter_flutter/docs/tool/Engine-artifacts.md
John "codefu" McDole eb786c8c49
fix: get content hash for master on local engine branches (#173114)
The content hash doesn't exist for local engine changes, except for on
CI. If we detect we're on a branch with committed or uncommitted changes
to engine files; use "master".

towards #171790

re-land attempt for #172792  with the following changes:

1. content_aware_hash.(ps1|sh) now consider multiple branches to choose
between HEAD and merge-base.
2. content_aware_hash_test.dart updated for these new requirements 
3. content_aware_hash_test.dart allows for forcing powershell on mac for
testing
4. updated docs/tool/Engine-artifacts.md documentation.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
2025-08-01 20:35:26 +00:00

6.4 KiB

How flutter fetches engine artifacts

flutter.dev/to/engine-artifacts

While in the same repository, the flutter (tool), which is used to run and test the framework, needs to know how to download the engine artifacts for the current platform and target device. Engine artifacts include dart (the standalone Dart SDK), which runs flutter itself, and per-platform and build mode prebuilt engines (which include the C++ compiled engine, and the embedders for Android, iOS, and so-on).

An example of cached engine artifacts

When using a released version of Flutter, i.e. from a channel such as stable, bin/internal/engine.version is set to the content hash SHA for a merged commit in https://github.com/flutter/flutter, where the engine artifacts have already been pre-built and uploaded.

When using the master channel, or contributing to Flutter (which is typically as a fork of Flutter's master channel), the engine SHA is computed by generating a content-aware hash of files that affect the engine build (such as DEPS and the engine directory itself).

For advanced use-cases, such as on CI platforms, or for custom 1-off testing using a pre-built Flutter engine (to use a locally built Flutter engine see locally built engines), the environment variable FLUTTER_PREBUILT_ENGINE_VERSION can be set, again to a engine SHA for a merged commit in flutter/flutter. This is only needed if different artifacts from the content sha are desired:

$ FLUTTER_PREBUILT_ENGINE_VERSION=abc123 flutter --version
..
Engine • revision abc123 ..
..
stateDiagram-v2
    [*] --> CheckEnvVar
    CheckEnvVar: <code>FLUTTER_PREBUILT_ENGINE_VERSION</code> set?
    UseEnvVar: Use <code>FLUTTER_PREBUILT_ENGINE_VERSION</code>
    CheckReleaseFile: <code>bin/internal/engine.version</code> exists?
    UseReleaseFile: Use <code>bin/internal/engine.version</code>
    UseContentAwareHash: Compute content-aware hash

    CheckEnvVar --> UseEnvVar: Yes
    CheckEnvVar --> CheckReleaseFile: No
    UseEnvVar --> [*]: Done
    CheckReleaseFile --> UseReleaseFile: Yes
    CheckReleaseFile --> UseContentAwareHash: No
    UseReleaseFile --> [*]: Done
    UseContentAwareHash --> [*]: Done

Flutter CI/CD Testing

On Cocoon (Flutter's internal CI/CD) we often set FLUTTER_PREBUILT_ENGINE_VERSION to the following:

Branch Presubmit Merge Queue Postsubmit
main content.sha content.sha content.sha
flutter-x.x-candidate.x content.sha N/A1 content.sha
stable or beta N/A2 N/A1 N/A2
anything else3 content.sha content.sh content.sha

To generate a new engine.version:

./bin/internal/content_aware_hash.sh > ./bin/internal/engine.version

As of b0ccfb53801abc9b0aa93e7cca3a3841513c3086 (May 6 2025), the packaging release process will refuse to let you publish a release with an out of date engine.version.

Content Hashing

The content hash is a fingerprint of the assets used in producing engine artifacts. These include:

  • DEPS: Used to pull third_party dependencies.
  • engine/: The entire engine subfolder4.
  • bin/internal/release-candidate-branch.version: A signal for release builds, keeping builds hermetic.

The Flutter project has a plethora of users: engineers working from local branches, release branches, GitHub merge queues, and downstream shallow consumers to name the known ones. The following table shows where the content hash is calculated from:

Branch Hashed From
main HEAD
master HEAD
stable HEAD
beta HEAD
GitHub Merge Queue HEAD
flutter-*-candidate.x HEAD
Shallow Clones HEAD
Everything Else. merge-base between HEAD and(origin or upstream)/(main or master)

References

The script(s) that compute (and test the computation of) the engine version:

The tool uses the engine version in the following locations:


  1. Does not use a merge queue. ↩︎

  2. Only updated through flutter-x.x-candidate.x branches. ↩︎

  3. I.e. experimental branches that do not fall into one of the above. ↩︎

  4. This is suboptimal from an artifact building perspective, but optimal for the speed of each dart and flutter call. Flutter is called more often than it is built. ↩︎