@@ -37,11 +37,22 @@ jobs:
3737 cache-date : ${{ env.CACHE_DATE }}
3838 tag : ${{ env.TAG }}
3939
40- # Build multi- platform builder and final images with caching from Docker Hub
41- # and GitHub Container Registry; push to GitHub Container Registry.
40+ # Build platform-specific builder and final images with caching from Docker
41+ # Hub and GitHub Container Registry; push to GitHub Container Registry.
4242 build :
43+ name : build (${{ matrix.platform }})
4344 needs : vars
44- runs-on : ubuntu-latest
45+ runs-on : ${{ matrix.runner }}
46+ strategy :
47+ matrix :
48+ include :
49+ - platform : linux/amd64
50+ arch : amd64
51+ runner : ubuntu-latest
52+
53+ - platform : linux/arm64
54+ arch : arm64
55+ runner : ubuntu-24.04-arm
4556 steps :
4657
4758 - uses : actions/checkout@v6
5061 with :
5162 python-version : ' >=3.8'
5263
53- - uses : docker/setup-qemu-action@v3
54-
5564 # GITHUB_TOKEN is unreliable¹ so use a token from nextstrain-bot.
5665 # ¹ https://github.com/docker/build-push-action/issues/463#issuecomment-939394233
5766 - uses : docker/login-action@v3
6069 username : nextstrain-bot
6170 password : ${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_MANAGE_PACKAGES }}
6271
63- - run : ./devel/build -p linux/amd64,linux/arm64 -r ghcr.io -t "$TAG" -l logs/
72+ - run : |
73+ ./devel/build \
74+ -p ${{ matrix.platform }} \
75+ -r ghcr.io \
76+ -t "$TAG-${{ matrix.arch }}" \
77+ -l logs-${{ matrix.arch }}/
6478 env:
6579 TAG: ${{ needs.vars.outputs.tag }}
6680 CACHE_DATE: ${{ needs.vars.outputs.cache-date }}
@@ -69,15 +83,15 @@ jobs:
6983 name : Upload build logs as artifacts
7084 uses : actions/upload-artifact@v6
7185 with :
72- name : build-logs
73- path : logs/
86+ name : build-logs-${{ matrix.arch }}
87+ path : logs-${{ matrix.arch }} /
7488
7589 - if : always()
7690 name : Summarize build logs for the GitHub Actions run summary page
7791 run : |
78- for log in logs/*; do
92+ for log in logs-${{ matrix.arch }} /*; do
7993 {
80- echo "## $(basename "$log")"
94+ echo "## [${{ matrix.platform }}] $(basename "$log")"
8195 echo ''
8296 echo '```'
8397 ./devel/summarize-buildkit-output "$log" 2>&1
@@ -86,16 +100,55 @@ jobs:
86100 } >> "$GITHUB_STEP_SUMMARY"
87101 done
88102
103+ # Merge platform-specific images into multi-platform images
104+ merge-builds :
105+ needs : [vars, build]
106+ runs-on : ubuntu-latest
107+ env :
108+ TAG : ${{ needs.vars.outputs.tag }}
109+ steps :
110+ - uses : docker/login-action@v3
111+ with :
112+ registry : ghcr.io
113+ username : nextstrain-bot
114+ password : ${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_MANAGE_PACKAGES }}
115+
116+ - name : Create base-builder-build-platform image
117+ run : |
118+ docker buildx imagetools create \
119+ -t "ghcr.io/nextstrain/base-builder-build-platform:$TAG" \
120+ "ghcr.io/nextstrain/base-builder-build-platform:$TAG-amd64" \
121+ "ghcr.io/nextstrain/base-builder-build-platform:$TAG-arm64"
122+
123+ - name : Create base-builder-target-platform image
124+ run : |
125+ docker buildx imagetools create \
126+ -t "ghcr.io/nextstrain/base-builder-target-platform:$TAG" \
127+ "ghcr.io/nextstrain/base-builder-target-platform:$TAG-amd64" \
128+ "ghcr.io/nextstrain/base-builder-target-platform:$TAG-arm64"
129+
130+ - name : Create base image
131+ run : |
132+ docker buildx imagetools create \
133+ -t "ghcr.io/nextstrain/base:$TAG" \
134+ "ghcr.io/nextstrain/base:$TAG-amd64" \
135+ "ghcr.io/nextstrain/base:$TAG-arm64"
136+
89137 # Run tests with the final image from GitHub Container Registry.
90138 test :
91139 name : test (${{ matrix.platform }})
92- needs : [vars, build ]
93- runs-on : ubuntu-latest
140+ needs : [vars, merge-builds ]
141+ runs-on : ${{ matrix.runner }}
94142 strategy :
95143 matrix :
96- platform :
97- - linux/amd64
98- - linux/arm64
144+ include :
145+ - platform : linux/amd64
146+ runner : ubuntu-latest
147+ - platform : linux/arm64
148+ # TODO: use ubuntu-24.04-arm and remove emulation when Nextstrain
149+ # CLI can be installed natively on aarch64.¹
150+ # ¹ <https://github.com/nextstrain/cli/pull/490>
151+ runner : ubuntu-latest
99152 permissions :
100153 contents : read
101154 id-token : write
@@ -116,9 +169,7 @@ jobs:
116169 with :
117170 python-version : ~3
118171
119- # The ubuntu-latest runner is linux/amd64 so anything else will
120- # run with emulation, which is still better than nothing.
121- - if : matrix.platform != 'linux/amd64'
172+ - if : matrix.platform == 'linux/arm64'
122173 uses : docker/setup-qemu-action@v3
123174
124175 - uses : actions/checkout@v6
@@ -141,7 +192,7 @@ jobs:
141192
142193 validate-platforms :
143194 name : Validate platforms
144- needs : [vars, build ]
195+ needs : [vars, merge-builds ]
145196 runs-on : ubuntu-latest
146197 steps :
147198 - uses : actions/checkout@v6
@@ -161,7 +212,7 @@ jobs:
161212 # Docker Hub, where they will persist. Do this regardless of test results.
162213 push-branch :
163214 if : startsWith(needs.vars.outputs.tag, 'branch-') && github.event_name != 'pull_request'
164- needs : [vars, build ]
215+ needs : [vars, merge-builds ]
165216 runs-on : ubuntu-latest
166217 steps :
167218 - uses : actions/checkout@v6
@@ -185,7 +236,7 @@ jobs:
185236 # Docker Hub, where they will persist. Only do this if tests pass.
186237 push-build :
187238 if : startsWith(needs.vars.outputs.tag, 'build-')
188- needs : [vars, build , test, validate-platforms]
239+ needs : [vars, merge-builds , test, validate-platforms]
189240 runs-on : ubuntu-latest
190241 steps :
191242 - uses : actions/checkout@v6
@@ -283,7 +334,7 @@ jobs:
283334 # Delete the builder and final images from GitHub Container Registry.
284335 cleanup-registry :
285336 if : always()
286- needs : [vars, build , test, validate-platforms, push-branch, push-build]
337+ needs : [vars, merge-builds , test, validate-platforms, push-branch, push-build]
287338 runs-on : ubuntu-latest
288339 steps :
289340 - uses : actions/checkout@v6
@@ -294,5 +345,4 @@ jobs:
294345 script : |
295346 const script = require('./devel/delete-from-ghcr.js');
296347 const tag = "${{ needs.vars.outputs.tag }}";
297- const token = "${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_MANAGE_PACKAGES }}";
298- script({fetch, octokit: github, tag, token});
348+ script({octokit: github, tag});
0 commit comments