Skip to content

ci: fix the multi-arch manifest check, which failed a correct manifest - #559

Merged
ohohoreilly merged 1 commit into
masterfrom
ohohoreilly/552-manifest-verify-regex
Sep 17, 2026
Merged

ohohoreilly merged 1 commit into
masterfrom
ohohoreilly/552-manifest-verify-regex

Conversation

@ohohoreilly

Copy link
Copy Markdown
Member

Found by running the first real publish. The good news is in #548: ghcr.io/orlyatomics/orly:latest is now a genuine multi-arch manifest. The bad news is that the job whose entire purpose is to prove that reported failure while doing it correctly.

The bug

got=$(docker buildx imagetools inspect --raw ghcr.io/orlyatomics/orly:latest \
        | grep -oE '"architecture":"[a-z0-9]+"' | sort -u | tr '\n' ' ')

imagetools inspect --raw pretty-prints. The actual bytes are:

      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }

"architecture": "amd64" — with a space. The regex requires none, so it matched zero times, got came back empty, and both assertions failed:

manifest advertises:
##[error]Process completed with exit code 1.

Meanwhile the stitch above it had worked perfectly.

Why it shipped

The step only runs on workflow_dispatch or a v* tag. Neither had ever happened — the repo has no v* tags at all — so this ran for the first time on the first publish, which is exactly the run it was supposed to protect. A gate that has never executed is not a gate.

The fix

Parse the index instead of grepping its formatting:

got=$(docker buildx imagetools inspect --raw ghcr.io/orlyatomics/orly:latest \
        | jq -r '.manifests[]?.platform | select(. != null) | "\(.os)/\(.architecture)"' \
        | sort -u)
grep -qx 'linux/amd64' <<<"$got"
grep -qx 'linux/arm64' <<<"$got"

Asserting on os/arch pairs rather than architecture alone also makes the check say what it means — a linux/amd64 + windows/arm64 pair would have satisfied the old one.

Checked both directions against the live registry rather than reasoning about it:

target advertises result
:latest (multi-arch) linux/amd64, linux/arm64 passes
:latest-amd64 (single) nothing — it is a plain manifest, not an index fails

The ? and select(. != null) are what make the second row a clean failure instead of a jq error.

#552)

The verification step matched '"architecture":"[a-z0-9]+"' against the output
of `docker buildx imagetools inspect --raw`. That output is pretty-printed --
the bytes are '"architecture": "amd64"', with a space -- so the regex matched
nothing, `got` came back empty, and the step failed a manifest list that was
correct.

Seen on the first real publish: :latest was stitched properly and advertises
linux/amd64 and linux/arm64, but the job that exists to prove that reported
failure. The step only runs on a dispatch or a version tag, so it had never
executed before and shipped unexercised.

Parse the index with jq instead of grepping its formatting, and assert on
os/arch pairs. Checked both ways against the live registry: it passes the
current multi-arch :latest and fails :latest-amd64.
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