Repository navigation
feat(ci): fail when a duplocloud image tag is not published multi-arch - #22
Merged
Merged
Conversation
Every devkit release is now expected to publish both linux/amd64 and linux/arm64 — the studio platform pin was dropped on that premise (scripts/_runtime.sh, runtime_rosetta_check). Nothing currently enforces it: bump a tag to an amd64-only build and the kit silently falls back to emulation on Apple Silicon, because the retained Rosetta check only fires on an EXPLICIT amd64 pin and cannot see an unset platform resolving to the wrong image. scripts/check-image-arches.sh queries the registry API directly for each configured duplocloud image (no docker/podman pull, no runtime, no credentials needed for a public quay repo) and fails if either required architecture is missing. Scoped to quay.io/duplocloud/* only, per @aboutte: these are images DuploCloud itself builds and has committed to publishing multi-arch, so a failure here is a mistake to fix, not a legitimate choice to accommodate — unlike the Rosetta check, which has to allow for a user's own private registry. Third-party images (mongo, qdrant, busybox) are out of scope for the same reason the design doc gives: stable, already multi-arch, and Docker Hub needs an auth dance this does not. .github/workflows/image-arch-check.yml runs it on pull_request, gated on .env.example and docker-compose.yml having changed (the only two files that can move a pinned tag), plus workflow_dispatch for a manual run with no PR required. Per @aboutte's reply, this fails the build; making it a required check in branch protection is a separate repo-settings change on his side — dev currently has no branch protection at all, so until that setting changes, a failure here is visible but not blocking. Tests: 19, all pure — manifest parsing, the architecture comparison, and the skip-decisions (unset, `latest`, a digest pin) are exercised with canned fixtures, no network. The two risk points are mutation-tested: removing the attestation-manifest filter (quay's backend image carries two `unknown/unknown` entries alongside its real platforms) and loosening the digest-pin skip detection each make a specific test fail. Verified against live quay, not only fixtures: a real run against the four tags on dev passes; a real amd64-only manifest — the `backend` image's own per-platform digest, queried on its own outside the multi-arch index — is correctly detected and fails. NOTE: GitHub only runs a pull_request-triggered workflow if it already exists on the base branch, so this workflow will not appear as a check on the PR that introduces it. It activates once merged to dev. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Per the Multi-Arch Image Guard proposal and @aboutte's reply: "check duplo images (quay)", "yes block PR merging."
What this does
Fails CI when a duplocloud image tag configured in this repo does not publish both
linux/amd64andlinux/arm64.Every devkit release is now expected to publish multi-arch — the studio platform pin was dropped on that premise (
scripts/_runtime.sh,runtime_rosetta_check). Nothing currently enforces it: bump a tag to an amd64-only build and the kit silently falls back to emulation on Apple Silicon, because the retained Rosetta check only fires on an explicit amd64 pin and cannot see an unset platform resolving to the wrong image.Scope
quay.io/duplocloud/*only, per @aboutte's decision. These are images DuploCloud itself builds and has committed to publishing multi-arch, so a failing tag here is a mistake to fix, not a legitimate choice to accommodate — unlike the Rosetta check, which has to allow for a user's own private registry. Third-party images (mongo,qdrant,busybox) stay out: stable, already multi-arch, and Docker Hub needs an auth dance this doesn't.BUILDER_TAGis also excluded — it defaults tolatest, a moving target that proves nothing about tomorrow's pull.How it checks
Queries the registry API directly for each configured image (
STUDIO_TAG,AGENT_TAG,UI_TAG,XTERM_TAG). No docker/podman pull, no runtime, no credentials needed — quay's duplocloud images are public, so this runs the same on a fork PR as it does here.Filters out attestation manifests (quay's
backendimage carries twoos/architecture: unknownentries alongside its real platforms) — naive parsing would count those and pass anything.Testing
19 unit tests, all pure — canned JSON fixtures, no network. Two mutation-tested: removing the attestation filter, and loosening the digest-pin skip detection, each make a specific test fail.
Also verified against live quay, not only fixtures:
devpasses.backendimage's own per-platform digest, queried outside the multi-arch index — is correctly detected and fails.main(which was 2 commits behindorigin/mainand unused), dispatched, confirmedsuccesswith the expected output, then restored to its exact prior commit. Run.Note for reviewers
GitHub only runs a
pull_request-triggered workflow if it already exists on the base branch, so this will not appear as a check on this PR. It activates once merged todev— the live-run link above is the closest available proof before then.This fails the build but does not yet block merging:
devcurrently has no branch protection rules at all. Making this (and arguablyextension-ci.yml'sbuildjob) a required check is a separate repo-settings change, which @aboutte said he'd make once this exists.🤖 Generated with Claude Code