From 4798ccf6c3e5648f36a95db6eabfe7bd5b887dc4 Mon Sep 17 00:00:00 2001 From: Shan Valleru Date: Wed, 16 Sep 2026 13:02:39 -0700 Subject: [PATCH 1/2] ci(publish): build the image for arm64 too E2B Embed pins this image and runs on arm64 hosts. The push path builds a linux/amd64,linux/arm64 manifest list with QEMU for the arm64 half; the dry run keeps a single platform because --load can only hold one. --- .github/workflows/publish.yml | 15 +++++++++++++-- README.md | 4 ++-- tests/unit/publish-workflow.test.ts | 3 ++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 08031db93..fc87432c7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -46,7 +46,8 @@ jobs: publish: name: Build and push the image runs-on: ubuntu-latest - timeout-minutes: 30 + # The arm64 build runs emulated; allow for it. + timeout-minutes: 90 steps: - name: Check the publishing credentials are configured @@ -151,6 +152,12 @@ jobs: exit 1 fi + # The arm64 half of the manifest list runs its Bun install and Next build + # under emulation; the alternative, cross-building on amd64, would ship + # amd64-only native modules (sharp) inside the standalone output. + - name: Set up QEMU + uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # v4.3.0 + - name: Set up Buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 @@ -162,13 +169,17 @@ jobs: run: | set -euo pipefail output=--push + platforms=linux/amd64,linux/arm64 if [ "${DRY_RUN}" = "true" ]; then + # A dry run loads the image into the local daemon, which can hold + # one platform, so it rehearses the native build only. output=--load + platforms=linux/amd64 fi # Artifact Registry rejects buildx's default provenance/SBOM # attestation manifest lists with HTTP 400. docker buildx build \ - --platform linux/amd64 \ + --platform "${platforms}" \ --provenance=false \ --sbom=false \ --build-arg "BUILD=${TAG}" \ diff --git a/README.md b/README.md index d9ab944df..3235a68ae 100644 --- a/README.md +++ b/README.md @@ -175,8 +175,8 @@ merging the open release PR updates `CHANGELOG.md` and `package.json` and tags the release as `vX.Y.Z`. That tag publishes a container image to -`us-docker.pkg.dev/e2b-artifacts/dashboard/dashboard:vX.Y.Z` (`linux/amd64`, -anonymous pulls): +`us-docker.pkg.dev/e2b-artifacts/dashboard/dashboard:vX.Y.Z` (`linux/amd64` and +`linux/arm64`, anonymous pulls): ```bash docker run --rm -p 3001:3001 us-docker.pkg.dev/e2b-artifacts/dashboard/dashboard:vX.Y.Z diff --git a/tests/unit/publish-workflow.test.ts b/tests/unit/publish-workflow.test.ts index 55439425c..28f31558f 100644 --- a/tests/unit/publish-workflow.test.ts +++ b/tests/unit/publish-workflow.test.ts @@ -33,7 +33,8 @@ describe('publish workflow', () => { expect(workflow).toContain( 'us-docker.pkg.dev/e2b-artifacts/dashboard/dashboard' ) - expect(workflow).toContain('--platform linux/amd64') + expect(workflow).toContain('platforms=linux/amd64,linux/arm64') + expect(workflow).toContain('docker/setup-qemu-action@') }) it('disables the attestations Artifact Registry rejects', () => { From ac89654a0c6f07c445799bf802d5de271e6376f9 Mon Sep 17 00:00:00 2001 From: Shan Valleru Date: Wed, 16 Sep 2026 14:29:09 -0700 Subject: [PATCH 2/2] test(publish): say the workflow guards two architectures The file docstring still described a single-architecture build after the assertions moved to linux/amd64,linux/arm64 (review nit on #533). --- tests/unit/publish-workflow.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/publish-workflow.test.ts b/tests/unit/publish-workflow.test.ts index 28f31558f..972bedee3 100644 --- a/tests/unit/publish-workflow.test.ts +++ b/tests/unit/publish-workflow.test.ts @@ -4,8 +4,8 @@ import { describe, expect, it } from 'vitest' /** * The publish path cannot be exercised outside a release, so these assertions - * guard the flags it cannot go without: the registry it pushes to, the single - * architecture, and the attestation switches Artifact Registry rejects. + * guard the flags it cannot go without: the registry it pushes to, the two + * architectures, and the attestation switches Artifact Registry rejects. */ const read = (relativePath: string) => readFileSync(join(process.cwd(), relativePath), 'utf8')