Skip to content

Commit c1b97c0

Browse files
authored
docker: Build arm image using ubuntu-24.04-arm runner (#42212)
Linux arm64 runners are in public preview. Building the arm64 part of the Docker image on one of these rather than in qemu should be a lot faster; let's try it.
1 parent 0e73aa1 commit c1b97c0

File tree

2 files changed

+281
-78
lines changed

2 files changed

+281
-78
lines changed

.github/workflows/build-docker-monorepo.yml

+141-39
Original file line numberDiff line numberDiff line change
@@ -18,40 +18,31 @@ concurrency:
1818
cancel-in-progress: true
1919

2020
jobs:
21-
build:
22-
name: Build and publish Jetpack Monorepo Environment
21+
prepare:
22+
name: Prepare
2323
runs-on: ubuntu-latest
2424
permissions:
25-
packages: write
2625
contents: read
27-
timeout-minutes: 60
26+
timeout-minutes: 5 # 2025-03-04: Takes just a few seconds.
27+
outputs:
28+
php-version: ${{ steps.buildargs.outputs.php-version }}
29+
composer-version: ${{ steps.buildargs.outputs.composer-version }}
30+
node-version: ${{ steps.buildargs.outputs.node-version }}
31+
pnpm-version: ${{ steps.buildargs.outputs.pnpm-version }}
32+
labels: ${{ steps.buildargs.outputs.labels }}
33+
tags: ${{ steps.buildargs.outputs.tags }}
34+
images: ${{ steps.buildargs.outputs.images }}
2835

2936
steps:
3037
- uses: actions/checkout@v4
3138

32-
- name: Set up qemu
33-
uses: docker/setup-qemu-action@v3
34-
with:
35-
platforms: arm64
36-
37-
- name: Set up Docker Buildx
38-
uses: docker/setup-buildx-action@v3
39-
40-
- name: Log in to Docker Hub
41-
uses: docker/login-action@v3
42-
with:
43-
username: matticbot
44-
password: ${{ secrets.DOCKER_HUB_MATTICBOT_TOKEN }}
45-
46-
- name: Log in to GitHub Packages
47-
uses: docker/login-action@v3
48-
with:
49-
registry: ghcr.io
50-
username: ${{ github.actor }}
51-
password: ${{ secrets.GITHUB_TOKEN }}
52-
5339
- name: Fetch build args
5440
id: buildargs
41+
env:
42+
LABELS: |
43+
org.opencontainers.image.title=Jetpack Monorepo Environment
44+
org.opencontainers.image.description=Environment for building and testing the Jetpack Monorepo.
45+
org.opencontainers.image.documentation=${{ github.server_url }}/${{ github.repository }}/blob/trunk/tools/docker/README.md
5546
run: |
5647
source .github/versions.sh
5748
source .github/files/gh-funcs.sh
@@ -60,7 +51,9 @@ jobs:
6051
gh_set_output composer-version "$COMPOSER_VERSION"
6152
gh_set_output node-version "$NODE_VERSION"
6253
gh_set_output pnpm-version "$PNPM_VERSION"
54+
gh_set_output labels "$LABELS"
6355
56+
# We're not git-tagging for the env. Just tag all trunk builds as latest.
6457
if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then
6558
gh_set_output tags "type=raw,latest"
6659
gh_set_output images $'automattic/jetpack-monorepo\nghcr.io/automattic/jetpack-monorepo'
@@ -72,29 +65,138 @@ jobs:
7265
exit 1
7366
fi
7467
68+
build:
69+
name: Build Jetpack Monorepo Environment (${{ matrix.platform }})
70+
runs-on: ${{ matrix.runner }}
71+
needs: prepare
72+
permissions:
73+
packages: write
74+
contents: read
75+
timeout-minutes: 15 # 2025-03-04: Arm64 build takes about 5 minutes, amd64 build about 3.
76+
strategy:
77+
matrix:
78+
include:
79+
- runner: ubuntu-latest
80+
platform: amd64
81+
- runner: ubuntu-24.04-arm
82+
platform: arm64
83+
84+
steps:
85+
- uses: actions/checkout@v4
86+
87+
- name: Set up Docker Buildx
88+
uses: docker/setup-buildx-action@v3
89+
90+
- name: Log in to Docker Hub
91+
uses: docker/login-action@v3
92+
with:
93+
username: matticbot
94+
password: ${{ secrets.DOCKER_HUB_MATTICBOT_TOKEN }}
95+
96+
- name: Log in to GitHub Packages
97+
uses: docker/login-action@v3
98+
with:
99+
registry: ghcr.io
100+
username: ${{ github.actor }}
101+
password: ${{ secrets.GITHUB_TOKEN }}
102+
75103
- name: Extract Docker metadata
76104
id: meta
77105
uses: docker/metadata-action@v5
78106
with:
79107
flavor: latest=false
80-
tags: ${{ steps.buildargs.outputs.tags }}
81-
images: ${{ steps.buildargs.outputs.images }}
82-
labels: |
83-
org.opencontainers.image.title=Jetpack Monorepo Environment
84-
org.opencontainers.image.description=Environment for building and testing the Jetpack Monorepo.
85-
org.opencontainers.image.documentation=${{ github.server_url }}/${{ github.repository }}/blob/trunk/tools/docker/README.md
108+
images: ${{ needs.prepare.outputs.images }}
109+
labels: ${{ needs.prepare.outputs.labels }}
86110

87-
- name: Build and push Docker image
111+
- name: Build and push by digest
112+
id: build
88113
uses: docker/build-push-action@v6
89114
with:
90115
context: tools/docker
91116
file: tools/docker/Dockerfile.monorepo
92-
push: true
93-
tags: ${{ steps.meta.outputs.tags }}
117+
platforms: linux/${{ matrix.platform }}
118+
# For push by digest, the "tags" are just the images. We tag later.
119+
tags: ${{ needs.prepare.outputs.images }}
94120
labels: ${{ steps.meta.outputs.labels }}
95-
platforms: linux/arm64,linux/amd64
121+
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
96122
build-args: |
97-
PHP_VERSION=${{ steps.buildargs.outputs.php-version }}
98-
COMPOSER_VERSION=${{ steps.buildargs.outputs.composer-version }}
99-
NODE_VERSION=${{ steps.buildargs.outputs.node-version }}
100-
PNPM_VERSION=${{ steps.buildargs.outputs.pnpm-version }}
123+
PHP_VERSION=${{ needs.prepare.outputs.php-version }}
124+
COMPOSER_VERSION=${{ needs.prepare.outputs.composer-version }}
125+
NODE_VERSION=${{ needs.prepare.outputs.node-version }}
126+
PNPM_VERSION=${{ needs.prepare.outputs.pnpm-version }}
127+
128+
- name: Export digest
129+
env:
130+
TEMP: ${{ runner.temp }}
131+
DIGEST: ${{ steps.build.outputs.digest }}
132+
run: |
133+
mkdir -p "$TEMP/digests"
134+
touch "$TEMP/digests/${DIGEST#sha256:}"
135+
136+
- name: Upload digest
137+
uses: actions/upload-artifact@v4
138+
with:
139+
name: digests-linux-${{ matrix.platform }}
140+
path: ${{ runner.temp }}/digests/*
141+
if-no-files-found: error
142+
retention-days: 1
143+
144+
merge:
145+
name: Merge and publish Jetpack Monorepo Environment
146+
runs-on: ubuntu-latest
147+
needs: [ prepare, build ]
148+
permissions:
149+
packages: write
150+
contents: read
151+
timeout-minutes: 5 # 2025-03-04: Merge takes less than a minute.
152+
153+
steps:
154+
- name: Download digests
155+
uses: actions/download-artifact@v4
156+
with:
157+
path: ${{ runner.temp }}/digests
158+
pattern: digests-*
159+
merge-multiple: true
160+
161+
- name: Set up Docker Buildx
162+
uses: docker/setup-buildx-action@v3
163+
164+
- name: Log in to Docker Hub
165+
uses: docker/login-action@v3
166+
with:
167+
username: matticbot
168+
password: ${{ secrets.DOCKER_HUB_MATTICBOT_TOKEN }}
169+
170+
- name: Log in to GitHub Packages
171+
uses: docker/login-action@v3
172+
with:
173+
registry: ghcr.io
174+
username: ${{ github.actor }}
175+
password: ${{ secrets.GITHUB_TOKEN }}
176+
177+
- name: Extract Docker metadata
178+
id: meta
179+
uses: docker/metadata-action@v5
180+
with:
181+
flavor: latest=false
182+
tags: ${{ needs.prepare.outputs.tags }}
183+
images: ${{ needs.prepare.outputs.images }}
184+
labels: ${{ needs.prepare.outputs.labels }}
185+
186+
- name: Create manifest list and push
187+
working-directory: ${{ runner.temp }}/digests
188+
run: |
189+
while IFS= read -r IMAGE; do
190+
echo "=== $IMAGE ==="
191+
docker buildx imagetools create $(jq -cr --arg IMG "$IMAGE" '.tags | map( select( startswith( $IMG + ":" ) ) | "-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
192+
$(printf "$IMAGE@sha256:%s " *)
193+
done < <( jq -r '.tags[] | sub( ":.*"; "" )' <<< "$DOCKER_METADATA_OUTPUT_JSON" )
194+
195+
- name: Inspect image
196+
env:
197+
VERSION: ${{ steps.meta.outputs.version }}
198+
run: |
199+
while IFS= read -r IMAGE; do
200+
echo "=== $IMAGE ==="
201+
docker buildx imagetools inspect "$IMAGE:$VERSION"
202+
done < <( jq -r '.tags[] | sub( ":.*"; "" )' <<< "$DOCKER_METADATA_OUTPUT_JSON" )

0 commit comments

Comments
 (0)