Skip to content

Commit 394dc67

Browse files
committed
Setup the Docker GH Action for Matrix Building
This change enables building of the amd64 and arm64 images simultaneously. Once both images finish, the manifest is sent to Docker Hub, allowing for a single image that has both the amd64/arm64 images.
1 parent cb70190 commit 394dc67

1 file changed

Lines changed: 153 additions & 20 deletions

File tree

.github/workflows/docker.yml

Lines changed: 153 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ permissions:
1717

1818

1919
env:
20+
REGISTRY_IMAGE: dspace/dspace-angular
2021
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
2122
# For a new commit on default branch (main), use the literal tag 'latest' on Docker image.
2223
# For a new commit on other branches, use the branch name as the tag for Docker image.
@@ -30,21 +31,30 @@ env:
3031
# We manage the 'latest' tag ourselves to the 'main' branch (see settings above)
3132
TAGS_FLAVOR: |
3233
latest=false
33-
# Architectures / Platforms for which we will build Docker images
34-
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
35-
# If this is NOT a PR (e.g. a tag or merge commit), also build for ARM64.
36-
PLATFORMS: linux/amd64${{ github.event_name != 'pull_request' && ', linux/arm64' || '' }}
37-
3834
3935
jobs:
40-
###############################################
41-
# Build/Push the 'dspace/dspace-angular' image
42-
###############################################
36+
#############################################################
37+
# Build/Push the '${{ env.REGISTRY_IMAGE }}' image
38+
#############################################################
4339
dspace-angular:
4440
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular'
4541
if: github.repository == 'dspace/dspace-angular'
46-
runs-on: ubuntu-latest
4742

43+
strategy:
44+
matrix:
45+
isPr:
46+
- ${{ github.event_name == 'pull_request' }}
47+
# Architectures / Platforms for which we will build Docker images
48+
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
49+
# If this is NOT a PR (e.g. a tag or merge commit), also build for ARM64.
50+
arch: ['linux/amd64', 'linux/arm64']
51+
os: [ubuntu-latest]
52+
exclude:
53+
- isPr: true
54+
os: ubuntu-latest
55+
arch: linux/arm64
56+
57+
runs-on: ${{ matrix.os }}
4858
steps:
4959
# https://github.com/actions/checkout
5060
- name: Checkout codebase
@@ -61,7 +71,7 @@ jobs:
6171
# https://github.com/docker/login-action
6272
- name: Login to DockerHub
6373
# Only login if not a PR, as PRs only trigger a Docker build and not a push
64-
if: github.event_name != 'pull_request'
74+
if: ${{ ! matrix.isPr }}
6575
uses: docker/login-action@v2
6676
with:
6777
username: ${{ secrets.DOCKER_USERNAME }}
@@ -73,7 +83,7 @@ jobs:
7383
id: meta_build
7484
uses: docker/metadata-action@v4
7585
with:
76-
images: dspace/dspace-angular
86+
images: ${{ env.REGISTRY_IMAGE }}
7787
tags: ${{ env.IMAGE_TAGS }}
7888
flavor: ${{ env.TAGS_FLAVOR }}
7989

@@ -84,22 +94,89 @@ jobs:
8494
with:
8595
context: .
8696
file: ./Dockerfile
87-
platforms: ${{ env.PLATFORMS }}
97+
platforms: ${{ matrix.arch }}
8898
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
8999
# but we ONLY do an image push to DockerHub if it's NOT a PR
90-
push: ${{ github.event_name != 'pull_request' }}
100+
push: ${{ ! matrix.isPr }}
91101
# Use tags / labels provided by 'docker/metadata-action' above
92102
tags: ${{ steps.meta_build.outputs.tags }}
93103
labels: ${{ steps.meta_build.outputs.labels }}
94104

105+
- name: Export digest
106+
if: ${{ ! matrix.isPr }}
107+
run: |
108+
mkdir -p /tmp/digests
109+
digest="${{ steps.docker_build.outputs.digest }}"
110+
touch "/tmp/digests/${digest#sha256:}"
111+
112+
- name: Upload digest
113+
if: ${{ ! matrix.isPr }}
114+
uses: actions/upload-artifact@v3
115+
with:
116+
name: digests
117+
path: /tmp/digests/*
118+
if-no-files-found: error
119+
retention-days: 1
120+
121+
merge:
122+
if: ${{ github.event_name != 'pull_request' }}
123+
runs-on: ubuntu-latest
124+
needs:
125+
- dspace-angular
126+
steps:
127+
- name: Download digests
128+
uses: actions/download-artifact@v3
129+
with:
130+
name: digests
131+
path: /tmp/digests
132+
- name: Set up Docker Buildx
133+
uses: docker/setup-buildx-action@v3
134+
- name: Docker meta
135+
id: meta
136+
uses: docker/metadata-action@v5
137+
with:
138+
images: ${{ env.REGISTRY_IMAGE }}
139+
tags: ${{ env.IMAGE_TAGS }}
140+
flavor: ${{ env.TAGS_FLAVOR }}
141+
142+
- name: Login to Docker Hub
143+
uses: docker/login-action@v3
144+
with:
145+
username: ${{ secrets.DOCKER_USERNAME }}
146+
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
147+
148+
- name: Create manifest list and push
149+
working-directory: /tmp/digests
150+
run: |
151+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
152+
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
153+
154+
- name: Inspect image
155+
run: |
156+
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
157+
95158
#############################################################
96-
# Build/Push the 'dspace/dspace-angular' image ('-dist' tag)
159+
# Build/Push the '${{ env.REGISTRY_IMAGE }}' image ('-dist' tag)
97160
#############################################################
98161
dspace-angular-dist:
99162
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular'
100163
if: github.repository == 'dspace/dspace-angular'
101-
runs-on: ubuntu-latest
102164

165+
strategy:
166+
matrix:
167+
isPr:
168+
- ${{ github.event_name == 'pull_request' }}
169+
# Architectures / Platforms for which we will build Docker images
170+
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
171+
# If this is NOT a PR (e.g. a tag or merge commit), also build for ARM64.
172+
arch: ['linux/amd64', 'linux/arm64']
173+
os: [ubuntu-latest]
174+
exclude:
175+
- isPr: true
176+
os: ubuntu-latest
177+
arch: linux/arm64
178+
179+
runs-on: ${{ matrix.os }}
103180
steps:
104181
# https://github.com/actions/checkout
105182
- name: Checkout codebase
@@ -116,7 +193,7 @@ jobs:
116193
# https://github.com/docker/login-action
117194
- name: Login to DockerHub
118195
# Only login if not a PR, as PRs only trigger a Docker build and not a push
119-
if: github.event_name != 'pull_request'
196+
if: ${{ ! matrix.isPr }}
120197
uses: docker/login-action@v2
121198
with:
122199
username: ${{ secrets.DOCKER_USERNAME }}
@@ -128,10 +205,10 @@ jobs:
128205
id: meta_build_dist
129206
uses: docker/metadata-action@v4
130207
with:
131-
images: dspace/dspace-angular
208+
images: ${{ env.REGISTRY_IMAGE }}
132209
tags: ${{ env.IMAGE_TAGS }}
133210
# As this is a "dist" image, its tags are all suffixed with "-dist". Otherwise, it uses the same
134-
# tagging logic as the primary 'dspace/dspace-angular' image above.
211+
# tagging logic as the primary '${{ env.REGISTRY_IMAGE }}' image above.
135212
flavor: ${{ env.TAGS_FLAVOR }}
136213
suffix=-dist
137214

@@ -141,10 +218,66 @@ jobs:
141218
with:
142219
context: .
143220
file: ./Dockerfile.dist
144-
platforms: ${{ env.PLATFORMS }}
221+
platforms: ${{ matrix.arch }}
145222
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
146223
# but we ONLY do an image push to DockerHub if it's NOT a PR
147-
push: ${{ github.event_name != 'pull_request' }}
224+
push: ${{ ! matrix.isPr }}
148225
# Use tags / labels provided by 'docker/metadata-action' above
149226
tags: ${{ steps.meta_build_dist.outputs.tags }}
150227
labels: ${{ steps.meta_build_dist.outputs.labels }}
228+
229+
- name: Export digest
230+
if: ${{ ! matrix.isPr }}
231+
run: |
232+
mkdir -p /tmp/digests/dist
233+
digest="${{ steps.docker_build_dist.outputs.digest }}"
234+
touch "/tmp/digests/dist/${digest#sha256:}"
235+
236+
- name: Upload digest
237+
if: ${{ ! matrix.isPr }}
238+
uses: actions/upload-artifact@v3
239+
with:
240+
name: digests
241+
path: /tmp/digests/dist/*
242+
if-no-files-found: error
243+
retention-days: 1
244+
245+
merge-dist:
246+
if: ${{ github.event_name != 'pull_request' }}
247+
runs-on: ubuntu-latest
248+
needs:
249+
- dspace-angular-dist
250+
steps:
251+
- name: Download digests
252+
uses: actions/download-artifact@v3
253+
with:
254+
name: digests
255+
path: /tmp/digests
256+
- name: Set up Docker Buildx
257+
uses: docker/setup-buildx-action@v3
258+
- name: Docker meta
259+
id: meta_dist
260+
uses: docker/metadata-action@v5
261+
with:
262+
images: ${{ env.REGISTRY_IMAGE }}
263+
tags: ${{ env.IMAGE_TAGS }}
264+
# As this is a "dist" image, its tags are all suffixed with "-dist". Otherwise, it uses the same
265+
# tagging logic as the primary '${{ env.REGISTRY_IMAGE }}' image above.
266+
flavor: ${{ env.TAGS_FLAVOR }}
267+
suffix=-dist
268+
269+
- name: Login to Docker Hub
270+
uses: docker/login-action@v3
271+
with:
272+
username: ${{ secrets.DOCKER_USERNAME }}
273+
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
274+
275+
- name: Create manifest list and push
276+
working-directory: /tmp/digests/dist
277+
run: |
278+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
279+
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
280+
281+
- name: Inspect image
282+
run: |
283+
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta_dist.outputs.version }}

0 commit comments

Comments
 (0)