Skip to content

Commit fcfdafe

Browse files
committed
build multiplatform images for testing
1 parent 137a64e commit fcfdafe

File tree

2 files changed

+134
-63
lines changed

2 files changed

+134
-63
lines changed

.github/workflows/build.yml

Lines changed: 112 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,32 @@ name: Build / Test / Push
33
on:
44
push:
55
branches:
6-
- '*'
6+
- '**'
7+
workflow_call:
78
workflow_dispatch:
89

10+
env:
11+
BUILD_SUFFIX: -build-${{ github.run_id }}_${{ github.run_attempt }}
12+
DOCKER_METADATA_SET_OUTPUT_ENV: 'true'
13+
914
jobs:
1015
build:
11-
runs-on: ubuntu-latest
16+
runs-on: ${{ matrix.runner }}
1217
outputs:
13-
build-image: ${{ steps.build-meta.outputs.tags }}
18+
build-image-arm: ${{ steps.gen-output.outputs.image-arm64 }}
19+
build-image-x64: ${{ steps.gen-output.outputs.image-x64 }}
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
include:
24+
- platform: linux/amd64
25+
runner: ubuntu-24.04
26+
- platform: linux/arm64
27+
runner: ubuntu-24.04-arm
1428
steps:
1529
- name: Checkout code
1630
uses: actions/checkout@v4
1731

18-
- name: Set up QEMU
19-
uses: docker/setup-qemu-action@v3
20-
2132
- name: Set up Docker Buildx
2233
uses: docker/setup-buildx-action@v3
2334

@@ -28,37 +39,105 @@ jobs:
2839
username: ${{ github.actor }}
2940
password: ${{ secrets.GITHUB_TOKEN }}
3041

31-
- name: Produce the build image tag
32-
id: build-meta
42+
- id: build-meta
43+
name: Docker meta
44+
uses: docker/metadata-action@v5
45+
with:
46+
images: ghcr.io/${{ github.repository }}
47+
tags: type=sha,suffix=${{ env.BUILD_SUFFIX }}
48+
49+
# Build cache is shared among all builds of the same architecture
50+
- id: cache-meta
51+
name: Docker meta
3352
uses: docker/metadata-action@v5
3453
with:
3554
images: ghcr.io/${{ github.repository }}
36-
tags: type=sha,suffix=-build-${{ github.run_id }}_${{ github.run_attempt }}
55+
tags: type=raw,value=buildcache-${{ runner.arch }}
56+
57+
- id: get-registry
58+
name: Get the sanitized registry name
59+
run: |
60+
echo "registry=$(echo '${{ steps.build-meta.outputs.tags }}' | cut -f1 -d:)" | tee -a "$GITHUB_OUTPUT"
61+
62+
- id: set_build_url
63+
name: Set BUILD_URL
64+
run: |
65+
echo "build_url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" | tee -a "$GITHUB_OUTPUT"
3766
38-
- name: Build and push the untested image
67+
- id: build
68+
name: Build/push the arch-specific image
3969
uses: docker/build-push-action@v6
4070
with:
41-
push: true
71+
platforms: ${{ matrix.platform }}
72+
build-args: |
73+
BUILD_TIMESTAMP=${{ github.event.repository.updated_at }}
74+
BUILD_URL=${{ steps.set_build_url.outputs.build_url }}
75+
GIT_REF_NAME=${{ github.ref_name }}
76+
GIT_SHA=${{ github.sha }}
77+
GIT_REPOSITORY_URL=${{ github.repositoryUrl }}
78+
cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }}
79+
cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max
4280
labels: ${{ steps.build-meta.outputs.labels }}
43-
tags: ${{ steps.build-meta.outputs.tags }}
44-
provenance: true
45-
cache-from: type=gha
46-
cache-to: type=gha
81+
provenance: mode=max
82+
sbom: true
83+
tags: ${{ steps.get-registry.outputs.registry }}
84+
outputs: type=image,push-by-digest=true,push=true
85+
86+
- id: gen-output
87+
name: Write arch-specific image digest to outputs
88+
run: |
89+
echo "image-${RUNNER_ARCH,,}=${{ steps.get-registry.outputs.registry }}@${{ steps.build.outputs.digest }}" | tee -a "$GITHUB_OUTPUT"
90+
91+
merge:
92+
runs-on: ubuntu-24.04
93+
needs:
94+
- build
95+
env:
96+
DOCKER_APP_IMAGE_ARM64: ${{ needs.build.outputs.build-image-arm }}
97+
DOCKER_APP_IMAGE_X64: ${{ needs.build.outputs.build-image-x64 }}
98+
outputs:
99+
build-image: ${{ steps.meta.outputs.tags }}
100+
build-image-arm: ${{ needs.build.outputs.build-image-arm }}
101+
build-image-x64: ${{ needs.build.outputs.build-image-x64 }}
102+
steps:
103+
- name: Checkout code
104+
uses: actions/checkout@v4
105+
106+
- name: Set up Docker Buildx
107+
uses: docker/setup-buildx-action@v3
108+
109+
- name: Login to GitHub Container Registry
110+
uses: docker/login-action@v3
111+
with:
112+
registry: ghcr.io
113+
username: ${{ github.actor }}
114+
password: ${{ secrets.GITHUB_TOKEN }}
115+
116+
- name: Docker meta
117+
id: meta
118+
uses: docker/metadata-action@v5
119+
with:
120+
images: ghcr.io/${{ github.repository }}
121+
tags: |
122+
type=sha,suffix=-build-${{ github.run_id }}_${{ github.run_attempt }}
123+
124+
- name: Push the multi-platform image
125+
run: |
126+
docker buildx imagetools create \
127+
--tag "$DOCKER_METADATA_OUTPUT_TAGS" \
128+
"$DOCKER_APP_IMAGE_ARM64" "$DOCKER_APP_IMAGE_X64"
47129
48130
test:
49-
runs-on: ubuntu-latest
131+
runs-on: ubuntu-24.04
50132
needs:
51-
- build
133+
- merge
52134
env:
53135
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
54-
DOCKER_APP_IMAGE: ${{ needs.build.outputs.build-image }}
136+
DOCKER_APP_IMAGE: ${{ needs.merge.outputs.build-image }}
55137
steps:
56138
- name: Checkout code
57139
uses: actions/checkout@v4
58140

59-
- name: Set up QEMU
60-
uses: docker/setup-qemu-action@v3
61-
62141
- name: Set up Docker Compose
63142
uses: docker/setup-compose-action@v1
64143

@@ -102,14 +181,21 @@ jobs:
102181
if-no-files-found: error
103182

104183
push:
105-
runs-on: ubuntu-latest
184+
runs-on: ubuntu-24.04
106185
needs:
107-
- build
186+
- merge
108187
- test
188+
env:
189+
DOCKER_APP_IMAGE: ${{ needs.merge.outputs.build-image }}
190+
DOCKER_APP_IMAGE_ARM64: ${{ needs.merge.outputs.build-image-arm }}
191+
DOCKER_APP_IMAGE_X64: ${{ needs.merge.outputs.build-image-x64 }}
109192
steps:
110193
- name: Checkout code
111194
uses: actions/checkout@v4
112195

196+
- name: Set up Docker Buildx
197+
uses: docker/setup-buildx-action@v3
198+
113199
- name: Login to GitHub Container Registry
114200
uses: docker/login-action@v3
115201
with:
@@ -128,9 +214,6 @@ jobs:
128214
type=raw,value=latest,enable={{is_default_branch}}
129215
130216
- name: Retag and push the image
131-
uses: docker/build-push-action@v6
132-
with:
133-
push: true
134-
labels: ${{ steps.branch-meta.outputs.labels }}
135-
tags: ${{ steps.branch-meta.outputs.tags }}
136-
cache-from: type=registry,ref=${{ needs.build.outputs.build-image }}
217+
run: |
218+
docker buildx imagetools create \
219+
$(jq -cr '.tags | map("--tag " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") $DOCKER_APP_IMAGE_ARM64 $DOCKER_APP_IMAGE_X64

.github/workflows/release.yml

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,26 @@ name: Push Release Tags
33
on:
44
push:
55
tags:
6-
- '*'
6+
- '**'
7+
workflow_call:
78
workflow_dispatch:
89

10+
env:
11+
DOCKER_METADATA_SET_OUTPUT_ENV: 'true'
12+
913
jobs:
10-
verify:
14+
retag:
1115
runs-on: ubuntu-latest
12-
outputs:
13-
base_image: ${{ steps.get-base-image.outputs.tags }}
1416
steps:
1517
- name: Checkout code
1618
uses: actions/checkout@v4
1719

20+
- name: Set up QEMU
21+
uses: docker/setup-qemu-action@v3
22+
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v3
25+
1826
- name: Login to GitHub Container Registry
1927
uses: docker/login-action@v3
2028
with:
@@ -30,33 +38,13 @@ jobs:
3038
tags: type=sha
3139

3240
- name: Verify that the image was previously built
33-
run: docker pull "$BASE_IMAGE"
3441
env:
3542
BASE_IMAGE: ${{ steps.get-base-image.outputs.tags }}
36-
37-
retag:
38-
runs-on: ubuntu-latest
39-
needs:
40-
- verify
41-
steps:
42-
- name: Checkout code
43-
uses: actions/checkout@v4
44-
45-
- name: Set up QEMU
46-
uses: docker/setup-qemu-action@v3
47-
48-
- name: Set up Docker Buildx
49-
uses: docker/setup-buildx-action@v3
50-
51-
- name: Login to GitHub Container Registry
52-
uses: docker/login-action@v3
53-
with:
54-
registry: ghcr.io
55-
username: ${{ github.actor }}
56-
password: ${{ secrets.GITHUB_TOKEN }}
43+
run: |
44+
docker manifest inspect "$BASE_IMAGE"
5745
5846
- name: Produce release tags
59-
id: meta
47+
id: tag-meta
6048
uses: docker/metadata-action@v5
6149
with:
6250
images: ghcr.io/${{ github.repository }}
@@ -67,10 +55,10 @@ jobs:
6755
type=semver,pattern={{major}}.{{minor}}
6856
type=semver,pattern={{version}}
6957
70-
- name: Retag and push the image
71-
uses: docker/build-push-action@v6
72-
with:
73-
push: true
74-
labels: ${{ steps.meta.outputs.labels }}
75-
tags: ${{ steps.meta.outputs.tags }}
76-
cache-from: type=registry,ref=${{ needs.verify.outputs.base_image }}
58+
- name: Retag the pulled image
59+
env:
60+
BASE_IMAGE: ${{ steps.get-base-image.outputs.tags }}
61+
run: |
62+
docker buildx imagetools create \
63+
$(jq -cr '.tags | map("--tag " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
64+
"$(echo "$BASE_IMAGE" | cut -f1 -d:)"

0 commit comments

Comments
 (0)