-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Background
Today, we have update_engine_version.sh (and friends) that do the following:
- If there is a git tracked
bin/internal/engine.versionfile, we use it. Done. - If there is a environment variable named
FLUTTER_PREBUILT_ENGINE_VERSIONset, we use it (write to a otherwise untrackedengine.version). Done. - If this appears to be a monorepo (it's always yes), then we branch:
A. If is a Flutter internal recognized CI/CD (LUCI_CONTEXT), we usegit rev-parse HEADbecause we're building (and using) the engine from source.
B. Otherwise, we usemerge-base HEAD upstream/master(or technically, origin/master, if upstream not set)
stateDiagram-v2
[*] --> CheckBinVersion
CheckBinVersion: bin/internal/engine.version exists?
BinVersionExists: Use bin/internal/engine.version
CheckEnvVar: FLUTTER_PREBUILT_ENGINE_VERSION set?
UseEnvVar: Use FLUTTER_PREBUILT_ENGINE_VERSION
CheckCI: LUCI_CONTEXT set?
UseHead: git rev-parse HEAD
UseMergeBase: git merge-base HEAD upstream/master
CheckBinVersion --> BinVersionExists: Yes
CheckBinVersion --> CheckEnvVar: No
BinVersionExists --> [*]: Done
CheckEnvVar --> UseEnvVar: Yes
CheckEnvVar --> CheckCI: No
UseEnvVar --> [*]: Done
CheckCI --> UseHead: Yes
CheckCI --> UseMergeBase: No
UseHead --> [*]: Done
UseMergeBase --> [*]: Done
The reason to do this is to:
- Skip building the engine for framework-only changes;
- To allow for shipped branches to have a static (pre-computed) engine version;
- For developers of Flutter to get the relevant engine artifacts from the merge queue, similar to (1);
- ... and for CI's to build and test the engine from source (engine changes).
Problem
-
What happens when
bin/internal/engine.versionflips from tracked (i.e. a shipped release) to untracked (i.e.master), or the inverse (frommasterto a shipped release)? There is now contention around the nature of thebin/internal/engine.versionfile - it's either being stomped on (which git prevents) or otherwise the state is unclean. -
How do you test a in-progress shipped branch? It's not shipped yet, so using a stamped
engine.versionisn't semantically correct (we still will have engine cherrypicks, for example, that need to built from source and used for presubmit testing, and even on post-submit, we want to use the latest build, not whatever the lastengine.versionhappened to be)?
Possible Solution
The easiest option is to stop tracking engine.version in the source tree, or at minimum do not over-conflate the "we determined to use abcd1234 as the engine version" with "this is a shipped production release that must use abcd1234". One possible interpretation of this is:
/bin
/internal
/engine.release # Is always tracked by git, but should only be set in a shipped production release.
# This operates a little bit like a "sticky" FLUTTER_PREBUILT_ENGINE_VERSION.
/engine.version # Is *never* tracked by git, and should *only* be set by update_engine_version.{sh|ps1}If we do this, we'd need to:
- Cocoon (our CI) sets
FLUTTER_PREBUILT_ENGINE_VERSIONfor every commit tomaster(pre and post).HEAD(for all post-submits and engine pre-submits)pr.baseRef(for framework pre-submits).
- Cocoon (our CI) will, for cherry-picks to an unshipped release branch, we will set
FLUTTER_PREBUILT_*:HEAD: For pre-submits; build the engine from source, and set???????: For post-submits, store a ref somewhere, and use it
??????? could be a quasi admin-panel on Cocoon, where you associated a commit SHA with a release-branch:
flutter/3.99.99-release-candidate-0.1. ==> abc123Finally, for shipping, the script that finalizes the release would write bin/internal/engine.release.
With this world, the update_engine_version.{sh|ps1} is simplified to:
- If there is a environment variable named
FLUTTER_PREBUILT_ENGINE_VERSIONset, we use it (write to a otherwise untrackedengine.version). Done. - If there is a
bin/internal/engine.versionfile, we write it toengine.versionas is. Done. - We use
merge-base HEAD upstream/master(or technically, origin/master, if upstream not set)
stateDiagram-v2
[*] --> CheckEnvVar
CheckEnvVar: FLUTTER_PREBUILT_ENGINE_VERSION set?
UseEnvVar: Use FLUTTER_PREBUILT_ENGINE_VERSION
CheckReleaseFile: bin/internal/engine.version exists?
UseReleaseFile: Use bin/internal/engine.version
UseMergeBase: git merge-base HEAD upstream/master
CheckEnvVar --> UseEnvVar: Yes
CheckEnvVar --> CheckReleaseFile: No
UseEnvVar --> [*]: Done
CheckReleaseFile --> UseReleaseFile: Yes
CheckReleaseFile --> UseMergeBase: No
UseReleaseFile --> [*]: Done
UseMergeBase --> [*]: Done