@@ -11,36 +11,122 @@ env:
1111
1212jobs :
1313 build :
14- runs-on : ubuntu-latest
14+ # We use a matrix to run each docker container build for a specific platform on it's own native runner.
15+ # This avoids using virtualization and massively speeds up builds.
16+ strategy :
17+ matrix :
18+ platform : [linux/amd64, linux/arm64]
19+ include :
20+ - platform : linux/amd64
21+ runner : ubuntu-latest
22+ - platform : linux/arm64
23+ runner : ubuntu-24.04-arm
24+
25+
26+ name : Build ${{ matrix.platform }}
27+ runs-on : ${{ matrix.runner }}
1528 steps :
16- - name : Checkout
29+ - name : Code checkout
1730 uses : actions/checkout@v4
31+
1832 - name : Set up Docker Buildx
1933 uses : docker/setup-buildx-action@v3
34+
2035 - name : Get source version
21- run : echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk {'print $2'})" >> "$GITHUB_ENV"
36+ run : echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk '{print $2}')" >> "$GITHUB_ENV"
37+
2238 - name : Docker meta
2339 id : meta
2440 uses : docker/metadata-action@v5
2541 with :
2642 images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
43+ flavor : |
44+ latest=false
2745 tags : |
28- type=ref,event=branch
29- type=semver,pattern={{version}}
30- - name : Login to registry ${{ env.REGISTRY }}
46+ type=ref,event=branch,pattern={{branch}}
47+ type=semver,pattern={{version}},value=${{ env.SOURCE_VERSION }}
48+
49+ - name : Derive arch-suffixed tags as output
50+ id : archtags
51+ run : |
52+ set -euo pipefail
53+ ARCH="$(echo '${{ matrix.platform }}' | cut -d/ -f2)"
54+ T="$(printf '%s\n' "${{ steps.meta.outputs.tags }}" | sed "s/$/-${ARCH}/")"
55+ {
56+ echo 'tags<<EOF'
57+ echo "$T"
58+ echo 'EOF'
59+ echo "arch=$ARCH"
60+ } >> "$GITHUB_OUTPUT"
61+
62+ - name : Login to ${{ env.REGISTRY }}
3163 if : github.event_name != 'pull_request'
3264 uses : docker/login-action@v3
3365 with :
3466 registry : ${{ env.REGISTRY }}
3567 username : ${{ secrets.DOCKER_USERNAME }}
3668 password : ${{ secrets.DOCKER_PASSWORD }}
37- - name : Build and push
38- uses : docker/build-push-action@v5
69+
70+ - name : Build & push ${{ matrix.platform }}
71+ uses : docker/build-push-action@v6
3972 with :
4073 context : .
74+ platforms : ${{ matrix.platform }}
75+ push : ${{ github.event_name != 'pull_request' }}
4176 build-args : |
4277 VERSION=${{ env.SOURCE_VERSION }}
43- platforms : linux/amd64,linux/arm64
44- push : ${{ github.event_name != 'pull_request' }}
45- tags : ${{ steps.meta.outputs.tags }}
78+ tags : ${{ steps.archtags.outputs.tags }}
4679 labels : ${{ steps.meta.outputs.labels }}
80+
81+ # In order to have a single tag that covers both archtectures we run one more job to create a multi-arch manifest
82+ # under a single tag.
83+ manifest :
84+ name : Create multi-arch manifest
85+ runs-on : ubuntu-latest
86+ needs : build
87+ steps :
88+ - name : Code checkout
89+ uses : actions/checkout@v4
90+
91+ - name : Get source version
92+ run : echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk '{print $2}')" >> "$GITHUB_ENV"
93+
94+ - name : Docker meta (same base tags)
95+ id : meta
96+ uses : docker/metadata-action@v5
97+ with :
98+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
99+ flavor : |
100+ latest=false
101+ tags : |
102+ type=ref,event=branch,pattern={{branch}}
103+ type=semver,pattern={{version}},value=${{ env.SOURCE_VERSION }}
104+
105+ - name : Login
106+ uses : docker/login-action@v3
107+ with :
108+ registry : ${{ env.REGISTRY }}
109+ username : ${{ secrets.DOCKER_USERNAME }}
110+ password : ${{ secrets.DOCKER_PASSWORD }}
111+
112+ - name : Create manifest for each base tag
113+ if : github.event_name != 'pull_request'
114+ run : |
115+ set -euo pipefail
116+ while IFS= read -r BASE; do
117+ echo "Preparing manifest for $BASE"
118+ AMD="${BASE}-amd64"
119+ ARM="${BASE}-arm64"
120+ # Skip if one arch is missing
121+ docker buildx imagetools inspect "$AMD"
122+ docker buildx imagetools inspect "$ARM"
123+
124+ docker buildx imagetools create \
125+ --tag "$BASE" \
126+ "$AMD" \
127+ "$ARM"
128+
129+ echo "OK: $BASE now points to $AMD + $ARM"
130+ done <<'EOF'
131+ ${{ steps.meta.outputs.tags }}
132+ EOF
0 commit comments