-
Notifications
You must be signed in to change notification settings - Fork 5
319 lines (285 loc) · 13.6 KB
/
docker-build-publish.yaml
File metadata and controls
319 lines (285 loc) · 13.6 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
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
name: Build and Publish Docker Image
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on:
schedule:
- cron: "0 10 * * *"
# If any commit message in your push or the HEAD commit of your PR contains the strings
# [skip ci], [ci skip], [no ci], [skip actions], or [actions skip]
# workflows triggered on the push or pull_request events will be skipped.
# https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/
push:
branches: [master]
# Publish semver tags as releases.
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
# If any commit message in your push or the HEAD commit of your PR contains the strings
# [skip ci], [ci skip], [no ci], [skip actions], or [actions skip]
# workflows triggered on the push or pull_request events will be skipped.
# https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/
pull_request:
branches: [master]
env:
# https://hub.docker.com/r/athenz/authorization-proxy/tags
DOCKER_REGISTRY_URL: docker.io
DOCKER_REGISTRY_ORG: athenz
DOCKER_REGISTRY_IMAGE: authorization-proxy
# DOCKER_REGISTRY_USER: values for docker login is stored in repository variables
# DOCKER_REGISTRY_TOKEN_NAME: values for docker login is stored in repository variables
TAGS_CONFIG: |
# If branch is master, main or default branch, push the latest tag image:
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
# If the event is a tag release in semver syntax, push the latest tag image:
type=semver,pattern=latest
# If it is PR version, push the pr-<pr-number> tag image:
type=ref,event=pr
type=semver,pattern=v{{version}}
# Any cron builds (scheduled workflows) push the nightly tag image:
type=schedule,pattern=nightly
jobs:
set_matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set.outputs.matrix }}
suffixes: ${{ steps.set.outputs.suffixes }}
steps:
- id: set
run: |
# We define BUILD_MATRIX so that we have multiple platform supported,
# maybe Windows as well in the future:
MATRIX_JSON='{
"include": [
{ "platform": "linux/amd64", "runner": "ubuntu-latest", "suffix": "-amd64" },
{ "platform": "linux/arm64", "runner": "ubuntu-24.04-arm", "suffix": "-arm64" }
]
}'
# Store JSON data:
echo "matrix=$(echo "$MATRIX_JSON" | jq -c .)" >> $GITHUB_OUTPUT
# Store Suffix list:
echo "suffixes=$(echo "$MATRIX_JSON" | jq -r '.include[].suffix' | xargs)" >> $GITHUB_OUTPUT
build:
needs: set_matrix
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.set_matrix.outputs.matrix) }}
permissions:
actions: none
checks: none
contents: read
deployments: none
issues: none
discussions: none
packages: write # for ghcr read permission
pull-requests: none
repository-projects: none
security-events: none
statuses: none
steps:
# A GitHub Action to expose useful environment variables.
# https://github.com/FranzDiebold/github-env-vars-action
- name: GitHub Environment Variables Action
id: env
# uses: https://github.com/FranzDiebold/github-env-vars-action/tags
uses: FranzDiebold/github-env-vars-action@v2
# This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
# https://github.com/actions/checkout
- name: Checkout repository
id: checkout
# You may pin to the exact commit or the version.
# uses: https://github.com/actions/checkout/tags
uses: actions/checkout@v4
# This action sets up a go environment for use in actions by:
# - Optionally downloading and caching a version of Go by version and adding to PATH.
# - Registering problem matchers for error output.
# https://github.com/actions/setup-go
- name: Setup Golang
id: setup-go
# You may pin to the exact commit or the version.
# uses: https://github.com/actions/setup-go/tags
uses: actions/setup-go@v4
with:
# Fix the following warning: Both go-version and go-version-file inputs are specified, only go-version will be used
go-version: "stable"
# go-version-file: './go.mod'
cache: true
# A GitHub Action for golang tests
- name: Golang Tests
id: go-tests
run: |
go version
rm -rf example
go test -v -race -covermode=atomic -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# https://github.com/apache/skywalking-eyes
# issue: go version hard-coded: https://github.com/apache/skywalking-eyes/blob/5dfa68f93380a5e57259faaf95088b7f133b5778/header/action.yml#L47-L51
- name: Check License Header
if: matrix.platform == 'linux/amd64' # Only required once for any platform, and will do the most general amd64
uses: apache/skywalking-eyes/header@main
with:
log: "info" # optional: set the log level. The default value is `info`.
config: ".licenserc.yaml" # optional: set the config file. The default value is `.licenserc.yaml`.
token: "" # optional: the token that license eye uses when it needs to comment on the pull request. Set to empty ("") to disable commenting on pull request. The default value is ${{ github.token }}
mode: "check" # optional: Which mode License-Eye should be run in. Choices are `check` or `fix`. The default value is `check`.
# The Github action runs CIS Dockerfile benchmark against dockerfiles in repository (CIS 4.1, 4.2, 4.3, 4.6, 4.7, 4.9, 4.10)
# https://github.com/sysdiglabs/benchmark-dockerfile
- name: Sysdig Benchmark Dockerfile
id: sysdig
if: matrix.platform == 'linux/amd64' # Only required once for any platform, and will do the most general amd64
# You may pin to the exact commit or the version.
# uses: https://github.com/sysdiglabs/benchmark-dockerfile/tags
uses: sysdiglabs/benchmark-dockerfile@v1.0.0
with:
# Directory of dockerfiles (default "./")
directory: "./"
# list of disallowed packages separated by comma (default ")
#disallowedPackages: ''
# list of trusted base images separated by comma (default "", meaning trust any base image)
trustedBaseImages: ""
# The Github action runs CIS Dockerfile benchmark against dockerfiles in repository (CIS 4.1, 4.2, 4.3, 4.6, 4.7, 4.9, 4.10)
# https://github.com/sysdiglabs/benchmark-dockerfile
# TODO: Skipping CIS 4.1 check until https://github.com/yahoojapan/authorization-proxy/pull/95 is fixed.
- name: Post Sysdig Benchmark Dockerfile
id: postsysdig
if: matrix.platform == 'linux/amd64' # Only required once for any platform, and will do the most general amd64
run: |
echo ${{ toJSON(steps.sysdig.outputs.violation_report) }} | \
jq -r .
echo ${{ toJSON(steps.sysdig.outputs.violation_report) }} | \
jq -r '.cis_docker_benchmark_violation_report[] | select(.rule!="CIS 4.1 Create a user for the container") | .violations[]' | \
wc -l | \
xargs -I% test 0 -eq %
# GitHub Action to install QEMU static binaries.
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
id: qemu
# You may pin to the exact commit or the version.
# uses: https://github.com/docker/setup-qemu-action/tags
uses: docker/setup-qemu-action@v3
# GitHub Action to set up Docker Buildx.
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
id: buildx
# You may pin to the exact commit or the version.
# uses: https://github.com/docker/setup-buildx-action/tags
uses: docker/setup-buildx-action@v3
- name: Login to Temporary Registry (GitHub Container Registry)
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Lowercase image id name to follow the docker name rule
run: |
IMAGE_ID=ghcr.io/${{ github.repository }}
echo "GHCR_IMAGE_ID=$(echo $IMAGE_ID | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: Build and Push to GHCR (Staging)
uses: docker/build-push-action@v4
with:
context: .
push: true
# tag i.e) ghcr.io/athenz/authorization-proxy:sha-ck29d1-amd64
tags: ${{ env.GHCR_IMAGE_ID }}:${{ github.sha }}${{ matrix.suffix }}
platforms: ${{ matrix.platform }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Test Docker image
- name: Test Docker image
id: test_docker
run: |
docker run --rm ${{ env.GHCR_IMAGE_ID }}:${{ github.sha }}${{ matrix.suffix }} --version
merge:
if: github.event_name != 'pull_request' # We do not need to push pr images to official registry (Docker.io)
needs:
- set_matrix
- build # Make sure each build of every platform defined in matrix is completed
runs-on: ubuntu-latest
permissions:
packages: write # Give read permission WITHOUT making the registry_visibility=Public
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker registry
uses: docker/login-action@v3
with:
# Server address of Docker registry. If not set then will default to Docker Hub
registry: ${{ env.DOCKER_REGISTRY_URL }} # optional
# Username used to log against the Docker registry
username: ${{ vars.DOCKER_REGISTRY_USER }} # optional
# Password or personal access token used to log against the Docker registry
password: ${{ secrets[vars.DOCKER_REGISTRY_TOKEN_NAME] }} # optional
# Log out from the Docker registry at the end of a job
logout: true # optional, default is true
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REGISTRY_URL }}/${{ env.DOCKER_REGISTRY_ORG }}/${{ env.DOCKER_REGISTRY_IMAGE }}
flavor: |
latest=false
# No suffix defined as this will be the merged one!
tags: ${{ env.TAGS_CONFIG }}
- name: Set GHCR Image Name (Lowercase)
run: |
IMAGE_ID=ghcr.io/${{ github.repository }}
echo "GHCR_IMAGE_ID=$(echo $IMAGE_ID | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: Create Manifest and Push to Docker Hub
env:
PLATFORM_SUFFIXES: ${{ needs.set_matrix.outputs.suffixes }}
SHA_TAG: ${{ github.sha }}
run: |
echo "${{ steps.meta.outputs.tags }}" | while read -r docker_registry_tag; do
echo "Merging sources into final tag: $docker_registry_tag"
sources=""
for suffix in $PLATFORM_SUFFIXES; do
# i.e) ghcr.io/athenz/authorization-proxy:sha-xxx-amd64
sources="$sources ${{ env.GHCR_IMAGE_ID }}:${SHA_TAG}${suffix}"
done
docker buildx imagetools create -t "$docker_registry_tag" $sources
done
cleanup:
name: Cleanup Temporary Images from GitHub Container Registry
needs: [set_matrix, build, merge]
if: always()
runs-on: ubuntu-latest
permissions:
packages: write # Permission to delete images from GitHub Container Registry
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Delete Temporary Images using GitHub API
env:
OWNER: ${{ github.repository_owner }}
PACKAGE_NAME: authorization-proxy
SHA_TAG: ${{ github.sha }}
PLATFORM_SUFFIXES: ${{ needs.set_matrix.outputs.suffixes }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🧹 Cleanup using GitHub API..."
for suffix in $PLATFORM_SUFFIXES; do
TAG_NAME="${SHA_TAG}${suffix}"
echo "🔍 Finding version ID for tag: $TAG_NAME"
VERSION_ID=$(gh api "/orgs/$OWNER/packages/container/$PACKAGE_NAME/versions" \
-H "Accept: application/vnd.github+json" \
--jq ".[] | select(.metadata.container.tags[]? == \"$TAG_NAME\") | .id")
if [ -z "$VERSION_ID" ]; then
echo "⚠️ Tag $TAG_NAME not found (already deleted?)"
continue
fi
echo "🗑️ Deleting Version ID: $VERSION_ID (Tag: $TAG_NAME)"
# Delete based on ID:
gh api -X DELETE "/orgs/$OWNER/packages/container/$PACKAGE_NAME/versions/$VERSION_ID" \
-H "Accept: application/vnd.github+json" || true
done
echo "✨ Cleanup finished!"