ci: native arm64 runners for PR builds (replace QEMU emulation)#868
Merged
ci: native arm64 runners for PR builds (replace QEMU emulation)#868
Conversation
…lation PR builds now use parallel native runners (ubuntu-latest for amd64, ubuntu-24.04-arm for arm64) with digest-based manifest merging. Release builds retain the existing buildx cross-compilation flow. Also adds explicit permissions blocks to satisfy CodeQL.
rohan-chaturvedi
approved these changes
May 1, 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.
Summary
Splits the staging/PR Docker build off the legacy single-runner buildx flow onto a matrix that uses native runners per architecture, then merges them into a single multi-arch manifest by digest. Release builds (the
:version+:latestpush tophasehq/backendandphasehq/frontend) are intentionally left on the existing flow — this PR only touches the staging path.Cherry-picked from #820 (workflow changes only — the URL routing changes from that PR are not included here).
What changed
testjob is now a separate job that both build paths depend on.buildjob (PR/staging only): matrix overubuntu-latest(amd64) andubuntu-24.04-arm(arm64), each builds + pushes by digest to DockerHub and GHCR.mergejob (PR/staging only): downloads digest artifacts and assembles a multi-arch manifest withdocker buildx imagetools create.build_and_pushjob kept for release path (is_pr != 'true'), unchanged in substance.scope=backend-amd64/scope=backend-arm64) so the two arches don't fight over a shared cache key.permissions:blocks on every job to satisfy CodeQL.Why
ARM64 staging builds were going through QEMU on an AMD64 runner — typically ~10–20 minutes per arch, serialized inside one buildx invocation. Native arm64 runners build in their own architecture and run in parallel with amd64, so wall-clock drops substantially.
Not in scope (follow-up)
Release builds (
:version+:latest) still use the old single-runner cross-compile flow. Migrating those should be a follow-up once we've validated the staging matrix in CI.Test plan
test→build (amd64)+build (arm64)in parallel →mergephasehq/backend-staging:<sha>andghcr.io/phasehq/console/backend-staging:<sha>resolve as multi-arch manifestsphasehq/frontend-staging:<sha>andghcr.io/phasehq/console/frontend-staging:<sha>resolve as multi-arch manifestsdocker manifest inspecton each shows bothlinux/amd64andlinux/arm64entriesis_pr != 'true') still produces multi-archphasehq/backend:<version>/:latestand the frontend equivalents