🌱 ci: build and push the toolchain runner image from CI (#7289) - #7315
Conversation
#7206 baked gcc/libc6-dev/tmux into the ARC runner image so race shards stop depending on apt egress from the self-hosted cluster (#6648 → #6870 → #6935 → #7124 → #7201). The Dockerfile merged on 2026-09-16; a day later the image still did not exist on GHCR (GET /orgs/hivecommons/packages/container/ hive-ci-runner → 404) and two more `test (hub 2/3)` shards had died at "Prepare cgo toolchain", because publishing was left to "an operator with docker + GHCR write". That was half of the rollout blocker, and it is the half CI can remove. .github/workflows/ci-runner-image.yml: - workflow_dispatch builds and pushes ghcr.io/<owner>/hive-ci-runner: <runner version>-<tag_suffix> (e.g. v2.337.0-ubuntu-24.04-toolchain-1) with the job's GITHUB_TOKEN (packages: write). The tag derives from the runner_base_image input so it always records which runner release it was built on — the thing the #6648 suite caveat needs an operator to read off the cluster. An existing tag is refused, never overwritten (ARC does not re-pull an unchanged tag). The job summary prints the digest and the exact `kubectl patch`, plus the first-push package-visibility caveat. - pull_request, path-filtered to the Dockerfile and the workflow, builds only: the Dockerfile's own `gcc --version` / `tmux -V` verification becomes the gate that keeps a change from shipping a network-dependent image. - runs-on ubuntu-latest, not HIVE_RUNNER_LABELS: the image exists to remove CI's dependency on the cluster's egress, so it must not be built behind it. - No gha layer cache: the Actions cache is the resource #7206 measured full (9.99/10 GB, 96.6% buildkit blobs), the reason the #7009 .deb cache never survived. - No push trigger and no branches: filter — rolling a new tag restarts every runner, so it stays an operator decision; the release-line guard has nothing to classify. pkg/config tests pin those properties (off-cluster, no gha cache, attestations off, SHA-pinned actions, push only on dispatch) and that the README points at the workflow and warns about the private-by-default package. README now leads with `gh workflow run`, keeps the laptop build as fallback, and marks the `kubectl patch` as the one step that still needs vllm-d access. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Douglas Baggett <doug.baggett@gmail.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
clubanderson
left a comment
There was a problem hiding this comment.
CI-built runner image off-cluster with immutable tags and a build-only PR gate — this closes the gap that left the cgo-toolchain shards flaking since #7206. LGTM.
|
LGTM label has been added. DetailsGit tree hash: 7754da08612265d6a53a93c80c31bcd1b3c3829d |
|
Thank you for your contribution! Your PR has been merged. We'd love to hear how your experience was: share feedback |
|
Dispatched the workflow after merge — run 35215122771 built and pushed |
Refs #7289
Summary
#7206 wrote the Dockerfile that bakes
gcc/libc6-dev/tmuxinto the self-hosted runner image so race shards stop failing at Prepare cgo toolchain when the cluster's apt egress drops. It merged on 2026-09-16 — and a day later the image still did not exist on GHCR and two moretest (hub 2/3)shards had died the same way, because publishing the image was left to "an operator withdockerand GHCR write access".This PR removes that half of the rollout blocker: a CI Runner Image workflow builds the Dockerfile on a GitHub-hosted runner and pushes it to
ghcr.io/hivecommons/hive-ci-runnerwith the job's ownGITHUB_TOKEN. The only step left for an operator is the one CI genuinely cannot do —kubectl patchthe RunnerDeployment inarc-systemsto the tag the run prints — and the job summary hands them that command with the digest filled in.How it works
workflow_dispatchbuilds and pushes. Inputs:runner_base_image(default matches the live runners) andtag_suffix. The pushed tag is<runner version>-<suffix>, e.g.v2.337.0-ubuntu-24.04-toolchain-1, so the tag always records which runner release it was built on (what the [ci] self-hosted runners lost egress to archive.ubuntu.com — every -race shard fails at 'Prepare cgo toolchain' since ~07:00Z 2026-09-11 #6648 suite caveat needs an operator to read off the cluster). An existing tag is refused, never overwritten — ARC does not re-pull an unchanged tag.pull_request, path-filtered to the Dockerfile and the workflow, builds only. The Dockerfile's owngcc --version/tmux -Vverification becomes the gate that keeps a Dockerfile change from shipping an image that quietly sends CI back to the mirrors.runs-on: ubuntu-latest, notHIVE_RUNNER_LABELS— the image exists to remove CI's dependency on the cluster's egress, so building it behind that egress would defeat it.type=ghalayer cache — the Actions cache is the resource 🌱 [ci] bake gcc/libc6-dev into the ARC runner image — root fix for the recurring apt-egress failure class #7206 measured full (9.99/10 GB, 96.6% buildkit blobs), the reason the 🐛 cache cgo apt packages for race tests #7009 offline.debcache never survived.push:trigger / nobranches:filter — rolling a new tag restarts every runner pod, so when stays an operator decision; the release-line guard has nothing to classify (verified withcheck-release-lines.sh,check-action-pins.sh).provenance: false,sbom: false) so the pushed tag is a plain image manifest, per the stable/candidate/edge images: hive binary fails exec with EPERM from /usr/local/bin/hive (works when copied elsewhere) #3760 contract.Also
src/deploy/ci-runners/README.mdnow leads withgh workflow run ci-runner-image.yml --ref v4 …, keeps the laptopdocker buildas a fallback, marks thekubectl patchas the step that still needsvllm-daccess, and adds the first-push caveat: GHCR creates the package private and ARC pulls anonymously, sohive-ci-runnermust be made public (likehive/hive-hub/hive-contributor) before patching or the pods land inImagePullBackOff.pkg/config/ci_runner_image_workflow_test.gopins the properties above (off-cluster, no gha cache, attestations off, SHA-pinned actions, push only on dispatch, README documents the workflow and the visibility caveat).changelog.d/changed-7289-ci-runner-image-workflow.md.Testing
go test ./pkg/config/ -run CIRunner— all pass (existing Dockerfile guards + 6 new).src/scripts/check-release-lines.sh,check-action-pins.sh,check-no-image-attestations.sh— PASS.pull_requestlane of the new workflow should run on this PR itself (it touches the workflow file), which is the first real build of the Dockerfile.After merge
gh workflow run ci-runner-image.yml --ref v4 -f tag_suffix=toolchain-1then follow the run's job summary for the
kubectl patch. Close #7289 on the first green race shard whose Prepare cgo toolchain step reports the tool already present.— hive: backend=claude model=claude-opus-5
🤖 Generated with Claude Code