|
| 1 | +## How ARM64 builds work |
| 2 | + |
| 3 | +### 1. Build phase — on each arch runner independently |
| 4 | + |
| 5 | +The `Build` task runs on **both** the `ubuntu-latest` (amd64) and the `ubuntu-24.04-arm` (arm64) GitHub Actions runners in parallel via a matrix job. |
| 6 | + |
| 7 | +On each runner, `Build` detects the host architecture at runtime: |
| 8 | + |
| 9 | +```powershell |
| 10 | +$hostArch = if ($IsLinux) { (dpkg --print-architecture 2>$null) ?? 'amd64' } else { 'amd64' } |
| 11 | +``` |
| 12 | + |
| 13 | +It then calls `docker build` and tags the produced image with an arch suffix: |
| 14 | + |
| 15 | +- **amd64 runner** → `firebirdsql/firebird-amd64:<tag>` (e.g. `firebirdsql/firebird-amd64:5.0.3-bookworm`) |
| 16 | +- **arm64 runner** → `firebirdsql/firebird-arm64:<tag>` (e.g. `firebirdsql/firebird-arm64:5.0.3-bookworm`) |
| 17 | + |
| 18 | +For Firebird 3.x and 4.x, which have no upstream ARM64 binary, `Build` checks `assets.json` for an `arm64` key. If it is absent, the arm64 build is skipped on the arm64 runner. The `Test` task similarly skips those versions on arm64. |
| 19 | + |
| 20 | +### 2. Publish-Arch — push staging tags (runs on each arch runner) |
| 21 | + |
| 22 | +After the build and tests, `Publish-Arch` pushes the locally built images to the registry using **tag-based staging** (not a separate image name): |
| 23 | + |
| 24 | +```powershell |
| 25 | +docker tag "$imagePrefix/firebird-${hostArch}:$tag" "$imagePrefix/firebird:$tag-$hostArch" |
| 26 | +docker push "$imagePrefix/firebird:$tag-$hostArch" |
| 27 | +``` |
| 28 | + |
| 29 | +So for tag `5.0.3-bookworm` this produces two pushed tags inside the **same** registry package: |
| 30 | +- `firebirdsql/firebird:5.0.3-bookworm-amd64` |
| 31 | +- `firebirdsql/firebird:5.0.3-bookworm-arm64` |
| 32 | + |
| 33 | +Both runners run `Publish-Arch` in parallel. When the matrix job is done, both arch-specific staging tags are in the registry. |
| 34 | + |
| 35 | +### 3. Publish-Manifests — create OCI multi-arch manifests (runs once, on ubuntu-latest) |
| 36 | + |
| 37 | +The `create-manifests` job in `publish.yaml` runs after all `build-and-test` matrix jobs succeed (`needs: build-and-test`). It calls `Publish-Manifests`: |
| 38 | + |
| 39 | +```powershell |
| 40 | +docker manifest create --amend "$imagePrefix/firebird:$tag" \ |
| 41 | + "$imagePrefix/firebird:$tag-amd64" \ |
| 42 | + "$imagePrefix/firebird:$tag-arm64" |
| 43 | +
|
| 44 | +docker manifest annotate "$imagePrefix/firebird:$tag" \ |
| 45 | + "$imagePrefix/firebird:$tag-amd64" --os linux --arch amd64 |
| 46 | +docker manifest annotate "$imagePrefix/firebird:$tag" \ |
| 47 | + "$imagePrefix/firebird:$tag-arm64" --os linux --arch arm64 |
| 48 | +
|
| 49 | +docker manifest push "$imagePrefix/firebird:$tag" |
| 50 | +``` |
| 51 | + |
| 52 | +This assembles the staging tags into a single OCI manifest list (multi-arch image). After the push, `docker pull firebirdsql/firebird:5.0.3-bookworm` on any machine automatically pulls the correct architecture. |
| 53 | + |
| 54 | +For **amd64-only** versions (Firebird 3.x, 4.x), `Publish-Manifests` creates a single-arch manifest from the `-amd64` staging tag instead. |
| 55 | + |
| 56 | +--- |
| 57 | + |
| 58 | +## Summary diagram |
| 59 | + |
| 60 | +``` |
| 61 | +ubuntu-latest (amd64) ubuntu-24.04-arm (arm64) |
| 62 | +───────────────────── ───────────────────────── |
| 63 | +Build Build |
| 64 | + → firebird-amd64:<tag> → firebird-arm64:<tag> |
| 65 | +Test Test (skips FB3/FB4) |
| 66 | +Publish-Arch Publish-Arch |
| 67 | + → push firebird:<tag>-amd64 → push firebird:<tag>-arm64 |
| 68 | + ↘ ↙ |
| 69 | + create-manifests (ubuntu-latest) |
| 70 | + Publish-Manifests |
| 71 | + docker manifest create firebird:<tag> |
| 72 | + ← firebird:<tag>-amd64 |
| 73 | + ← firebird:<tag>-arm64 |
| 74 | + docker manifest push firebird:<tag> |
| 75 | +``` |
| 76 | + |
0 commit comments