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.
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 master2026-08-20 14:22:29 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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,python3andpy3-yaml, the Dockerfile did not, and rebuilding from the Dockerfile silently dropped them. Gitea CI then failed atcredentials-coverage: need python3without reaching the tests at all. Nothing in the pipeline objected, because every check asked whether the image built, not what was in it.Asserts
python3with a workingimport yaml, plusgcc,node,bash,make,curl,tarandgit-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:
Assumptions & Decisions
loaded locally. The honest split is: push proves it builds, publish proves it contains.credentials-coverage.sh,validate-admission.shandfeature-lint.shneed python3+yaml;go test -raceneeds cgo hence gcc;forgeprobeneeds git-http-backend.