Skip to content

Commit a84688f

Browse files
jmgrosenclaude
andcommitted
Use native runners for multiplatform build
Split build across ubuntu-latest (amd64) and ubuntu-24.04-arm (arm64) with a merge job to create the manifest list. Much faster than QEMU cross-compilation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6192841 commit a84688f

File tree

1 file changed

+75
-13
lines changed

1 file changed

+75
-13
lines changed

.github/workflows/build.yml

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,27 @@ env:
99
IMAGE_NAME: ${{ github.repository }}
1010

1111
jobs:
12-
build-and-push:
13-
runs-on: ubuntu-latest
12+
build:
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
include:
17+
- platform: linux/amd64
18+
runner: ubuntu-latest
19+
- platform: linux/arm64
20+
runner: ubuntu-24.04-arm
21+
runs-on: ${{ matrix.runner }}
1422
permissions:
1523
contents: read
1624
packages: write
17-
1825
steps:
1926
- uses: actions/checkout@v4
2027

28+
- name: Prepare platform pair
29+
run: |
30+
platform=${{ matrix.platform }}
31+
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
32+
2133
- uses: docker/login-action@v3
2234
with:
2335
registry: ${{ env.REGISTRY }}
@@ -28,20 +40,70 @@ jobs:
2840
id: meta
2941
with:
3042
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
31-
tags: |
32-
type=sha
33-
type=raw,value=latest
34-
35-
- uses: docker/setup-qemu-action@v3
3643

3744
- uses: docker/setup-buildx-action@v3
3845

3946
- uses: docker/build-push-action@v6
47+
id: build
4048
with:
4149
context: .
42-
platforms: linux/amd64,linux/arm64
43-
push: true
44-
tags: ${{ steps.meta.outputs.tags }}
50+
platforms: ${{ matrix.platform }}
4551
labels: ${{ steps.meta.outputs.labels }}
46-
cache-from: type=gha
47-
cache-to: type=gha,mode=max
52+
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
53+
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
54+
cache-from: type=gha,scope=${{ matrix.platform }}
55+
cache-to: type=gha,scope=${{ matrix.platform }},mode=max
56+
57+
- name: Export digest
58+
run: |
59+
mkdir -p ${{ runner.temp }}/digests
60+
digest="${{ steps.build.outputs.digest }}"
61+
touch "${{ runner.temp }}/digests/${digest#sha256:}"
62+
63+
- name: Upload digest
64+
uses: actions/upload-artifact@v4
65+
with:
66+
name: digests-${{ env.PLATFORM_PAIR }}
67+
path: ${{ runner.temp }}/digests/*
68+
if-no-files-found: error
69+
retention-days: 1
70+
71+
merge:
72+
runs-on: ubuntu-latest
73+
needs: build
74+
permissions:
75+
contents: read
76+
packages: write
77+
steps:
78+
- name: Download digests
79+
uses: actions/download-artifact@v4
80+
with:
81+
path: ${{ runner.temp }}/digests
82+
pattern: digests-*
83+
merge-multiple: true
84+
85+
- uses: docker/login-action@v3
86+
with:
87+
registry: ${{ env.REGISTRY }}
88+
username: ${{ github.actor }}
89+
password: ${{ secrets.GITHUB_TOKEN }}
90+
91+
- uses: docker/setup-buildx-action@v3
92+
93+
- uses: docker/metadata-action@v5
94+
id: meta
95+
with:
96+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
97+
tags: |
98+
type=sha
99+
type=raw,value=latest
100+
101+
- name: Create manifest list and push
102+
working-directory: ${{ runner.temp }}/digests
103+
run: |
104+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
105+
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
106+
107+
- name: Inspect image
108+
run: |
109+
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

0 commit comments

Comments
 (0)