77 workflow_dispatch :
88
99env :
10+ BUILD_SUFFIX : -build-${{ github.run_id }}_${{ github.run_attempt }}
1011 DOCKER_METADATA_SET_OUTPUT_ENV : ' true'
1112
1213jobs :
1314 build :
14- runs-on : ubuntu-latest
15+ runs-on : ${{ matrix.runner }}
1516 outputs :
16- build-image : ${{ steps.build-meta.outputs.tags }}
17+ image-arm64 : ${{ steps.gen-output.outputs.image-arm64 }}
18+ image-x64 : ${{ steps.gen-output.outputs.image-x64 }}
19+ strategy :
20+ fail-fast : false
21+ matrix :
22+ runner :
23+ - ubuntu-24.04
24+ - ubuntu-24.04-arm
1725 steps :
1826 - name : Checkout code
1927 uses : actions/checkout@v4
2028
21- - name : Set up QEMU
22- uses : docker/setup-qemu-action@v3
23-
2429 - name : Set up Docker Buildx
2530 uses : docker/setup-buildx-action@v3
2631
@@ -31,32 +36,84 @@ jobs:
3136 username : ${{ github.actor }}
3237 password : ${{ secrets.GITHUB_TOKEN }}
3338
34- - name : Produce the build image tag
35- id : build-meta
39+ - id : build-meta
40+ name : Docker meta
41+ uses : docker/metadata-action@v5
42+ with :
43+ images : ghcr.io/${{ github.repository }}
44+ tags : type=sha,suffix=${{ env.BUILD_SUFFIX }}
45+
46+ # Build cache is shared among all builds of the same architecture
47+ - id : cache-meta
48+ name : Docker meta
3649 uses : docker/metadata-action@v5
3750 with :
3851 images : ghcr.io/${{ github.repository }}
39- tags : type=sha,suffix=-build- ${{ github.run_id }}_${{ github.run_attempt }}
52+ tags : type=raw,value=buildcache- ${{ runner.arch }}
4053
41- - name : Build and push the untested image
54+ - id : get-registry
55+ name : Get the sanitized registry name
56+ run : |
57+ echo "registry=$(echo '${{ steps.build-meta.outputs.tags }}' | cut -f1 -d:)" | tee -a "$GITHUB_OUTPUT"
58+
59+ - id : build
60+ name : Build/push the arch-specific image
4261 uses : docker/build-push-action@v6
4362 with :
44- cache-from : type=gha
45- cache-to : type=gha
63+ cache-from : type=registry,ref=${{ steps.cache-meta.outputs.tags }}
64+ cache-to : type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max
4665 labels : ${{ steps.build-meta.outputs.labels }}
47- platforms : linux/amd64,linux/arm64
48- provenance : true
49- push : true
66+ provenance : mode=max
5067 sbom : true
51- tags : ${{ steps.build-meta.outputs.tags }}
68+ tags : ${{ steps.get-registry.outputs.registry }}
69+ outputs : type=image,push-by-digest=true,push=true
70+
71+ - id : gen-output
72+ name : Write arch-specific image digest to outputs
73+ run : |
74+ echo "image-${RUNNER_ARCH,,}=${{ steps.get-registry.outputs.registry }}@${{ steps.build.outputs.digest }}" | tee -a "$GITHUB_OUTPUT"
75+
76+ merge :
77+ runs-on : ubuntu-24.04
78+ needs : build
79+ env :
80+ DOCKER_APP_IMAGE_ARM64 : ${{ needs.build.outputs.image-arm64 }}
81+ DOCKER_APP_IMAGE_X64 : ${{ needs.build.outputs.image-x64 }}
82+ outputs :
83+ image : ${{ steps.meta.outputs.tags }}
84+ steps :
85+ - name : Checkout code
86+ uses : actions/checkout@v4
87+
88+ - name : Set up Docker Buildx
89+ uses : docker/setup-buildx-action@v3
90+
91+ - name : Login to GitHub Container Registry
92+ uses : docker/login-action@v3
93+ with :
94+ registry : ghcr.io
95+ username : ${{ github.actor }}
96+ password : ${{ secrets.GITHUB_TOKEN }}
97+
98+ - id : meta
99+ name : Generate tag for the app image
100+ uses : docker/metadata-action@v5
101+ with :
102+ images : ghcr.io/${{ github.repository }}
103+ tags : type=sha,suffix=${{ env.BUILD_SUFFIX }}
104+
105+ - name : Push the multi-platform app image
106+ run : |
107+ docker buildx imagetools create \
108+ --tag "$DOCKER_METADATA_OUTPUT_TAGS" \
109+ "$DOCKER_APP_IMAGE_ARM64" "$DOCKER_APP_IMAGE_X64"
52110
53111 test :
54- runs-on : ubuntu-latest
55- needs :
56- - build
112+ runs-on : ubuntu-24.04
113+ needs : merge
57114 env :
58115 COMPOSE_FILE : docker-compose.yml:docker-compose.ci.yml
59- DOCKER_APP_IMAGE : ${{ needs.build .outputs.build- image }}
116+ DOCKER_APP_IMAGE : ${{ needs.merge .outputs.image }}
60117 steps :
61118 - name : Checkout code
62119 uses : actions/checkout@v4
@@ -71,18 +128,21 @@ jobs:
71128 username : ${{ github.actor }}
72129 password : ${{ secrets.GITHUB_TOKEN }}
73130
74- - name : Run the test script
131+ - name : Setup the stack
75132 run : |
76133 docker compose up --wait
134+
135+ - name : Run test script
136+ run : |
77137 docker compose exec app test/test.sh
78138
79139 push :
80- runs-on : ubuntu-latest
140+ runs-on : ubuntu-24.04
81141 needs :
82- - build
142+ - merge
83143 - test
84144 env :
85- DOCKER_APP_IMAGE : ${{ needs.build .outputs.build- image }}
145+ DOCKER_APP_IMAGE : ${{ needs.merge .outputs.image }}
86146 steps :
87147 - name : Checkout code
88148 uses : actions/checkout@v4
95155 password : ${{ secrets.GITHUB_TOKEN }}
96156
97157 - name : Produce permanent image tags
98- id : branch-meta
99158 uses : docker/metadata-action@v5
100159 with :
101160 images : ghcr.io/${{ github.repository }}
0 commit comments