fix(ci): the check job installs the tools its image does not ship #147
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:bootstrap
scope:coolify
scope:db
scope:docs
scope:drill
scope:installer
scope:labels
scope:platform
scope:runner
scope:users
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/rig#147
Loading…
Reference in a new issue
No description provided.
Delete branch "build/144-ubuntu-latest-tooling"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #144. Implements the ruling @andres gave in 4398: option B —
ubuntu-latestkeeps meaning the slim act image, and rig's own workflow equips itself with what that image does not ship.Why B, in one table
Measured 2026-08-01 by streaming ghcr layer blobs through
gzip -dc | tar -trather than pulling, so these are the images' own numbers:shellcheckact-22.04— the defaultrunner-22.04full-22.04/usr/bin/shellcheck, 0.8.0)The panel started 3/3 on mapping
ubuntu-latesttofull-22.04and reversed on the extracted figure: a box-class ci tenant has ~34–40 GB free, so that mapping is not expensive parity, it is a default that cannot land.apt-get install -y shellcheckcosts 7 s and yields the same ShellCheck 0.8.0 the parity image carries, so parity buys no newer tool either.What is in the change
.github/workflows/ci.yml—checkinstallsshellcheckonly when absent. Thecommand -vshort-circuit means GitHub pays nothing; thesudois a no-op on the act path (jobs run as uid 0 there, and that image has norunneraccount) and load-bearing on GitHub's. The comment says exactly that, so nobody deletes it as dead weight. The check contract —globstar, thecommcoverage guard,shellcheck -x— is untouched.DEFAULT_LABELS— the measurement table above now lives beside it, with the rule it implies: on this forge a workflow must not assume tools from the image.ubuntu-latest-fullships in the default map. A mapping pulls nothing until a job matches it, so it costs a box that never asks exactly nothing — and it has to ship now, because Forgejo freezes labels at registration and a label absent then cannot be added without re-registering.test/cli.sh— 16 new checks;changelog.d/144.md.One deliberate deviation from the agreed terms
The thread agreed the warning should fire when
.rig-labels≠ the current default. Implemented literally, that warns on every converge of any runner the operator deliberately gave--labels— which is precisely why the original code only spoke whenLABELS_EXPLICIT. Nothing on disk distinguishes "registered under an older rig" from "the operator chose this map" except the string itself.So the warning matches against
SUPERSEDED_DEFAULTS— the exact maps rig has ever shipped as its default, appended to and never edited. Drift is recognised; an operator's own map stays silent forever. The message also says plainly that nothing is broken: under this ruling a runner on the old map still runs jobs, and still runs them green. Re-registering buys the new labels, nothing else.A second defect this uncovered — and why it is fixed here
With the shellcheck cause fixed,
checkwas still red, on two checks that had never run on this forge:Both prove a good
--versiongot through validation by asserting the next gate down,must run as root— a gate that only exists for a non-root caller. forgejo-runner runs job containers as uid 0, where GitHub's runner is the unprivilegedrunneruser, so rig reaches the token prompt instead. #136's class, in a place its sweep did not reach.Verified pre-existing: unmodified
mainfails the same two checks in the same image. They are fixed here rather than filed away because #144's acceptance criterion is a greencheck, which is unreachable while they fail. Both gates are equally good evidence that validation is behind us, so either is accepted — andexit 1is still required, so a validation refusal (exit 2) still fails the check, proven by driving a bad pin.Evidence
The whole
checkjob, run insideghcr.io/catthehacker/ubuntu:act-22.04as uid 0 — the exact image and user a real Forgejo job gets — on this branch at0daa2d0:And on the host, where the non-root blocks also run:
cli 817/0,release 51/0,drill 84/0,install-lifecycle 25/0,shellcheck -xclean over 34 files.Must-fail, both halves:
ci.ymlstep andcheckreturns toshellcheck: command not found, exitcode 127 — the original defect.Not in this PR
ubuntu-latest-full(which needs a host bigger than this box class) and the non-root edge logged in 4396.test/cli.shruns 765 checks as root against 817 as a normal user: 52 assertions sit behindif [ "$(id -u)" -ne 0 ]and are silently skipped on this forge, not failed. Every one is a "refuses non-root" guard —bootstrap,coolify,db,users,tenant,runner. So CI on Forgejo is materially weaker than on GitHub and says nothing about it. Sibling of #136, out of scope here.@andres — yours to review and merge; I will not merge or close anything.
Closing this as the duplicate per @andres’s explicit tie-break instruction on #144. !146 survives: it was the first claimed build, now includes the same retired-default matcher, has the narrower patch, and is green on the relevant checks. No merge is being performed; useful review findings from this branch are already incorporated into !146.
Pull request closed