ci(docker): build multi-arch images (amd64 + arm64) (#3392)
Some checks failed
Lint / ShellCheck (push) Has been cancelled
Lint / Biome Lint (push) Has been cancelled
Lint / macOS Compatibility (push) Has been cancelled

* ci(docker): build multi-arch images (amd64 + arm64)

The agent images at ghcr.io/openrouterteam/spawn-<agent>:latest were built
linux/amd64 only. On Apple Silicon (arm64) hosts running --beta sandbox,
OrbStack pulls the amd64 image and runs it under Rosetta. Inside the
container, github-auth.sh's `apt-get update` to install gh hangs in
emulation — confirmed by `[rosetta] /usr/lib/apt/methods/http` processes
sleeping forever. A native arm64 ubuntu:24.04 finishes the same apt-get
update + curl install in ~12s; the amd64-emulated run was still stuck
after 5+ minutes.

Adds docker/setup-qemu-action + docker/setup-buildx-action and sets
platforms: linux/amd64,linux/arm64 on the build-push step. Builds will
take longer (arm64 layer compiles under QEMU on the amd64 runner), but
the resulting multi-arch manifest gives Apple Silicon users native arm64
binaries and unblocks the sandbox flow.

All current Dockerfiles (claude, codex, cursor, hermes, junie, kilocode,
openclaw, opencode, pi) install via npm or arch-aware curl scripts, so
they're already arch-portable.

* ci(docker): verify the pushed manifest contains both architectures

Post-build step runs `docker buildx imagetools inspect` and greps the
manifest for both linux/amd64 and linux/arm64. Catches regressions
where setup-qemu/buildx gets dropped or the `platforms:` flag gets
lost in a future refactor — silent single-arch publishes would be
invisible until an Apple Silicon user hit the Rosetta hang again.

One post-build step per matrix entry keeps the check local to the
agent that was just pushed.

---------

Co-authored-by: Claude <claude@anthropic.com>
This commit is contained in:
Ahmed Abushagur 2026-05-05 00:27:08 -07:00 committed by GitHub
parent 53c7ead179
commit 3ae6554c21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,6 +24,10 @@ jobs:
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
@ -34,5 +38,23 @@ jobs:
with:
context: .
file: sh/docker/${{ matrix.agent }}.Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/openrouterteam/spawn-${{ matrix.agent }}:latest
# Verify the pushed manifest actually contains both architectures.
# Catches regressions where setup-qemu/buildx gets dropped or the
# platforms flag gets lost in a future refactor.
- name: Verify multi-arch manifest
run: |
set -euo pipefail
image="ghcr.io/openrouterteam/spawn-${{ matrix.agent }}:latest"
echo "Inspecting $image"
manifest="$(docker buildx imagetools inspect "$image")"
echo "$manifest"
for arch in linux/amd64 linux/arm64; do
if ! grep -qF "$arch" <<< "$manifest"; then
echo "::error::$image is missing $arch in the published manifest"
exit 1
fi
done