Skip to content

ci: the BuildKit cache in GitHub's registry, which the KVM fleet can read - #239

Merged
aledbf merged 1 commit into
mainfrom
ci/registry-cache
Nov 12, 2026
Merged

aledbf merged 1 commit into
mainfrom
ci/registry-cache

Conversation

@aledbf

@aledbf aledbf commented Nov 12, 2026

Copy link
Copy Markdown
Member

Hypothesis

compat (KVM fleet) never reads the lanes' BuildKit cache, so it compiles QEMU and the kernel cold on every run, and a cold QEMU build breaks as soon as Alpine's mirror drops what qemu/apk.lock pins. Moving the cache from type=gha to type=registry (ghcr) gives every runner the same cache.

Baseline (measured, 2026-10-24 → 2026-11-12)

n p50 p90 failures
Compat [push main] 9 8m39s 10m50s 4 (every run since 11-09)
Release [dispatch] 5 11m15s 17m40s 3 (two on 11-12, both at compat)
  • Compat's build step: 7m14s, cold every time. In 6 logs: 0 cached QEMU layers, about 4390 ninja steps and about 2345 kernel CCs each.
  • Cause: on the fleet, ACTIONS_CACHE_URL and ACTIONS_RESULTS_URL point to runs-on's proxy (http://10.42.x.x:6871/). importing cache manifest from gha:… DONE 0.0s
  • Failure: unable to select packages in apk add (run 43153951135).
  • Actions cache: 10.36 GB in 142 entries, over the 10 GB limit and evicting entries.

Change

  • Taskfile.yml: CACHE_BACKEND=registry → ghcr.io/spin-stack/spin-machine/cache:{qemu,kernel,e2fsprogs,image} with mode=max,image-manifest=true,oci-mediatypes=true. local stays the developer default.
  • qemu, kernel, image and release: docker login to ghcr in place of crazy-max/ghaction-github-runtime. Main exports (CACHE_EXPORT as before); everything else only reads.
  • compat: login and CACHE_BACKEND=registry.
  • Permissions: packages: write in kernel and image, as qemu already had; packages: read in compat and release (the caller has to hold what compat asks for).

Expected impact

  • compat: from about 8m39s to about 2 min when QEMU and the kernel don't change. This is an estimate, based on the release's warm build of 2-3 min.
  • Release: about 7 min less.
  • Fewer failures from mirror drift, as long as the apk add layer is in the cache.

Risks

  • The first push to main compiles cold once to fill the registry. This PR's own runs are also cold.
  • If the login is missing, BuildKit warns and builds cold without failing. It shows up as no CACHED lines in the log.
  • The cache package is created private and linked to the repo by the first push.

Validation

After merging, count CACHED lines and ninja steps in the logs of the next 5 compat runs on main. Then:

gha_metrics.py --split-at <merge> on Compat [push] and Release

Revert

git revert. The GHA cache will refill on its own.

🤖 Generated with Claude Code

…read

compat compiled QEMU and the kernel cold on every run. runs-on points
ACTIONS_CACHE_URL and ACTIONS_RESULTS_URL at its own cache, so `type=gha` on the
fleet read a store nobody writes: six compat logs read, no cached QEMU layer,
~4390 ninja steps and ~2345 kernel CCs in each. A cold QEMU build reinstalls
qemu/apk.lock from Alpine's live mirror, and once the mirror stopped serving
what it pins compat failed on main four times running (from 2026-11-09), and
both release attempts on 2026-11-12 failed at it.

The Actions cache was also over its 10 GB (10.36 GB, 142 entries, 2026-11-12)
and evicting least recently used.

The caches are now cache:qemu, cache:kernel, cache:e2fsprogs and cache:image
under ghcr.io/spin-stack/spin-machine, written by main's lanes and read by pull
requests, compat and the release with a docker login. The ghaction-github-runtime
step has nothing left to do and goes.

The first push to main compiles cold once, to fill the registry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aledbf
aledbf merged commit 1666cb5 into main Nov 12, 2026
7 checks passed
@aledbf
aledbf deleted the ci/registry-cache branch November 12, 2026 06:01
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