Skip to content

Commit e7781e0

Browse files
authored
fix(rest): set TARGETARCH per matrix leg so arm64 images are arm64 (+ arch guard on PRs) (#2870)
## Context Follow-up to #2841, which switched the REST images to native per-arch builds + manifest merge. That landed the structure, but the first `main` build still failed: **all 9 arm64 legs produced amd64 binaries** and the arch guard (correctly) failed the build. ## Root cause The Dockerfile builder is `FROM --platform=$BUILDPLATFORM` and cross-compiles via `ENV GOARCH=$TARGETARCH`, where `ARG TARGETARCH=amd64` (default). On a **native single-platform build**, BuildKit does **not** inject the automatic `TARGETARCH`, so it stays at the `amd64` default → `GOARCH=amd64` → the arm64 leg cross-compiles to **amd64 even on an arm64 runner**. Proof from the failed main build (nico-rest-api arm64 leg): the runner is arm64 (`Platforms: linux/arm64,…`), `go build -o /app/api` ran fresh (`#30 DONE 66.6s`, not cached), yet the binary is `x86-64`. amd64 legs passed only because `amd64` happens to be the default. ## Why the PR for #2841 didn't catch it The guard (extract + `file` check) was gated `if: inputs.push_enabled == true`; PR builds have `push_enabled=false`, so the guard was **skipped on PRs** and only ran on `main`. The PR therefore built (broken) arm64 images but never verified them. ## Fix 1. **Set `TARGETARCH` explicitly per matrix leg** via `build-args` (`TARGETOS=linux`, `TARGETARCH=${{ matrix.arch }}`) so `GOARCH` is correct regardless of BuildKit's auto-arg behavior on native builds. 2. **Run the arch guard on PRs too** (drop the `push_enabled` gate on the extract+verify step; the build already `load`s the image). PRs now catch an arch mismatch before merge — not only on `main`. Push/upload steps stay push-only. ## Verify This PR's build legs extract and `file`-check both arch binaries (amd64 → x86-64, arm64 → aarch64) on the PR itself; merge/push remain main-only.
1 parent 9304997 commit e7781e0

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

.github/workflows/rest-build-push-service.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ jobs:
140140
platforms: ${{ matrix.platform }}
141141
push: false
142142
load: true
143+
# The Dockerfile builder is FROM --platform=$BUILDPLATFORM and cross-compiles via
144+
# GOARCH=$TARGETARCH. On a NATIVE single-platform build BuildKit does not inject the
145+
# automatic TARGETARCH, so it falls back to the Dockerfile default (amd64) and the
146+
# arm64 leg cross-compiles to amd64 even on an arm64 runner. Set it explicitly.
147+
build-args: |
148+
TARGETOS=linux
149+
TARGETARCH=${{ matrix.arch }}
143150
tags: ${{ steps.docker-tags.outputs.arch_tag }}
144151
cache-from: type=gha,scope=${{ inputs.service_name }}-${{ matrix.arch }}
145152
cache-to: type=gha,mode=max,scope=${{ inputs.service_name }}-${{ matrix.arch }}
@@ -166,7 +173,8 @@ jobs:
166173
sbom-artifact-name: sbom-${{ inputs.service_name }}-${{ github.run_id }}-${{ github.run_attempt }}
167174

168175
- name: Extract ${{ matrix.arch }} binary and verify architecture
169-
if: inputs.push_enabled == true
176+
# No push_enabled gate: the build step loads the image, so this guard also runs on PRs
177+
# and catches an arch mismatch before merge — not only on main.
170178
run: |
171179
set -euo pipefail
172180
mkdir -p artifacts

0 commit comments

Comments
 (0)