Skip to content

feat(image): give the image a way to put a pinned binary on PATH, and bake actionlint - #281

Merged
rldyourmnd merged 1 commit into
mainfrom
feat/actionlint-path-binary
Aug 29, 2026
Merged

feat(image): give the image a way to put a pinned binary on PATH, and bake actionlint#281
rldyourmnd merged 1 commit into
mainfrom
feat/actionlint-path-binary

Conversation

@rldyourmnd

Copy link
Copy Markdown
Contributor

actionlint is the tool two repositories opened their command with, and their CI did not start for weeks. It could not be added: it is not in the Ubuntu archive, and the only mechanism for a command on a job's PATH was apt. The baked toolchains cannot serve — they land in the runner tool cache, which only the setup-* actions add to PATH, so a plain run: step cannot call them.

guest.path_binaries pins single-binary tools the way the compiler cache already is: archive digest, the entry expected inside it, and the binary's own digest. Provisioning verifies all three before installing to /usr/local/bin — the same sequence sccache goes through a few lines above. Validation requires each pinned binary to appear in guest.provides, so a tool installed but not declared — a tool nobody knows they have, which is half of what this mechanism exists to end — fails the manifest.

actionlint v1.7.12 is pinned. Its archive digest was checked against the checksums the release publishes, not merely computed from whatever arrived.

One guard needed strengthening rather than satisfying. The variant-parity test enumerates Guest fields rather than comparing them, so listing path_binaries there would only say "may differ". They must not differ: a tool on PATH is part of what every worker promises, and a version differing between the standard and integration images would make the same command mean two things depending on where a job landed. It is listed to satisfy the enumeration, and the sameness is asserted properly by a new TestVariantsPinTheSamePathBinaries.

Exercised before being believed. The install loop was run against the real archive: it verifies, extracts, installs, cleans up, and actionlint 1.7.12 runs. A tampered binary digest aborts it with exit 1. make verify green; both fingerprints repinned because the manifest and the build recipe both really changed.

Follows #280, which added guest.provides and the smoke assertion that proves it.

https://claude.ai/code/session_01NpzpgiRaxi5mHVTMoRYndt

… bake actionlint

actionlint is the tool two repositories opened their command with, and their CI
did not start for weeks. It could not be added: it is not in the Ubuntu archive,
and the only mechanism for a command on a job's PATH was apt. The baked
toolchains cannot serve -- they land in the runner tool cache, which only the
setup-* actions add to PATH, so a plain `run:` step cannot call them.

guest.path_binaries pins single-binary tools the way the compiler cache is
already pinned: archive digest, the entry expected inside it, and the binary's
own digest. Provisioning verifies all three before installing to
/usr/local/bin, the same sequence sccache goes through a few lines above.
Validation requires each pinned binary to appear in guest.provides, so a tool
installed but not declared -- a tool nobody knows they have, which is half of
what this mechanism exists to end -- fails the manifest.

actionlint v1.7.12 is pinned. Its archive digest was checked against the
checksums the release publishes, not merely computed from what arrived.

The variant-parity guard enumerates Guest fields rather than comparing them, so
listing path_binaries there would only say "may differ". They must not: a tool
on PATH is part of what every worker promises, and a version differing between
the standard and integration images would make the same command mean two things
depending on where a job landed. It is listed to satisfy the enumeration and
the sameness is asserted properly by TestVariantsPinTheSamePathBinaries.

The install loop was exercised against the real archive before being believed:
it verifies, extracts, installs, cleans up, and actionlint 1.7.12 runs. A
tampered binary digest aborts it with exit 1.

Claude-Session: https://claude.ai/code/session_01NpzpgiRaxi5mHVTMoRYndt
@rldyourmnd
rldyourmnd merged commit a555f28 into main Aug 29, 2026
10 checks passed
@rldyourmnd
rldyourmnd deleted the feat/actionlint-path-binary branch August 29, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant