ci: assert the published image still contains the toolchain the gates need #5

Merged
markus merged 1 commits from claude/ci/assert-image-contents into master 2026-08-20 14:22:29 +00:00
Member

Depends-on: #4

This image is a toolchain, so "it built" is not the property worth checking — "it still contains what the repo's gates shell out to" is.

It exists because the hand-built image had drifted from the Dockerfile: the deployed ci3 carried gcc, musl-dev, python3 and py3-yaml, the Dockerfile did not, and rebuilding from the Dockerfile silently dropped them. Gitea CI then failed at credentials-coverage: need python3 without reaching the tests at all. Nothing in the pipeline objected, because every check asked whether the image built, not what was in it.

Asserts python3 with a working import yaml, plus gcc, node, bash, make, curl, tar and git-http-backend — on both architectures, since a package resolving on amd64 but not arm64 would otherwise reach half the nodes unnoticed.

Verified the check can actually FAIL, which is the only thing that makes it worth having:

bare forgejo/runner:12.11.1   → python3+yaml=MISSING gcc=MISSING node=MISSING git-http-backend=MISSING
with packages installed       → python3+yaml=3.12.14 gcc=ok node=ok git-http-backend=ok

Assumptions & Decisions

  • Draft until #4 merges: this asserts the packages #4 restores, so merging it first would correctly fail the next build.
  • Runs only on the publish path, not the master-push validation. The validation path does not push, so there is no image to run; multi-platform builds cannot be loaded locally. The honest split is: push proves it builds, publish proves it contains.
  • The tool list is what the repo's gates actually invoke, not a wish list — credentials-coverage.sh, validate-admission.sh and feature-lint.sh need python3+yaml; go test -race needs cgo hence gcc; forgeprobe needs git-http-backend.
  • If this ever fails, restore the package in the Dockerfile. Do not weaken the check — that is how the drift became invisible in the first place.
Depends-on: #4 This image is a **toolchain**, so "it built" is not the property worth checking — "it still contains what the repo's gates shell out to" is. It exists because the hand-built image had drifted from the Dockerfile: the deployed ci3 carried `gcc`, `musl-dev`, `python3` and `py3-yaml`, the Dockerfile did not, and rebuilding from the Dockerfile silently dropped them. Gitea CI then failed at `credentials-coverage: need python3` without reaching the tests at all. **Nothing in the pipeline objected, because every check asked whether the image built, not what was in it.** Asserts `python3` with a working `import yaml`, plus `gcc`, `node`, `bash`, `make`, `curl`, `tar` and `git-http-backend` — on **both** architectures, since a package resolving on amd64 but not arm64 would otherwise reach half the nodes unnoticed. **Verified the check can actually FAIL**, which is the only thing that makes it worth having: ``` bare forgejo/runner:12.11.1 → python3+yaml=MISSING gcc=MISSING node=MISSING git-http-backend=MISSING with packages installed → python3+yaml=3.12.14 gcc=ok node=ok git-http-backend=ok ``` ## Assumptions & Decisions - Draft until #4 merges: this asserts the packages #4 restores, so merging it first would correctly fail the next build. - Runs only on the publish path, not the master-push validation. The validation path does not push, so there is no image to run; multi-platform builds cannot be `load`ed locally. The honest split is: push proves it builds, publish proves it contains. - The tool list is what the repo's gates actually invoke, not a wish list — `credentials-coverage.sh`, `validate-admission.sh` and `feature-lint.sh` need python3+yaml; `go test -race` needs cgo hence gcc; `forgeprobe` needs git-http-backend. - If this ever fails, restore the package in the Dockerfile. Do not weaken the check — that is how the drift became invisible in the first place.
agent added 1 commit 2026-08-20 14:03:13 +00:00
This image is a TOOLCHAIN, so "it built" is not the property worth checking —
"it still contains what the repo's gates shell out to" is.

It exists because the hand-built image had drifted from this Dockerfile: the
deployed ci3 carried gcc, musl-dev, python3 and py3-yaml, the Dockerfile did
not, and rebuilding from the Dockerfile silently dropped them. Gitea CI then
failed at "credentials-coverage: need python3" without reaching the tests at
all. Nothing in the pipeline objected, because every check asked whether the
image built, not what was in it.

Asserts python3 with a working yaml import, gcc, node, bash, make, curl, tar
and git-http-backend, on BOTH architectures — a package that resolves on amd64
but not arm64 would otherwise reach half the nodes unnoticed.

Verified the check can actually FAIL, which is the only property that makes it
worth having: against the bare forgejo/runner:12.11.1 it reports python3+yaml,
gcc, node and git-http-backend all MISSING; with the packages installed it
reports 3.12.14 and ok for the rest.
agent marked the pull request as ready for review 2026-08-20 14:14:54 +00:00
markus merged commit bf26dc4e15 into master 2026-08-20 14:22:29 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: zegit-zoo/zegit-forgejo-runner#5