release: 0.3.0 — remote_cache_trees by tree kind - #8
Merged
Conversation
remote_cache_trees was one boolean over two artifacts with very different economics. A worker has to materialize the assembled pub cache locally whichever way the flag is set — it feeds the local-only flutter build, and its own @pub_* repository inputs must be fetched to compute any action key at all — so remote-caching it buys a multi-GB download in place of a hardlink assembly. Remote-caching the ~100MB prepared and overlay workspaces buys ~180MB of download in place of a full intl_utils plus build_runner codegen run. Those are not the same decision, so the flag now takes none (default), workspaces or all. PrepareFlutterAppWorkspace had no execution posture at all, unlike every sibling that produces a tree. It was therefore remote-execution eligible — which would mean uploading its no-remote-cache input tree — and its own ~100MB output was uploaded on every build under --remote_upload_local_results, which is precisely the end-of-invocation drain this flag exists to prevent. Also dropped the wall-clock timestamp from the dependency-preparation log: it is a declared output, so a clock reading in it made the action unreproducible for nothing. Documented what workspaces= can and cannot do, because the answer is not obvious and I got it wrong first: the prepared trees are NOT reproducible. .dart_tool records the producing sandbox's absolute execroot in ~16 text files, and — decisively — in the host native-asset binaries JIT codegen links; .dart_tool/hooks_runner/shared/objective_c/build/<hash>/objective_c.dylib holds 17 copies of it in Mach-O load commands, which are length-prefixed and cannot be rewritten. Canonicalizing the text was implemented and reverted for that reason; the finding is recorded next to the action. The SDK filegroup separately contributes 51 source *directories*, which Bazel fingerprints by mtime rather than content, so two independently provisioned workers never agree on a key. workspaces= therefore helps workers that share an output base or a fetched SDK. BREAKING CHANGE: //flutter:remote_cache_trees is a string flag taking none (default), workspaces or all. --//flutter:remote_cache_trees becomes --//flutter:remote_cache_trees=all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The kind split landed with FlutterPrepareDeps still on the default TREE_WORKSPACE, but that action declares its own pub cache tree whenever it is not handed a preassembled one — and for the assemble+pub_package combination that tree is the full multi-GB merge. An action carries a single execution posture for all of its outputs, so `workspaces` would have lifted no-remote-cache off an action uploading a pub cache: precisely the trade the setting was split apart to avoid. prepare_deps_tree_kind now picks the more restrictive kind whenever a pub cache is among the declared outputs, and the call site derives its argument from the outputs list itself rather than re-deriving the branch condition, so the two cannot drift. Also repairs the three remote_cache_trees docstrings, which kept a dangling "and False" from the boolean they used to describe. An analysis test would be the natural home for this, but Starlark's Action object exposes no execution requirements (only args/argv/content/env/inputs/ mnemonic/outputs/substitutions), so the invariant is pinned as a unit test on the pure helper. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Dates the section and adds the compare links. A breaking flag change is a minor bump while the module is pre-1.0. Also records why this one cannot go out through the tag workflow: ccv has no 0.x special case, so the BREAKING CHANGE footer maps straight to IncMajor() and a dispatch would tag v1.0.0 — which the release job's own guard then skips, leaving a major tag with no artifacts behind it. Push v0.3.0 by hand; release.yml triggers on the tag. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Releases
0.3.0: theremote_cache_treessplit fromfeature/reproducible-prepare-deps, one correctness fix found reviewing it, andthe changelog cut.
1.
feat(flutter)!: split remote_cache_trees by tree kind(unchanged work)//flutter:remote_cache_treesbecomes a string flag —none(default),workspaces,all— because the assembled pub cache and the prepared/overlayworkspaces have different economics.
PrepareFlutterAppWorkspacegains theexecution posture every other tree-producing action already had, and the
dependency-preparation log drops its wall-clock timestamp.
Only the commit subject changed: the original was not a Conventional Commit,
so Commitizen would reject it and
ccvwould derive no version from it at all.2.
fix(flutter): classify a prepare action by the trees it declares(new)The split landed with
FlutterPrepareDepsstill on the defaultTREE_WORKSPACE, but that action declares its own pub cache tree wheneverit is not handed a preassembled one:
An action carries one posture for all of its outputs, so
--//flutter:remote_cache_trees=workspaceswould have liftedno-remote-cacheoff an action uploading a pub cache — exactly the trade the flag was split apart
to avoid. Worst case is the assemble +
pub_packagecombination, where thattree is the full merge.
prepare_deps_tree_kindnow takes the more restrictive kind whenever a pubcache is among the declared outputs, and the call site derives its argument from
the
prepare_outputslist itself rather than re-deriving the branch condition,so classification cannot drift from the outputs.
Also repairs the three
remote_cache_treesdocstrings, which kept a danglingand Falsefrom the boolean they used to describe, and documents theper-action rule in
docs/hermeticity.mdand the changelog.An analysis test would be the natural home for the invariant, but Starlark's
Actionexposes no execution requirements —["args", "argv", "content", "env", "inputs", "mnemonic", "outputs", "substitutions"]— so it is pinned as a unittest on the pure helper instead.
3.
chore(release): cut 0.3.0A breaking flag change is a minor bump while the module is pre-1.0.
Tag a Releaseccvhas no 0.x special case —ccv.gomatches^(fix|feat)(\(.+\))?!: |BREAKING CHANGE:straight toIncMajor(). A dispatchover this branch would tag v1.0.0, and
tag.yaml's ownnew-tag-version-type != 'major'guard would then skip the release job,leaving a major tag with no artifacts behind it.
After merge, push the tag by hand —
release.ymltriggers onv*.*.*:A comment in
tag.yamlnow records this so the next person does not find outthe hard way.
Checklist
bazel test //flutter/tests:all_tests //docs:update_testspasses — 16/16cd e2e/smoke && bazel test //:integration_testspasses — 21/21bazel run //docs:updateif any rule/macro API changed — no public APIchange;
//docs:update_testsconfirms the goldens are currentpre-commit run --all-files(buildifier + prettier) is cleandocs/hermeticity.md+CHANGELOG.md🤖 Generated with Claude Code