-
Notifications
You must be signed in to change notification settings - Fork 0
258 lines (231 loc) 路 11.9 KB
/
release.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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
name: Publish to ghcr.io
on:
push:
tags:
- '*'
env:
REGISTRY: ghcr.io # default is docker.io
IMAGE_NAME: ${{ github.repository }} # e.g. user/fancy-project
# https://stackoverflow.com/a/62805013/4292075
# repo name: ${{ github.event.repository.name }}
jobs:
go-releaser:
runs-on: ubuntu-latest
permissions:
contents: write # for go-releaser binaries (add and cleanup)
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# Use go-releaser to build binaries outside docker
- name: Set up Go
uses: actions/setup-go@v5
# not necessary? https://goreleaser.com/cookbooks/using-main.version/
#- name: Set Variables used in .goreleaser.yml for ldflags
# run: |
# echo "RUBIN_COMMIT=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV
# echo "RUBIN_VERSION=${GITHUB_REF#refs/*/}" >> "$GITHUB_ENV"
# echo "RUBIN_BUILD_DATE=$(date +'%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_ENV"
- name: Run GoReleaser to build and release binaries (only once on linux/amd64)
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
#args: build --clean # use this if you only need binaries w/o releasing anything
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Move goreleaser generated binaries to a predictable platform path for docker build
# use target subdirectory app/${{ matrix.platform }}/, which is passed as build arg to docker build,
# copy platform specific binary in actual image (the other one was built in vain, but it's fast :-))
# see also https://goreleaser.com/customization/builds/#why-is-there-a-_v1-suffix-on-amd64-builds
run: |
mkdir -p app/linux/amd64
mkdir -p app/linux/arm64
mv -v dist/${{ github.event.repository.name }}_linux_amd64_v1/${{ github.event.repository.name }} \
app/linux/amd64/${{ github.event.repository.name }}
mv -v dist/${{ github.event.repository.name }}_linux_arm64/${{ github.event.repository.name }} \
app/linux/arm64/${{ github.event.repository.name }}
mv -v dist/polly_linux_amd64_v1/polly app/linux/amd64/polly
mv -v dist/polly_linux_arm64/polly app/linux/arm64/polly
- name: Upload binaries built by go-releaser
uses: actions/upload-artifact@v4
with:
name: go-releaser-binaries
path: app/
if-no-files-found: error
retention-days: 1
# https://github.com/marketplace/actions/delete-older-releases
- name: Delete old released binaries
uses: dev-drprasad/delete-older-releases@v0.3.3
with:
#repo: <owner>/<repoName> # defaults to current repo
keep_latest: 5
keep_min_download_counts: 1 # Optional parameters
delete_expired_data: 30 # must set, or nothing gets removed
#delete_tag_pattern: beta # defaults to ""
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docker-push:
name: Release multiplatform binaries and container images
runs-on: ubuntu-latest
needs: [go-releaser]
permissions:
packages: write # required to write to container registry
strategy:
fail-fast: true
# restrict steps in matrix: https://github.com/orgs/community/discussions/27105#discussioncomment-3254644
# example: if: matrix.platform == 'linux/amd64'
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download binaries built by go-releaser from previous job
uses: actions/download-artifact@v4
with:
name: go-releaser-binaries
path: app/ # must specify path (e.g. same as during upload), or files end up on root (?)
#merge-multiple: true
#path: ${{ runner.temp }}/digests
- name: Chmod apps and set Variables used in build-args for docker build
# we can't chmod in Dockerfile with distroless, but x will be preserved during COPY
run: |
chmod -R ugo+x app/
echo "APP_COMMIT=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV
echo "APP_VERSION=${GITHUB_REF#refs/*/}" >> "$GITHUB_ENV"
echo "APP_DATE=$(date +'%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_ENV"
echo "APP_BUILT_BY=docker/build-push-action" >> "$GITHUB_ENV"
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# QEMU is a generic and open source machine & userspace emulator and virtualizer.
# to emulating a complete machine in software without any need for hardware virtualization support
- name: Set up QEMU static binaries
uses: docker/setup-qemu-action@v3
with:
# since we run platform specific builds in parallel, we only need the current platform
platforms: ${{ matrix.platform }}
- name: Set up Docker Buildx for Multiple platform builds
uses: docker/setup-buildx-action@v3
- name: Login to GitHub container registry (ghcr.io)
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
# You can use the GitHub actor context to automatically use the username of the user that triggered the workflow run.
username: ${{ github.actor }}
# You can use the automatically-generated GITHUB_TOKEN secret for the password
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build docker image
id: build # so we can reference this step as ${{ steps.build.outputs.digest }} in export step
uses: docker/build-push-action@v5
# Resulting commandline from this action:
# /usr/bin/docker buildx build --build-arg APP_COMMIT=0ce58cd --build-arg APP_VERSION=v0.7.3 --build-arg APP_DATE=2024-02-28T22:55:42
# --build-arg APP_BUILT_BY=docker/build-push-action --iidfile /home/runner/work/_temp/docker-actions-toolkit-xyz/iidfile
# --label org.opencontainers.image.created=2024-02-28T22:55:42.455Z --label org.opencontainers.image.description="taken from GitHub 'About' Description"
# --label org.opencontainers.image.licenses=Apache-2.0 --label org.opencontainers.image.revision=0ce58cde59c89fc15b07791107fb4969c585ab51
# --label org.opencontainers.image.source=https://github.com/tillkuhn/rubin --label org.opencontainers.image.title=rubin
# --label org.opencontainers.image.url=https://github.com/tillkuhn/rubin --label org.opencontainers.image.version=v0.7.3
# --output type=image,name=ghcr.io/tillkuhn/rubin,push-by-digest=true,name-canonical=true,push=true
# --platform linux/amd64 --provenance false --metadata-file /home/runner/work/_temp/docker-actions-toolkit-xyz/metadata-file .
with:
platforms: ${{ matrix.platform }}
context: .
push: false # push later
# DO NOT specify 'tags' here (error "get can't push tagged ref by digest")
# tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# why provenance: false? See "GitHub Action produces unknown architecture and OS": https://github.com/docker/build-push-action/issues/820
provenance: false
build-args: |
APP_COMMIT=${{ env.APP_COMMIT }}
APP_VERSION=${{ env.APP_VERSION }}
APP_DATE=${{ env.APP_DATE }}
APP_BUILT_BY=${{ env.APP_BUILT_BY }}
PLATFORM=${{ matrix.platform }}
# capture output for export and upload image digests
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
- name: Export docker image digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
platform="${{ matrix.platform }}"
echo "PLATFORM_SLUG=${platform//\//_}" >> "$GITHUB_ENV"
- name: Upload docker image digest
uses: actions/upload-artifact@v4
with:
# as of upload-artifact@v4, artifact name must be unique (and must NOT contain a slash :-))
# https://github.com/actions/upload-artifact/issues/478#issuecomment-1885470013
name: digests-${{ env.PLATFORM_SLUG }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
# dedicated manifest merge job which runs after all platform specific build jobs are finished
# see https://docs.docker.com/build/ci/github-actions/multi-platform/
# see https://github.com/docker/build-push-action/issues/846
merge-manifests:
runs-on: ubuntu-latest
permissions:
packages: write # avoid unexpected status from PUT request to https://ghcr.io/v2/tillkuhn/rubin/manifests/latest: 403 Forbidden
needs: [docker-push]
steps:
- name: Download image digests
uses: actions/download-artifact@v4
with:
# see comment in upload-artifact@v4, we need to merge by pattern due to the platform specific names
pattern: digests-*
merge-multiple: true
path: ${{ runner.temp }}/digests
- name: Set up Docker Buildx # but no need for QEMU in this job
uses: docker/setup-buildx-action@v3
- name: Extract docker metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push
# ${{ runner.temp }} /home/runner/work/_temp, better than /tmp
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect and test new multi-platform image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} -help
- name: Install latest rubin Kafka Record producer
run: |
curl -LsSo ${{ runner.temp }}/rubin.zip $(curl -LsS 'https://api.github.com/repos/tillkuhn/rubin/releases/latest' | jq -r '.assets[] | select(.name|endswith("linux_amd64.zip")).browser_download_url')
unzip ${{ runner.temp }}/rubin.zip -d ${{ runner.temp }} && chmod u+g ${{ runner.temp }}/rubin
- name: Produce Kafka Publish Event
id: send-kafka-publish-event
run: |
${{ runner.temp }}/rubin -key "${GITHUB_REPOSITORY}" -ce \
-source "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
-type "net.timafe.event.ci.published.v1" -subject "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}" \
-record "{\"action\":\"$GITHUB_ACTION\",\"version\":\"${GITHUB_REF#refs/*/}\",\"commit\":\"$GITHUB_SHA\"}" \
-header "github_run_id=${GITHUB_RUN_ID}"
env:
KAFKA_PRODUCER_TOPIC_URL: ${{ secrets.KAFKA_PRODUCER_TOPIC_URL }}
KAFKA_PRODUCER_API_SECRET: ${{ secrets.KAFKA_PRODUCER_API_SECRET }}
- name: Cleanup old packages (container registry)
uses: actions/delete-package-versions@v5
with:
package-name: ${{ github.event.repository.name }}
package-type: 'container'
min-versions-to-keep: 7
delete-only-untagged-versions: 'false'