-
Notifications
You must be signed in to change notification settings - Fork 1
324 lines (285 loc) · 14.5 KB
/
ci.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
name: CI
on:
push:
branches:
- 'main'
tags:
- '*.*.*'
paths-ignore:
- '*.md'
pull_request:
paths-ignore:
- '*.md'
workflow_dispatch:
concurrency:
# Branches and PR all run in their individual, separate concurrency groups (with cancel-in-progress: true). The main
# branch and tags (which are used for releases) run in one shared concurrency group (with cancel-in-progress: true).
# This allows to schedule a release immediately after merging a PR to main, and have the release's CI build be queued
# automatically after the CI build for main has finished. That way, the CI build for the release will be able to reuse
# the Docker cache from the CI build for main.
group: ci-concurrency-group-${{ (github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')) && 'main-and-tags' || github.ref }}
# For branches and PRs, we cancel existing builds if a new commit comes in. For the main branch and tags, we queue
# them and let the run one after the other. The reason is that we build multi-arch container images on main and for
# tags, which takes a really long time if there are changes. But once they have been build, Docker caching makes the
# next builds fast again.
cancel-in-progress: ${{ !(github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')) }}
jobs:
verify:
name: Build & Test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ~1.23
cache: true
- name: go version
run: |
go version
- name: build
run: |
make
- name: verify that generated code is up-to-date
run: |
# make (which we ran in the previous step) will implicitly also run the targets manifests & generate, which
# could potentially modify code that is under version control, if changes have been comitted that would have
# required updating manifests or generated code and these updates have not been done.
git diff --exit-code
- name: lint
run: |
make lint
- name: lint C sources with clang-format
uses: jidicula/[email protected]
with:
clang-format-version: '19'
check-path: 'images/instrumentation/injector/src'
- name: install Helm unittest plugin
shell: bash
run: |
helm plugin install https://github.com/helm-unittest/helm-unittest.git
- name: run operator and Helm chart unit tests
run: |
make test
injector_binary_and_instrumentation_image_tests:
name: Injector Binary & Instrumentation Image Tests
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
- uses: actions/checkout@v4
- name: get branch name
id: branch-name
uses: tj-actions/branch-names@v8
- name: find SHA of last successful workflow run on main branch
uses: nrwl/nx-set-shas@v4
id: last_succsesfull_commit_main_branch
with:
# Get the last successful commit on main branch (actually, on the target branch for the PR, but that is
# usually main).
main-branch-name: ${{ steps.branch-name.outputs.base_ref_branch }}
# We use the changed-files action to potentially skip the injector & instrumentation tests on PRs that contain no
# changes for the instrumentation image. This is because running the tests requires to build the instrumentation
# image for both arm64 and X86_64, and the cross-platform build is very slow (takes up to 15 minutes). We do
# always run these steps when building the main branch or a tag though. By default, changed-files would compare
# against the last non-merge commit on the target branch for pull request events (which is used in PR builds), but
# together with the nrwl/nx-set-shas step from above we compare against the SHA from the last _successful_ CI
# workflow run on the main branch.
- name: compile list of relevant changed files for the instrumentation image
id: changed-files
uses: tj-actions/changed-files@v45
with:
base_sha: ${{ steps.last_succsesfull_commit_main_branch.outputs.base }}
files_yaml: |
instrumentation:
- .github/workflows/ci.yaml
- images/instrumentation/**
- name: show changed files
env:
INSTRUMENTATION_CHANGED_FILES_FLAG: ${{ steps.changed-files.outputs.instrumentation_any_changed }}
INSTRUMENTATION_CHANGED_FILES_LIST: ${{ steps.changed-files.outputs.instrumentation_all_changed_files }}
run: |
echo "files for instrumentation image have changed: $INSTRUMENTATION_CHANGED_FILES_FLAG"
echo "changed files for instrumentation image: $INSTRUMENTATION_CHANGED_FILES_LIST"
- name: set up docker buildx
uses: docker/setup-buildx-action@v3
if: |
steps.changed-files.outputs.instrumentation_any_changed == 'true' ||
github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')
# Just for building on arm, buildx is enough but doing docker run with --platform=linux/arm64 (which we do when
# testing the injector binary and the instrumentation image) requires qemu.
- name: set up qemu
uses: docker/setup-qemu-action@v3
if: |
steps.changed-files.outputs.instrumentation_any_changed == 'true' ||
github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')
- name: login to GitHub container registry
uses: docker/login-action@v3
if: |
steps.changed-files.outputs.instrumentation_any_changed == 'true' ||
github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# To enable running the tests for multiple active branches in parallel without risking conflicts, we use the
# branch name as part of the image tag. However, we cannot just use the branch name as is, since it may contain
# characters that are not allowed in image tags (most notably slashes in dependabot PRs). We replace all invalid
# characters with underscores and use the output of this step as the image tag.
- name: assemble instrumentation test image name
id: instrumentation-test-image
run: |
export image_tag=$( echo "${{ github.head_ref || github.ref_name }}" | sed 's/[^a-zA-Z0-9_\.\-]/\_/g' )
echo "image_name=ghcr.io/dash0hq/instrumentation-ci-test:$image_tag" >> $GITHUB_OUTPUT
- name: build temporary instrumentation image
uses: docker/build-push-action@v6
# Dependabot PRs currently fail in this step, see
# https://stackoverflow.com/questions/74788092/github-dependabot-doesnt-have-permissions-to-publish-to-ghcr-how-can-i-give-it
# This can be worked around by ammending the Dependabot commit and force-pushing it.
# (The original suspicion was that the HTTP 403 was somehow related to the image tag, but this is purely a
# Dependabot permission issue.)
# See also: https://docs.github.com/en/code-security/dependabot
# Maybe we can also allow Dependabot PRs to dry-run the Helm chart publishing, that is, remove the
# github.actor != 'dependabot[bot]' condition we have on those steps.
if: |
steps.changed-files.outputs.instrumentation_any_changed == 'true' ||
github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')
with:
context: images/instrumentation
tags: ${{ steps.instrumentation-test-image.outputs.image_name }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha,scope=instrumentation
cache-to: type=gha,mode=max,scope=instrumentation
push: true
- name: injector tests
if: |
steps.changed-files.outputs.instrumentation_any_changed == 'true' ||
github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')
env:
INSTRUMENTATION_IMAGE: ${{ steps.instrumentation-test-image.outputs.image_name }}
run: |
images/instrumentation/injector/test/scripts/test-all.sh
- name: instrumentation image tests
if: |
steps.changed-files.outputs.instrumentation_any_changed == 'true' ||
github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')
env:
INSTRUMENTATION_IMAGE: ${{ steps.instrumentation-test-image.outputs.image_name }}
run: |
images/instrumentation/test/test-all.sh
- name: delete test image
uses: bots-house/[email protected]
if: ${{ always() && ( steps.changed-files.outputs.instrumentation_any_changed == 'true' || github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/') ) }}
with:
owner: dash0hq
name: instrumentation-ci-test
token: ${{ secrets.GITHUB_TOKEN }}
# delete untagged images from this build (and from earlier builds, if there are any leftovers)
untagged-keep-latest: 1
# Builds and potentially pushes all container images. For pushes to PRs/branches, we simply verify that the image
# build still works, the resulting image will not be pushed to any target registry. For pushes to the main branch, the
# images are tagged with "main-dev", but not with a version x.y.z. Finally, for pushes to a tag (or when a tag is
# created), the images are tagged with the version indicated by the tag respectively, and also with latest. That is:
# Creating a GitHub release (or creating a git tag via other means) will trigger building images tagged with x.y.z
# meant for production use.
build-and-push-images:
name: Build Images
runs-on: ubuntu-latest
needs:
- verify
- injector_binary_and_instrumentation_image_tests
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: build operator controller image
uses: ./.github/actions/build-image
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
imageName: operator-controller
imageTitle: Dash0 Kubernetes Operator Controller
imageDescription: the controller for the Dash0 operator for Kubernetes
imageUrl: https://github.com/dash0hq/dash0-operator/tree/main
context: .
- name: build instrumentation image
uses: ./.github/actions/build-image
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
imageName: instrumentation
imageTitle: Dash0 Instrumentation
imageDescription: contains Dash0 OpenTelemetry distributions for multiple runtimes
imageUrl: https://github.com/dash0hq/dash0-operator/tree/main/images/instrumentation
context: images/instrumentation
- name: build collector image
uses: ./.github/actions/build-image
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
imageName: collector
imageTitle: Dash0 Kubernetes Collector
imageDescription: the OpenTelemetry collector for the Dash0 operator for Kubernetes
imageUrl: https://github.com/dash0hq/dash0-operator/tree/main/images/collector
context: images/collector
- name: build configuration reloader image
uses: ./.github/actions/build-image
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
imageName: configuration-reloader
imageTitle: Dash0 Kubernetes Configuration Reloader
imageDescription: the configuration reloader for the Dash0 operator for Kubernetes
imageUrl: https://github.com/dash0hq/dash0-operator/tree/main/images/configreloader
context: images
file: images/configreloader/Dockerfile
- name: build filelog offset synch image
uses: ./.github/actions/build-image
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
imageName: filelog-offset-synch
imageTitle: Dash0 Kubernetes Filelog Offset Synch
imageDescription: the filelog offset synch for the Dash0 operator for Kubernetes
imageUrl: https://github.com/dash0hq/dash0-operator/tree/main
context: images
file: images/filelogoffsetsynch/Dockerfile
publish-helm-chart-dry-run:
name: Publish Helm Chart (Dry Run)
runs-on: ubuntu-latest
if: ${{ ! contains(github.ref, 'refs/tags/') && github.actor != 'dependabot[bot]'}}
needs:
- build-and-push-images
steps:
- uses: actions/checkout@v4
- name: publish helm chart (dry run)
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
echo "verifying that helm chart can be published"
DRY_RUN=true helm-chart/bin/publish.sh 0.0.0
# By default, when a GH action run is triggered by dependabot, it will only get read-only permissions.
# See https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions#changing-github_token-permissions
# For that reason, we skip the check whether the Helm chart can still be published for Dependabot update PRs.
# Those PRs do not change the Helm chart anyway.
# Note that the value of the "name" attribute needs to be identical to the publish-helm-chart-dry-run job, since the
# branch protection rules reference this property, and it is a required check.
skip-publish-helm-chart-dry-run-for-dependabot:
name: Publish Helm Chart (Dry Run)
runs-on: ubuntu-latest
if: ${{ ! contains(github.ref, 'refs/tags/') && github.actor == 'dependabot[bot]'}}
needs:
- build-and-push-images
steps:
- name: skipping publish helm chart (dry run)
run: |
echo skipping publish helm chart dry run for dependabot commit
publish-helm-chart:
name: Publish Helm Chart
runs-on: ubuntu-latest
if: ${{ contains(github.ref, 'refs/tags/') && github.actor != 'dependabot[bot]'}}
needs:
- build-and-push-images
steps:
- uses: actions/checkout@v4
- name: publish helm chart
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
echo "publishing helm chart version ${{ github.ref_name }}"
helm-chart/bin/publish.sh ${{ github.ref_name }}