forked from DSpace/DSpace
-
Notifications
You must be signed in to change notification settings - Fork 2
239 lines (217 loc) · 9.53 KB
/
reusable-docker-build.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#
# DSpace's reusable Docker build/push workflow.
#
# This is used by docker.yml for all Docker image builds
name: Reusable DSpace Docker Build
on:
workflow_call:
# Possible Inputs to this reusable job
inputs:
python_version_script_dest:
required: false
default: version.txt
type: string
run_python_version_script:
required: false
default: false
type: boolean
# Build name/id for this Docker build. Used for digest storage to avoid digest overlap between builds.
build_id:
required: true
type: string
# Requires the image name to build (e.g dspace/dspace-test)
image_name:
required: true
type: string
# Optionally the path to the Dockerfile to use for the build. (Default is [dockerfile_context]/Dockerfile)
dockerfile_path:
required: false
type: string
# Optionally the context directory to build the Dockerfile within. Defaults to "." (current directory)
dockerfile_context:
required: false
type: string
default: '.'
# Optionally a list of "additional_contexts" to pass to Dockerfile. Defaults to empty
dockerfile_additional_contexts:
required: false
type: string
default: ''
# If Docker image should have additional tag flavor details (e.g. a suffix), it may be passed in.
tags_flavor:
required: false
type: string
secrets:
# Requires that Docker login info be passed in as secrets.
DOCKER_USERNAME:
required: true
DOCKER_ACCESS_TOKEN:
required: true
# These URL secrets are optional. When specified & branch checks match, the redeployment code below will trigger.
# Therefore builds which need to trigger redeployment MUST specify these URLs. All others should leave them empty.
REDEPLOY_SANDBOX_URL:
required: false
REDEPLOY_DEMO_URL:
required: false
# Define shared default settings as environment variables
env:
IMAGE_NAME: ${{ inputs.image_name }}
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
# For a new commit on default branch (main), use the literal tag 'latest' on Docker image.
# For a new commit on other branches, use the branch name as the tag for Docker image.
# For a new tag, copy that tag name as the tag for Docker image.
IMAGE_TAGS: |
type=raw,value=dspace-7_x,enable=${{ github.ref_name == github.event.repository.default_branch }}
type=raw,value=${{ github.sha }}
type=ref,event=branch,enable=${{ github.ref_name != github.event.repository.default_branch }}
type=ref,event=tag
# Define default tag "flavor" for docker/metadata-action per
# https://github.com/docker/metadata-action#flavor-input
# We manage the 'latest' tag ourselves to the 'main' branch (see settings above)
TAGS_FLAVOR: |
latest=false
${{ inputs.tags_flavor }}
# When these URL variables are specified & required branch matches, then the sandbox or demo site will be redeployed.
# See "Redeploy" steps below for more details.
REDEPLOY_SANDBOX_URL: ${{ secrets.REDEPLOY_SANDBOX_URL }}
REDEPLOY_DEMO_URL: ${{ secrets.REDEPLOY_DEMO_URL }}
# Current DSpace maintenance branch (and architecture) which is deployed to demo.dspace.org / sandbox.dspace.org
# (NOTE: No deployment branch specified for sandbox.dspace.org as it uses the default_branch)
DEPLOY_DEMO_BRANCH: 'dspace-7_x'
DEPLOY_ARCH: 'linux/amd64'
jobs:
docker-build:
strategy:
matrix:
# Architectures / Platforms for which we will build Docker images
# arch: [ 'linux/amd64', 'linux/arm64' ]
arch: [ 'linux/amd64' ]
os: [ ubuntu-latest ]
isPr:
- ${{ github.event_name == 'pull_request' }}
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work.
# The below exclude therefore ensures we do NOT build ARM64 for PRs.
# exclude:
# - isPr: true
# os: ubuntu-latest
# arch: linux/arm64
runs-on: ${{ matrix.os }}
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v4
- name: Add version
if: ${{ inputs.run_python_version_script }}
run: python scripts/sourceversion.py ${{ github.server_url }}/${{ github.repository }}/actions/runs/ ${{ github.run_id }} > ${{ inputs.python_version_script_dest }}
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU emulation to build for multiple architectures
uses: docker/setup-qemu-action@v3
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: ${{ ! matrix.isPr }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
# https://github.com/docker/metadata-action
# Get Metadata for docker_build_deps step below
- name: Sync metadata (tags, labels) from GitHub to Docker for image
id: meta_build
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_NAME }}
tags: ${{ env.IMAGE_TAGS }}
flavor: ${{ env.TAGS_FLAVOR }}
# https://github.com/docker/build-push-action
- name: Build and push image
id: docker_build
uses: docker/build-push-action@v5
with:
build-contexts: |
${{ inputs.dockerfile_additional_contexts }}
context: ${{ inputs.dockerfile_context }}
file: ${{ inputs.dockerfile_path }}
platforms: ${{ matrix.arch }}
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
# but we ONLY do an image push to DockerHub if it's NOT a PR
push: ${{ ! matrix.isPr }}
# Use tags / labels provided by 'docker/metadata-action' above
tags: ${{ steps.meta_build.outputs.tags }}
labels: ${{ steps.meta_build.outputs.labels }}
# Export the digest of Docker build locally (for non PRs only)
# - name: Export Docker build digest
# if: ${{ ! matrix.isPr }}
# run: |
# mkdir -p /tmp/digests
# digest="${{ steps.docker_build.outputs.digest }}"
# touch "/tmp/digests/${digest#sha256:}"
# Upload digest to an artifact, so that it can be used in manifest below
# - name: Upload Docker build digest to artifact
# if: ${{ ! matrix.isPr }}
# uses: actions/upload-artifact@v3
# with:
# name: digests-${{ inputs.build_id }}
# path: /tmp/digests/*
# if-no-files-found: error
# retention-days: 1
# If this build is NOT a PR and passed in a REDEPLOY_SANDBOX_URL secret,
# Then redeploy https://sandbox.dspace.org if this build is for our deployment architecture and 'main' branch.
# - name: Redeploy sandbox.dspace.org (based on main branch)
# if: |
# !matrix.isPR &&
# env.REDEPLOY_SANDBOX_URL != '' &&
# matrix.arch == env.DEPLOY_ARCH &&
# github.ref_name == github.event.repository.default_branch
# run: |
# curl -X POST $REDEPLOY_SANDBOX_URL
# If this build is NOT a PR and passed in a REDEPLOY_DEMO_URL secret,
# Then redeploy https://demo.dspace.org if this build is for our deployment architecture and demo branch.
# - name: Redeploy demo.dspace.org (based on maintenace branch)
# if: |
# !matrix.isPR &&
# env.REDEPLOY_DEMO_URL != '' &&
# matrix.arch == env.DEPLOY_ARCH &&
# github.ref_name == env.DEPLOY_DEMO_BRANCH
# run: |
# curl -X POST $REDEPLOY_DEMO_URL
# Merge Docker digests (from various architectures) into a manifest.
# This runs after all Docker builds complete above, and it tells hub.docker.com
# that these builds should be all included in the manifest for this tag.
# (e.g. AMD64 and ARM64 should be listed as options under the same tagged Docker image)
# docker-build_manifest:
# if: ${{ github.event_name != 'pull_request' }}
# runs-on: ubuntu-latest
# needs:
# - docker-build
# steps:
# - name: Download Docker build digests
# uses: actions/download-artifact@v3
# with:
# name: digests-${{ inputs.build_id }}
# path: /tmp/digests
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
# - name: Add Docker metadata for image
# id: meta
# uses: docker/metadata-action@v5
# with:
# images: ${{ env.IMAGE_NAME }}
# tags: ${{ env.IMAGE_TAGS }}
# flavor: ${{ env.TAGS_FLAVOR }}
# - name: Login to Docker Hub
# uses: docker/login-action@v3
# with:
# username: ${{ secrets.DOCKER_USERNAME }}
# password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
# - name: Create manifest list from digests and push
# working-directory: /tmp/digests
# run: |
# docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
# $(printf '${{ env.IMAGE_NAME }}@sha256:%s ' *)
# - name: Inspect image
# run: |
# docker buildx imagetools inspect ${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}