From c9db77766466bb6ed38e5e5db2133663b5ccdbc1 Mon Sep 17 00:00:00 2001 From: Michael Pretorius Date: Sat, 25 Jul 2026 09:34:05 +0400 Subject: [PATCH] feat(node-ci-build): optional multi-arch docker builds via new platforms input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an optional `platforms` input (e.g. "linux/amd64,linux/arm64") to the node build/publish workflow. When set, QEMU + buildx are configured and the platform list is passed to docker/build-push-action; when empty (default) the behavior is exactly as before — single-arch on the runner architecture, plain docker driver, no extra setup steps. Motivation: images meant for local/e2e use (first consumer: the subscriptions-api worker image for ixo-testing-harness) run workerd/V8, which is unreliable under Rosetta emulation on Apple Silicon — a native arm64 variant sidesteps that entirely. Authored by: Michael Pretorius --- .github/workflows/node-ci-build.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/node-ci-build.yml b/.github/workflows/node-ci-build.yml index 0d1bb37..159156c 100644 --- a/.github/workflows/node-ci-build.yml +++ b/.github/workflows/node-ci-build.yml @@ -27,6 +27,11 @@ on: type: string description: 'For builds in sub-directories, provide the path. Leave empty for repo root.' default: '' + platforms: + required: false + type: string + default: '' + description: 'Comma-separated docker target platforms for a multi-arch image, e.g. "linux/amd64,linux/arm64". Empty (default) keeps the current single-arch build on the runner architecture. Use for images that must also run natively on arm64 hosts (e.g. dev/e2e images pulled on Apple Silicon, where emulating JIT-heavy runtimes like workerd/V8 under Rosetta is unreliable).' permissions: contents: write @@ -180,6 +185,16 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GHCR_TOKEN || secrets.GITHUB_TOKEN }} + # Cross-arch emulation + buildx are only needed for multi-arch builds; + # the default single-arch path stays on the plain docker driver. + - name: Set up QEMU + if: ${{ inputs.platforms != '' }} + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + if: ${{ inputs.platforms != '' }} + uses: docker/setup-buildx-action@v3 + - name: Build and push Docker image uses: docker/build-push-action@v5 with: @@ -187,6 +202,8 @@ jobs: file: ${{ inputs.root_path && format('{0}/Dockerfile', inputs.root_path) || './Dockerfile' }} push: true tags: ghcr.io/${{ env.IMAGE_NAME }} + # empty string = input omitted (single-arch, unchanged behavior) + platforms: ${{ inputs.platforms }} security-scan: name: 'Docker Security Scan'