-
Notifications
You must be signed in to change notification settings - Fork 52
192 lines (162 loc) · 7.51 KB
/
worker-images.yml
File metadata and controls
192 lines (162 loc) · 7.51 KB
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
name: Build Worker Images
on:
push:
branches:
- main
- 'releases/*'
tags:
- 'v[0-9]+.[0-9]+.*'
pull_request:
branches:
- main
paths:
- '.github/workflows/worker-images/matrix.json'
- '.github/workflows/worker-images.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
load-matrix:
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
runs-on: ubuntu-22.04
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set matrix
id: set-matrix
run: |
MATRIX=$(cat .github/workflows/worker-images/matrix.json)
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
build-worker-images:
permissions:
packages: write
id-token: write # Required for cosign OIDC signing
attestations: write # Required for GitHub attestations
needs: load-matrix
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1
with:
egress-policy: audit
allowed-endpoints: >
api.github.com:443
fulcio.sigstore.dev:443
ghcr.io:443
github.com:443
*.githubusercontent.com:443
proxy.golang.org:443
rekor.sigstore.dev:443
storage.googleapis.com:443
tuf-repo-cdn.sigstore.dev:443
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Cosign
if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch' }}
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
name: Login to GHCR
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/enable-containerd
- name: Setup environment
run: |
echo MAIN_CACHE_SCOPE=main.${{ matrix.target }} >> $GITHUB_ENV
tag="${{ github.ref_name }}"
tag="${tag//\//-}" # Replace slashes with dashes
tag="${tag%.*}" # Trim off patch version if it exists
# Format repository name (lowercase)
FORMATTED_REPO=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
BASE_REPO="${FORMATTED_REPO}/${{ matrix.target }}"
echo "BASE_REPO=${BASE_REPO}" >> $GITHUB_ENV
echo "IMAGE_REPO=${BASE_REPO}:${tag}" >> $GITHUB_ENV
- if: ${{ github.event_name == 'pull_request' }}
name: Setup up (PR)
run: |
set -eux
# Here we try to build this as much like a release as possible, but we push to a local registry
ref="localhost:5000/${IMAGE_REPO}"
EXTRA_FLAGS="--set worker.cache-from=type=gha,scope=${MAIN_CACHE_SCOPE} --set worker.tags=${ref} --push"
# Because we sometimes add an extra ref for ":latest", let's also do that here to validate that it works
EXTRA_FLAGS+=" --set worker.tags=${ref}-latest"
echo "EXTRA_FLAGS=${EXTRA_FLAGS}" >> $GITHUB_ENV
# Format repository name (lowercase) for registry mirror
FORMATTED_REPO=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
docker run -d --net=host ghcr.io/${FORMATTED_REPO}/mirror/dockerhub/library/registry:latest
- if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch' }}
name: Setup (tagged)
env:
GH_TOKEN: ${{ github.token }}
run: |
set -eux
ref="ghcr.io/${IMAGE_REPO}"
# Don't need to care about cache-from in this case as this is the "prod" image, better to build it from scratch
# Inline the cache with the image so others can use it as a cache-from for their own builds.
EXTRA_FLAGS="--set worker.cache-to=type=inline,mode=max --set worker.tags=${ref} --push"
latest="$(gh release view --json tagName -q .tagName)"
if [ ${{ github.ref_name }} = "${latest}" ]; then
# If this is the latest release, we also tag it as "latest"
IMAGE_REPO_LATEST="${BASE_REPO}:latest"
EXTRA_FLAGS+=" --set worker.tags=ghcr.io/${IMAGE_REPO_LATEST}"
fi
echo "EXTRA_FLAGS=${EXTRA_FLAGS}" >> $GITHUB_ENV
- if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/heads/') }}
name: Setup (merged)
run: |
set -ex -o pipefail
EXTRA_FLAGS="--set worker.cache-to=type=gha,scope=main.${{matrix.target}},mode=max --set worker.cache-from=type=gha,scope=${MAIN_CACHE_SCOPE}"
echo "EXTRA_FLAGS=${EXTRA_FLAGS}" >> $GITHUB_ENV
- name: Setup QEMU
run: docker run --rm --privileged tonistiigi/binfmt:latest --install all
- name: Expose GitHub tokens for caching
uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3.1.0
- name: Build worker images
run: |
set -eux
docker buildx bake worker \
--set worker.platform=linux/amd64,linux/arm64 \
${EXTRA_FLAGS}
env:
WORKER_TARGET: ${{ matrix.target }}
- name: Sign and attest worker images
if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch' }}
id: sign
env:
GH_TOKEN: ${{ github.token }}
run: |
set -eux
ref="ghcr.io/${IMAGE_REPO}"
# Get the digest of the pushed image
DIGEST=$(docker buildx imagetools inspect ${ref} --format '{{json .Manifest.Digest}}' | tr -d '"')
# Sign the image
cosign sign --yes "${ref}@${DIGEST}"
# Verify the signature
cosign verify "${ref}@${DIGEST}" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity "https://github.com/${{ github.repository }}/.github/workflows/worker-images.yml@${{ github.ref }}"
# If there's a latest tag, sign that too
latest="$(gh release view --json tagName -q .tagName || echo '')"
if [ "${{ github.ref_name }}" = "${latest}" ]; then
IMAGE_REPO_LATEST="${BASE_REPO}:latest"
ref_latest="ghcr.io/${IMAGE_REPO_LATEST}"
cosign sign --yes "${ref_latest}@${DIGEST}"
fi
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
echo "image-name=ghcr.io/${BASE_REPO}" >> $GITHUB_OUTPUT
- name: Attest build provenance
if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch' }}
uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v2.0.0
with:
subject-name: ${{ steps.sign.outputs.image-name }}
subject-digest: ${{ steps.sign.outputs.digest }}
push-to-registry: true