Skip to content

Commit a0ae0cc

Browse files
committed
Try digest approach from Docker docs
1 parent cb63f8b commit a0ae0cc

File tree

1 file changed

+104
-7
lines changed

1 file changed

+104
-7
lines changed

.github/workflows/ci-pipeline.yml

Lines changed: 104 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ jobs:
5252
run: |
5353
docker run --rm ${{ env.TEST_TAG }} make ci-test
5454
55+
# Inspired to https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
5556
build-arch:
5657
runs-on: ${{ matrix.arch.runner }}
5758
needs: test
@@ -64,9 +65,9 @@ jobs:
6465
strategy:
6566
matrix:
6667
arch:
67-
- platform: "amd64"
68+
- platform: linux/amd64
6869
runner: ubuntu-latest
69-
- platform: "arm64"
70+
- platform: linux/arm64
7071
# There is no latest for ARM yet
7172
# https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
7273
runner: ubuntu-24.04-arm
@@ -77,11 +78,14 @@ jobs:
7778
# - dramatiq
7879
steps:
7980
# GitHub gives only repository complete in <owner>/<repo> format.
80-
# Need some manual sheanigans
81+
# Need some manual shenanigans
8182
# Set IMAGE_NAME so we can push to <owner>/<repo>/<image>
83+
# Transform os/arch to os-arch for suffix target
8284
- name: Set ENV variables
8385
run: |
8486
echo "IMAGE_NAME=${GITHUB_REPOSITORY#$GITHUB_REPOSITORY_OWNER/}" >> $GITHUB_ENV
87+
platform=${{ matrix.platform }}
88+
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
8589
8690
- name: Checkout repository
8791
uses: actions/checkout@v4
@@ -115,23 +119,116 @@ jobs:
115119
${{ env.REGISTRY }}/${{ env.REGISTRY_PATH }}/${{ env.IMAGE_NAME }}-${{ matrix.docker_target }}
116120
# generate Docker tags based on the following events/attributes
117121
tags: |
118-
type=sha,suffix=${{ matrix.arch.platform }}
122+
type=sha,suffix=-${{ env.PLATFORM_PAIR }}
119123
120-
# Build and push Docker image with Buildx
124+
# Build and push Docker image with Buildx by digest
121125
# https://github.com/docker/build-push-action
122126
- name: Build and push production image
123127
id: build-and-push
124128
uses: docker/[email protected]
125129
with:
126130
context: .
127131
target: ${{ matrix.docker_target }}
128-
platforms: linux/${{ matrix.arch.platform }}
129-
push: true
132+
platforms: ${{ matrix.arch.platform }}
133+
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
130134
tags: ${{ steps.meta.outputs.tags }}
131135
labels: ${{ steps.meta.outputs.labels }}
132136
cache-from: type=gha
133137
cache-to: type=gha,mode=max
134138

139+
- name: Export digest
140+
run: |
141+
mkdir -p ${{ runner.temp }}/digests/${{ matrix.docker_target }}
142+
digest="${{ steps.build.outputs.digest }}"
143+
touch "${{ runner.temp }}/digests/${{ matrix.docker_target }}/${digest#sha256:}"
144+
145+
- name: Upload digest
146+
uses: actions/upload-artifact@v4
147+
with:
148+
name: digests-${{ env.PLATFORM_PAIR }}
149+
path: ${{ runner.temp }}/digests/*
150+
if-no-files-found: error
151+
retention-days: 1
152+
153+
154+
aggregate-manifests:
155+
runs-on: ubuntu-latest
156+
needs: build-arch
157+
permissions:
158+
contents: read
159+
packages: write
160+
# This is used to complete the identity challenge
161+
# with sigstore/fulcio when running outside of PRs.
162+
id-token: write
163+
strategy:
164+
matrix:
165+
docker_target:
166+
# - migrations
167+
- http
168+
# - socketio
169+
# - dramatiq
170+
171+
steps:
172+
# GitHub gives only repository complete in <owner>/<repo> format.
173+
# Need some manual sheanigans
174+
# Set IMAGE_NAME so we can push to <owner>/<repo>/<image>
175+
- name: Set ENV variables
176+
run: |
177+
echo "IMAGE_NAME=${GITHUB_REPOSITORY#$GITHUB_REPOSITORY_OWNER/}" >> $GITHUB_ENV
178+
179+
- name: Download digests
180+
uses: actions/download-artifact@v4
181+
with:
182+
path: ${{ runner.temp }}/digests/${{ matrix.docker_target }}
183+
pattern: digests-*
184+
merge-multiple: true
185+
186+
- name: Checkout repository
187+
uses: actions/checkout@v4
188+
189+
# Install the cosign tool
190+
# https://github.com/sigstore/cosign-installer
191+
- name: Install cosign
192+
uses: sigstore/[email protected]
193+
194+
- name: Setup Docker buildx
195+
uses: docker/[email protected]
196+
197+
# Login against a Docker registry
198+
# https://github.com/docker/login-action
199+
- name: Log into registry ${{ env.REGISTRY }}
200+
uses: docker/[email protected]
201+
with:
202+
registry: ${{ env.REGISTRY }}
203+
username: ${{ github.actor }}
204+
password: ${{ secrets.GITHUB_TOKEN }}
205+
206+
# Extract metadata (tags, labels) for Docker
207+
# https://github.com/docker/metadata-action
208+
- name: Extract Docker metadata
209+
id: meta
210+
uses: docker/[email protected]
211+
with:
212+
# list of Docker images to use as base name for tags
213+
# <registry/<owner>/<repo_name>/<repo_name>-<target>
214+
images: |
215+
${{ env.REGISTRY }}/${{ env.REGISTRY_PATH }}/${{ env.IMAGE_NAME }}-${{ matrix.docker_target }}
216+
# generate Docker tags based on the following events/attributes
217+
tags: |
218+
type=sha
219+
type=raw,value={{branch}}-latest
220+
type=raw,value={{branch}}-{{date 'YYYYMMDDHHmmss'}}
221+
222+
- name: Create manifest list and push
223+
working-directory: ${{ runner.temp }}/digests
224+
run: |
225+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
226+
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
227+
228+
- name: Inspect image
229+
run: |
230+
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
231+
135232
#TODO: Implement signature using generated key: https://docs.sigstore.dev/signing/quickstart/#signing-with-a-generated-key
136233

137234
# Sign the resulting Docker image digest except on PRs.

0 commit comments

Comments
 (0)