Task T6 of the WHP multi-arch image plan (docs/arm64/IMAGE-PIPELINE-PLAN.md 2.2 #5/#6, 4.1, 4.4). Does NOT change the build matrix platforms:.
What
scripts/image-label-amd64.sh: index-safe label read of the linux/amd64 image (raw index -> amd64 child digest, attestation children ignored -> inspect child). Works for OCI index, Docker manifest list, single manifest. Exit 0 ok / 3 tag not found / 1 anything else.
scripts/php-emergency-guard.sh: used by BOTH guard sites in build-push.yaml. Same decisions as the old inline step on single-platform images (54-combination test vs the verbatim old predicate), but FAILS CLOSED when labels cannot be read (registry/auth/network error, malformed manifest, no/ambiguous amd64 child, non-amd64 config). Only "tag not found" (first build) and labels-absent proceed.
lsphp-source-emergency.yaml: push by digest + assemble with scripts/assemble-multiarch-index.sh (verbatim copy of haproxy-manager-base PR #17, with a bash test; copied because CI cannot fetch across repos). New inputs build_arm64 (default false, QEMU, continue-on-error) and allow_amd64_only (default false). Immutable :phpNN-phpnet-X.Y.Z is always created; the production tags are REFUSED if the current tag is a multi-arch index with arm64 and arm64 was not built successfully, unless allow_amd64_only=true. A stale arm64 is never reattached.
scripts/index-platforms.sh + tests; all wired into Shell-Checks.
Verified
Unit tests (fixtures: two-platform index + attestations, manifest list, single manifest, malformed). Real local registry:2 with buildx-built indexes (buildx 0.38.2 and 0.15.1): the OLD inline format errors on a real index ("index of untyped nil", swallowed -> guard off); new script reads the labels. Not verified: runs on the Gitea runner, real Gitea "not found" wording (matches not found|manifest unknown|name unknown|404), emergency workflow end-to-end (not dispatched), arm64 php.net source build.
Merge
Merging to trunk triggers build-push.yaml (full publish). Merge with [skip ci] in the merge title.
Task T6 of the WHP multi-arch image plan (docs/arm64/IMAGE-PIPELINE-PLAN.md 2.2 #5/#6, 4.1, 4.4). Does NOT change the build matrix `platforms:`.
## What
- `scripts/image-label-amd64.sh`: index-safe label read of the linux/amd64 image (raw index -> amd64 child digest, attestation children ignored -> inspect child). Works for OCI index, Docker manifest list, single manifest. Exit 0 ok / 3 tag not found / 1 anything else.
- `scripts/php-emergency-guard.sh`: used by BOTH guard sites in build-push.yaml. Same decisions as the old inline step on single-platform images (54-combination test vs the verbatim old predicate), but FAILS CLOSED when labels cannot be read (registry/auth/network error, malformed manifest, no/ambiguous amd64 child, non-amd64 config). Only "tag not found" (first build) and labels-absent proceed.
- `lsphp-source-emergency.yaml`: push by digest + assemble with `scripts/assemble-multiarch-index.sh` (verbatim copy of haproxy-manager-base PR #17, with a bash test; copied because CI cannot fetch across repos). New inputs `build_arm64` (default false, QEMU, continue-on-error) and `allow_amd64_only` (default false). Immutable `:phpNN-phpnet-X.Y.Z` is always created; the production tags are REFUSED if the current tag is a multi-arch index with arm64 and arm64 was not built successfully, unless `allow_amd64_only=true`. A stale arm64 is never reattached.
- `scripts/index-platforms.sh` + tests; all wired into Shell-Checks.
## Verified
Unit tests (fixtures: two-platform index + attestations, manifest list, single manifest, malformed). Real local registry:2 with buildx-built indexes (buildx 0.38.2 and 0.15.1): the OLD inline format errors on a real index ("index of untyped nil", swallowed -> guard off); new script reads the labels. Not verified: runs on the Gitea runner, real Gitea "not found" wording (matches `not found|manifest unknown|name unknown|404`), emergency workflow end-to-end (not dispatched), arm64 php.net source build.
## Merge
Merging to trunk triggers build-push.yaml (full publish). Merge with `[skip ci]` in the merge title.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
- scripts/image-label-amd64.sh: index-safe read of the amd64 image's labels
(OCI index with attestations, Docker manifest list, single manifest).
- scripts/php-emergency-guard.sh: used by both build-push.yaml guard sites;
same decisions as the old inline step on single-platform images, but FAILS
CLOSED when the labels cannot be read (only "tag not found" passes).
- lsphp-source-emergency.yaml: push by digest + assemble (copy of HMB
assemble-multiarch-index.sh); optional arm64; refuses to replace a
multi-arch production tag with amd64-only unless allow_amd64_only.
- Tests wired into Shell-Checks; main build matrix platforms unchanged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
jknapp
merged commit adf74e2f69 into trunk2026-11-12 01:55:43 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Task T6 of the WHP multi-arch image plan (docs/arm64/IMAGE-PIPELINE-PLAN.md 2.2 #5/#6, 4.1, 4.4). Does NOT change the build matrix
platforms:.What
scripts/image-label-amd64.sh: index-safe label read of the linux/amd64 image (raw index -> amd64 child digest, attestation children ignored -> inspect child). Works for OCI index, Docker manifest list, single manifest. Exit 0 ok / 3 tag not found / 1 anything else.scripts/php-emergency-guard.sh: used by BOTH guard sites in build-push.yaml. Same decisions as the old inline step on single-platform images (54-combination test vs the verbatim old predicate), but FAILS CLOSED when labels cannot be read (registry/auth/network error, malformed manifest, no/ambiguous amd64 child, non-amd64 config). Only "tag not found" (first build) and labels-absent proceed.lsphp-source-emergency.yaml: push by digest + assemble withscripts/assemble-multiarch-index.sh(verbatim copy of haproxy-manager-base PR #17, with a bash test; copied because CI cannot fetch across repos). New inputsbuild_arm64(default false, QEMU, continue-on-error) andallow_amd64_only(default false). Immutable:phpNN-phpnet-X.Y.Zis always created; the production tags are REFUSED if the current tag is a multi-arch index with arm64 and arm64 was not built successfully, unlessallow_amd64_only=true. A stale arm64 is never reattached.scripts/index-platforms.sh+ tests; all wired into Shell-Checks.Verified
Unit tests (fixtures: two-platform index + attestations, manifest list, single manifest, malformed). Real local registry:2 with buildx-built indexes (buildx 0.38.2 and 0.15.1): the OLD inline format errors on a real index ("index of untyped nil", swallowed -> guard off); new script reads the labels. Not verified: runs on the Gitea runner, real Gitea "not found" wording (matches
not found|manifest unknown|name unknown|404), emergency workflow end-to-end (not dispatched), arm64 php.net source build.Merge
Merging to trunk triggers build-push.yaml (full publish). Merge with
[skip ci]in the merge title.🤖 Generated with Claude Code
https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb