Repository navigation
ci: build each published platform on a native runner - #549
Merged
Merged
Conversation
The arm64 half of the image was built under QEMU on one x64 runner and took about 24 of a publish run's 25 minutes. Each platform now builds natively on its own runner and pushes by digest, and a final job joins the two into the tagged manifest list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pmakanju-e2b
requested review from
Kraci,
ben-fornefeld and
drankou
as code owners
November 6, 2026 10:21
The publish workflow test still required the QEMU action and a single multi-platform build. It now checks for native per-architecture runners, push by digest, a manifest list verified before it is tagged, and a dry run that never reaches the merge job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
drankou
approved these changes
Nov 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Publishing a release takes far longer than the build itself needs. The last five Publish runs took 15–29 minutes. In run 42075381880 (v0.5.1),
next buildtook 150s on amd64 and 1449s on arm64, because the arm64 half of the manifest list was built under QEMU on one x64 runner.Change
.github/workflows/publish.ymlis now three jobs:preflight(ubuntu-latest): the existing checks, unchanged. It checks the credentials are configured, resolves the tag and commit, checks the tag names the commit, and refuses to overwrite an existing tag. It exposestagandshato the later jobs.build: a matrix oflinux/amd64onubuntu-24.04andlinux/arm64onubuntu-24.04-arm, with no QEMU. Both legs check out the exact commitpreflightresolved and build with the same flags, build-arg and OCI labels as before. Each leg pushes its image by digest only (untagged) and uploads that digest as an artifact. Native runners also avoid cross-building, which would ship amd64-only native modules (sharp) in the arm64 image.merge: joins the two digests withdocker buildx imagetools create. It first does a--dry-runand checks that the planned manifest list holds exactlylinux/amd64andlinux/arm64with this run's digests. Only then does it write the tag, because tags are immutable and a wrong list could never be replaced. The step summary is the same as before.A dry run builds both platforms natively, loads them into the runner's local Docker and pushes nothing.
Verification
Dry run from this branch: run 42202046094 passed in 3m17s, using
ref=ci/native-arm64-publish,tag=v0.0.0anddry_run=true. The baseline is the v0.5.1 publish, run 42075381880, which took ~26 min.preflightjobmergejobnext buildamd64: "Compiled in" / step DONEnext buildarm64: "Compiled in" / step DONEbun installamd64 / arm64The arm64
next buildwent from 1449s to 109s. Both legs ran together onubuntu-24.04andubuntu-24.04-arm.Push path rehearsed locally: I ran the push-and-merge path against a throwaway
registry:2with a small Dockerfile and a separate Buildx builder:--metadata-file.imagetools create --dry-runwith the check frommergematched exactlylinux/amd64 <digest>andlinux/arm64 <digest>.imagetools create --tagand the summary'simagetools inspectboth worked.actionlint1.7.12 (with shellcheck) reports no errors.Not yet exercised against Artifact Registry: the real push to Artifact Registry and the
mergejob first run on the next release. Things to watch on that run:digest-amd64/digest-arm64.merge: the manifest-list check passes, and the step summary shows the index digest.docker buildx imagetools inspect us-docker.pkg.dev/e2b-artifacts/dashboard/dashboard:<tag>lists exactlylinux/amd64andlinux/arm64.