fix(ci): mirror base images as whole multi-arch indexes (T1 of multi-arch image plan) #16

Merged
jknapp merged 1 commits from fix/mirror-base-image-keep-index into main 2026-11-12 00:46:13 +00:00
Owner

What

The weekly mirror re-published only the amd64 manifest, so cloud-hosting-platform/python:3.12-slim and golang:1.25 had no arm64 variant. The pull/tag/push step is replaced by .gitea/scripts/mirror-index-copy.sh:

  1. docker buildx imagetools create -t <dst>:<tag>-staging docker.io/<img>@<index digest> (registry-to-registry, whole index)
  2. assert staging lists linux/amd64 AND linux/arm64, and its digest equals the Docker-Hub-reported index digest
  3. only then imagetools create -t <dst>:<tag> <dst>@<digest> (registry-side) and re-assert

A failure in 1-2 leaves the real tag untouched (a previously multi-arch tag cannot be downgraded). resolve-base-image.sh verification and regex checks are kept; login step and secrets handling unchanged; setup-buildx added.

Measured

imagetools create round-trips the index digest exactly (python:3.12-slim and golang:1.25 into a local registry: identical sha256). Test .gitea/scripts/test-mirror-index-copy.sh (throwaway local registry): multi-arch passes, single-platform source is rejected, real tag not created, existing multi-arch tag survives a failing refresh, malformed refs refused.

Not verified

The real workflow has NOT run (no dispatch, no push to repo.anhonesthost.net registry). Notes: the copy now brings the full upstream index (7-8 platforms + attestations; several GB for golang on first run, incremental after); a <tag>-staging tag remains in the registry by design.

First real run

Manual workflow_dispatch after merge; check docker buildx imagetools inspect repo.anhonesthost.net/cloud-hosting-platform/python:3.12-slim shows arm64 and digest equals upstream. Roll back: note current digests of the two tags before the run; re-point with imagetools create -t <repo>:<tag> <repo>@<old digest> (old amd64 manifest stays in the registry).

🤖 Generated with Claude Code

https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb

## What The weekly mirror re-published only the amd64 manifest, so `cloud-hosting-platform/python:3.12-slim` and `golang:1.25` had no arm64 variant. The pull/tag/push step is replaced by `.gitea/scripts/mirror-index-copy.sh`: 1. `docker buildx imagetools create -t <dst>:<tag>-staging docker.io/<img>@<index digest>` (registry-to-registry, whole index) 2. assert staging lists linux/amd64 AND linux/arm64, and its digest equals the Docker-Hub-reported index digest 3. only then `imagetools create -t <dst>:<tag> <dst>@<digest>` (registry-side) and re-assert A failure in 1-2 leaves the real tag untouched (a previously multi-arch tag cannot be downgraded). resolve-base-image.sh verification and regex checks are kept; login step and secrets handling unchanged; setup-buildx added. ## Measured `imagetools create` round-trips the index digest exactly (python:3.12-slim and golang:1.25 into a local registry: identical sha256). Test `.gitea/scripts/test-mirror-index-copy.sh` (throwaway local registry): multi-arch passes, single-platform source is rejected, real tag not created, existing multi-arch tag survives a failing refresh, malformed refs refused. ## Not verified The real workflow has NOT run (no dispatch, no push to repo.anhonesthost.net registry). Notes: the copy now brings the full upstream index (7-8 platforms + attestations; several GB for golang on first run, incremental after); a `<tag>-staging` tag remains in the registry by design. ## First real run Manual `workflow_dispatch` after merge; check `docker buildx imagetools inspect repo.anhonesthost.net/cloud-hosting-platform/python:3.12-slim` shows arm64 and digest equals upstream. Roll back: note current digests of the two tags before the run; re-point with `imagetools create -t <repo>:<tag> <repo>@<old digest>` (old amd64 manifest stays in the registry). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
jknapp added 1 commit 2026-11-12 00:40:23 +00:00
mirror-base-image.yaml pulled the upstream index digest on an amd64 runner and
re-pushed it, publishing only the amd64 manifest; the python/golang mirrors
had no arm64 variant. Replace pull/tag/push with a registry-to-registry
`imagetools create` of the digest-pinned index via .gitea/scripts/
mirror-index-copy.sh: copy to <tag>-staging, assert linux/amd64+linux/arm64
are listed and the index digest equals the Docker Hub digest, then move the
real tag and re-assert. A failed assertion never touches the real tag.
Adds a local-registry test (.gitea/scripts/test-mirror-index-copy.sh).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
jknapp merged commit 74fc9ef183 into main 2026-11-12 00:46:13 +00:00
jknapp deleted branch fix/mirror-base-image-keep-index 2026-11-12 00:46:13 +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: cloud-hosting-platform/haproxy-manager-base#16