Skip to content

feat(builder): arm64 builds with tag isolation, plus builder-merge #269

Description

@conbrad

Problem

builder builds only the runner's architecture (amd64 on ubuntu-*). Developers on Apple Silicon run every image under emulation, which is slow and crash-prone for native-heavy images like GDAL. Teams that want arm64 have to leave builder and write their own build workflow. bcgov/wps did this in bcgov/wps#5899.

Two constraints shape the fix:

  • No QEMU. Emulating arm64 on an amd64 runner is very slow for compile-heavy builds, so arm64 has to build natively on an ARM runner (ubuntu-24.04-arm).
  • Deploys stay amd64. OpenShift runs amd64 only, and the deploy contract (build → image-tracker → deploy by digest) relies on the canonical tags (:<pr>, :<sha>, :test, :prod) and outputs.digest being amd64. An arm64 build must never change those or block a deploy.

Proposal

  1. architecture input on builder. Leave it unset (or amd64) for today's behaviour. Set it to arm64 on an ARM runner and every tag, plus the tag_fallback lookup (test-arm64), gets an -arm64 suffix, so it can never overwrite a canonical tag. It must match the runner: a mismatch fails rather than emulating. The arm64 job keeps its own build cache, and nothing that deploys depends on it.
  2. image-tracker only resolves the deploy architecture. The -arm64 images carry the same revision label as the canonical image, so without this check image-tracker's fallback scan can return an arm64 image for an amd64 deploy. A new architecture input (default amd64) means a multi-arch index must include it and a single-arch image must be it; other images are skipped. Images whose architecture is unknown are still accepted.
  3. Optional builder-merge action. For teams that want one tag that runs natively everywhere, it combines the canonical amd64 image and the -arm64 image into a separate :<pr>-multiarch / :<sha>-multiarch tag. It never writes canonical tags.
build:
  runs-on: ubuntu-24.04
  steps:
    - uses: bcgov/actions/builder@vX.Y.Z
      with:
        package: backend

build-arm64:
  runs-on: ubuntu-24.04-arm
  steps:
    - uses: bcgov/actions/builder@vX.Y.Z
      with:
        package: backend
        architecture: arm64

merge:   # optional
  needs: [build, build-arm64]
  runs-on: ubuntu-24.04
  steps:
    - uses: bcgov/actions/builder-merge@vX.Y.Z
      with:
        package: backend

Acceptance

  • With architecture unset, builder behaves exactly as today
  • architecture: arm64 builds natively on an ARM runner, publishes only -arm64 tags, falls back to <tag_fallback>-arm64, and fails on a mismatched runner
  • Canonical tags and outputs.digest stay amd64
  • image-tracker never resolves a non-amd64 image by default, including through its fallback scan
  • builder-merge publishes an amd64 + arm64 -multiarch index and leaves canonical tags unchanged
  • Tests cover canonical vs -arm64 tags, image-tracker resolution, builder-merge, and the per-architecture fallback
  • READMEs document the two-job setup, builder-merge, and the image-tracker architecture input

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions