-
Notifications
You must be signed in to change notification settings - Fork 336
356 lines (299 loc) · 12.5 KB
/
windows.yaml
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
#
# This workflow builds base and python-version-specific docker images if
# required, then runs the rez tests in the python image.
#
# The images are tagged with a hash of the relevant sourcefile contents (eg
# Dockerfile). Images from the 'AcademySoftwareFoundation/rez' GitHub container registry will be used
# if they are up-to-date.
#
# If images require updating, the necessary images will be
# created and will be stored in the GitHub Container registry. The images
# will always be stored in the current's repo namespace (ghcr.io/<user>/<repo>).
#
# This approach ensures that image rebuilds are avoided when possible, but are
# supported from forks who may have made changes to docker-related
# source (such as Dockerfile) and need this workflow to run.
#
---
name: windows
on:
pull_request:
paths:
- 'src/**'
- '.github/workflows/windows.yaml'
- '.github/docker/rez-win-base/**'
- '.github/docker/rez-win-py/**'
- '!src/rez/utils/_version.py'
- '!**.md'
push:
paths:
- 'src/**'
- '.github/workflows/windows.yaml'
- '.github/docker/rez-win-base/**'
- '.github/docker/rez-win-py/**'
- '!src/rez/utils/_version.py'
- '!**.md'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
# The default namespace that the jobs will look at or use.
PUB_NAMESPACE: ghcr.io/academysoftwarefoundation/rez
# We don't take changes to this workfile yaml into account when determining
# image tags, because changes here very rarely cause changes to the images,
# and this causes lots of unnecessary image rebuilds. On the offchance a
# change is made here that _does_ affect the images, increment this value
IMAGE_TAG_SALT: 3
jobs:
# image tags are based on sourcefile contents
image_tags:
name: Calculate image tags
runs-on: ubuntu-latest
outputs:
base: ${{ steps.base.outputs.tag }}
py: ${{ steps.py.outputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Determine base image tag
id: base
run: |
tag=$( \
echo "${{ hashFiles('.github/docker/rez-win-base/*') }}${IMAGE_TAG_SALT}" \
| md5sum - \
| awk '{print $1}' \
)
echo "base tag is ${tag}"
echo "::set-output name=tag::${tag}"
- name: Determine python image tag
id: py
run: |
tag=$( \
echo "${{ hashFiles('.github/docker/rez-win-base/*', '.github/docker/rez-win-py/*') }}${IMAGE_TAG_SALT}" \
| md5sum - \
| awk '{print $1}' \
)
echo "py tag is ${tag}"
echo "::set-output name=tag::${tag}"
# note that we don't track staleness on a per-matrix-entry basis. Github actions
# job outputs wrt matrix is problematic and frankly not worth the hassle.
public_py_image:
name: Check for up-to-date public py image
runs-on: windows-${{ matrix.os-version }}
needs: image_tags
strategy:
fail-fast: false
matrix:
os-version:
- '2019'
py-version:
- '2.7.17'
- '3.7.5'
outputs:
namespace: ${{ steps.inspect.outputs.namespace }}
needs_rebuild: ${{ steps.inspect.outputs.needs_rebuild }}
steps:
- name: Inspect public py image
id: inspect
run: |
# Try to get the image from the pub namepsace first.
$pub_namespace = "${Env:PUB_NAMESPACE}"
$docker_image = "${pub_namespace}/rez-win-${{ matrix.os-version }}-py-${{ matrix.py-version }}:${{ needs.image_tags.outputs.py }}".ToLower()
Write-Output "Inspecting image ${docker_image}..."
$ErrorActionPreference = "Continue"
docker manifest inspect $docker_image *>$null || Write-Output "(no such image)"
$ErrorActionPreference = "Stop"
if ($LastExitCode -eq 0) {
Write-Output "Found ${docker_image}"
Write-Output "::set-output name=namespace::${pub_namespace}"
Write-Output "::set-output name=needs_rebuild::false"
}
else {
Write-Output "${docker_image} not found"
# Image not found in pub namespace, look into the current's
# repo registry or in the originating repo when the workflow is
# triggered from a PR.
if ('${{ github.event_name }}' -eq 'pull_request') {
# This is quite important since workflows don't have write
# permissions when the source branch is from a fork.
$github_namespace = "ghcr.io/${{ github.event.pull_request.head.repo.full_name }}"
}
else {
$github_namespace = "ghcr.io/${{ github.repository }}"
}
$docker_image = "${github_namespace}/rez-win-${{ matrix.os-version }}-py-${{ matrix.py-version }}:${{ needs.image_tags.outputs.py }}".ToLower()
Write-Output "Inspecting image ${docker_image}..."
$ErrorActionPreference = "Continue"
docker manifest inspect $docker_image *>$null || Write-Output "(no such image)"
$ErrorActionPreference = "Stop"
# Inform the next jobs that they need to use the "private"
# registry.
Write-Output "::set-output name=namespace::${github_namespace}"
if ($LastExitCode -ne 0) {
# Well, no images found at all! We will need to build the images.
Write-Output "${docker_image} not found"
Write-Output "::set-output name=needs_rebuild::true"
} else {
Write-Output "Found ${docker_image}"
Write-Output "::set-output name=needs_rebuild::false"
}
}
exit 0
base_image:
name: Build base docker image if required
runs-on: windows-${{ matrix.os-version }}
needs:
- image_tags
- public_py_image
if: needs.public_py_image.outputs.needs_rebuild == 'true'
strategy:
fail-fast: false
matrix:
# The windows version has to match the host system.
# 1809 -> 10.0.17763.805 -> windows-2019
# Compare: https://hub.docker.com/_/microsoft-windows-servercore
include:
- os-version: '2019'
windows-version: '1809-amd64'
steps:
- name: Fail with summary
if: (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name != github.repository)
shell: bash
run: |
echo '# Action required!
This branch is coming from a fork and the appropriate docker images were
not found in `${{ needs.public_py_image.outputs.namespace }}`.
Please ensure that you run the workflow in your fork. Once this is done,
please let the reviewers know so that they can re-run the workflow in
the context of the PR.' > $GITHUB_STEP_SUMMARY
exit 1
- name: Set job vars
id: vars
run: |
$docker_image = "${{ needs.public_py_image.outputs.namespace }}/rez-win-${{ matrix.os-version }}-base:${{ needs.image_tags.outputs.base }}".ToLower()
Write-Output "::set-output name=docker_image::${docker_image}"
- name: Login to docker repository
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
- name: Inspect base image
id: inspect
run: |
Write-Output "Inspecting image ${{ steps.vars.outputs.docker_image }}..."
$ErrorActionPreference = "Continue"
docker manifest inspect ${{ steps.vars.outputs.docker_image }} *>$null || Write-Output "(no such image)"
$ErrorActionPreference = "Stop"
if ($LastExitCode -ne 0) {
Write-Output "::set-output name=image_exists::false"
}
exit 0
- name: Checkout
if: steps.inspect.outputs.image_exists == 'false'
uses: actions/checkout@v2
- name: Build base image
if: steps.inspect.outputs.image_exists == 'false'
run: |
Write-Output "Building image ${{ steps.vars.outputs.docker_image }}..."
cd .github\docker\rez-win-base
docker build `
--tag ${{ steps.vars.outputs.docker_image }} `
--build-arg WINDOWS_VERSION="${{ matrix.windows-version }}" `
.
- name: Push base image
if: steps.inspect.outputs.image_exists == 'false'
run: |
Write-Output "Pushing image ${{ steps.vars.outputs.docker_image }}..."
docker push ${{ steps.vars.outputs.docker_image }}
py_image:
name: Build py docker image if required
runs-on: windows-${{ matrix.os-version }}
needs:
- image_tags
- base_image
- public_py_image
strategy:
fail-fast: false
matrix:
os-version:
- '2019'
py-version:
- '2.7.17'
- '3.7.5'
steps:
- name: Set job vars
id: vars
run: |
# When publishing the images, we always publish in the current repo's package registry
$base_docker_image = "ghcr.io/${{ github.repository }}/rez-win-${{ matrix.os-version }}-base:${{ needs.image_tags.outputs.base }}".ToLower()
$docker_image = "ghcr.io/${{ github.repository }}/rez-win-${{ matrix.os-version }}-py-${{ matrix.py-version }}:${{ needs.image_tags.outputs.py }}".ToLower()
Write-Output "::set-output name=base_docker_image::${base_docker_image}"
Write-Output "::set-output name=docker_image::${docker_image}"
- name: Login to docker repository
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
- name: Inspect py image
id: inspect
run: |
Write-Output "Inspecting image ${{ steps.vars.outputs.docker_image }}..."
$ErrorActionPreference = "Continue"
docker manifest inspect ${{ steps.vars.outputs.docker_image }} *>$null || Write-Output "(no such image)"
$ErrorActionPreference = "Stop"
if ($LastExitCode -ne 0) {
Write-Output "::set-output name=image_exists::false"
}
exit 0
- name: Checkout
if: steps.inspect.outputs.image_exists == 'false'
uses: actions/checkout@v2
- name: Pull base image
if: steps.inspect.outputs.image_exists == 'false'
run: |
Write-Output "Pulling base image ${{ steps.vars.outputs.base_docker_image }}..."
docker pull ${{ steps.vars.outputs.base_docker_image }}
- name: Build py image
if: steps.inspect.outputs.image_exists == 'false'
run: |
Write-Output "Building image ${{ steps.vars.outputs.docker_image }}..."
cd .github\docker\rez-win-py
docker build `
--tag ${{ steps.vars.outputs.docker_image }} `
--build-arg BASE_IMAGE_NAME="${{ steps.vars.outputs.base_docker_image }}" `
--build-arg IMAGE_NAME="${{ steps.vars.outputs.docker_image }}" `
--build-arg PYTHON_VERSION="${{ matrix.py-version }}" `
.
- name: Push py image
if: steps.inspect.outputs.image_exists == 'false'
run: |
Write-Output "Pushing image ${{ steps.vars.outputs.docker_image }}..."
docker push ${{ steps.vars.outputs.docker_image }}
main:
name: Run rez tests
runs-on: windows-${{ matrix.os-version }}
needs:
- image_tags
- public_py_image
- py_image
# Forces this job to run even if needed jobs are skipped but not when the workflow is cancelled or failed.
if: (success() || needs.py_image.result == 'skipped') && !cancelled() && !failure()
strategy:
fail-fast: false
matrix:
os-version:
- '2019'
py-version:
- '2.7.17'
- '3.7.5'
steps:
- name: Set job vars
id: vars
run: |
$docker_image = "${{ needs.public_py_image.outputs.namespace }}/rez-win-${{ matrix.os-version }}-py-${{ matrix.py-version }}:${{ needs.image_tags.outputs.py }}".ToLower()
Write-Output "::set-output name=docker_image::${docker_image}"
Write-Output "Using image ${docker_image}..."
- name: Checkout
uses: actions/checkout@v2
- name: Pull py image
run: |
docker pull ${{ steps.vars.outputs.docker_image }}
- name: Run Docker image (installs and tests rez)
run: docker run --mount type=bind,src=$pwd,dst=C:\checkout,readonly ${{ steps.vars.outputs.docker_image }}
env:
_REZ_ENSURE_TEST_SHELLS: cmd,pwsh,gitbash