-
Notifications
You must be signed in to change notification settings - Fork 531
485 lines (472 loc) · 20.4 KB
/
test-build-deploy.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
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
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
name: ci
on:
push:
branches:
- main
- r[0-9]+ # Trigger builds after a push to weekly branches
tags:
# The following regex matches the Mimir release tag. Tag filters not as strict due to different regex system on Github Actions.
- mimir-[0-9]+.[0-9]+.[0-9]+**
pull_request:
concurrency:
# Cancel any running workflow for the same branch when new commits are pushed.
# We group both by ref_name (available when CI is triggered by a push to a branch/tag)
# and head_ref (available when CI is triggered by a PR).
group: "${{ github.ref_name }}-${{ github.head_ref }}"
cancel-in-progress: true
jobs:
prepare:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Get build image from Makefile
id: build_image_step
run: echo "build_image=$(make print-build-image)" >> "$GITHUB_OUTPUT"
outputs:
build_image: ${{ steps.build_image_step.outputs.build_image }}
# Determine if we will deploy (aka push) the image to the registry.
is_deploy: ${{ (startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/r')) && github.event_name == 'push' && github.repository == 'grafana/mimir' }}
goversion:
runs-on: ubuntu-latest
needs: prepare
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Get Go Version
id: go-version
run: |
echo "version=$(make BUILD_IN_CONTAINER=false print-go-version)" >> "$GITHUB_OUTPUT"
outputs:
version: ${{ steps.go-version.outputs.version }}
lint:
runs-on: ubuntu-latest
needs: prepare
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
# Commands in the Makefile are hardcoded with an assumed file structure of the CI container
# Symlink ensures paths specified in previous commands don’t break
- name: Symlink Expected Path to Workspace
run: |
mkdir -p /go/src/github.com/grafana/mimir
ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Get golangci-lint cache path
id: golangcilintcache
run: |
echo "path=$(golangci-lint cache status | grep 'Dir: ' | cut -d ' ' -f2)" >> "$GITHUB_OUTPUT"
- name: Cache golangci-lint cache
uses: actions/cache@v4
with:
key: lint-golangci-lint-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum', '.golangci.yml', 'Makefile') }}
path: ${{ steps.golangcilintcache.outputs.path }}
- name: Get Go cache paths
id: goenv
run: |
echo "gocache=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "gomodcache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Cache Go build cache
uses: actions/cache@v4
with:
key: lint-go-build-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum') }}
path: ${{ steps.goenv.outputs.gocache }}
# Although we use vendoring, this linting job downloads all modules to verify that what is vendored is correct,
# so it'll use GOMODCACHE. Other jobs don't need this.
- name: Cache Go module cache
uses: actions/cache@v4
with:
key: lint-go-mod-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum') }}
path: ${{ steps.goenv.outputs.gomodcache }}
- name: Lint
run: make BUILD_IN_CONTAINER=false lint
- name: Check Vendor Directory
run: make BUILD_IN_CONTAINER=false mod-check
- name: Check Protos
run: make BUILD_IN_CONTAINER=false check-protos
- name: Check Generated Documentation
run: make BUILD_IN_CONTAINER=false check-doc
- name: Check White Noise
run: make BUILD_IN_CONTAINER=false check-white-noise
- name: Check License Header
run: make BUILD_IN_CONTAINER=false check-license
- name: Check Docker-Compose YAML
run: make BUILD_IN_CONTAINER=false check-mimir-microservices-mode-docker-compose-yaml check-mimir-read-write-mode-docker-compose-yaml
- name: Check Generated OTLP Code
run: make BUILD_IN_CONTAINER=false check-generated-otlp-code
doc-validator:
runs-on: ubuntu-latest
container:
image: grafana/doc-validator:v5.2.0
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Run doc-validator tool (mimir)
run: >
doc-validator
'--skip-checks=^canonical-does-not-match-pretty-URL$'
docs/sources/mimir
/docs/mimir/latest
| reviewdog
-f=rdjsonl
--fail-on-error
--filter-mode=nofilter
--name=doc-validator
--reporter=github-pr-review
env:
REVIEWDOG_GITHUB_API_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: Run doc-validator tool (helm-charts)
run: >
doc-validator
docs/sources/helm-charts
/docs/helm-charts/mimir-distributed/latest
| reviewdog
-f=rdjsonl
--fail-on-error
--filter-mode=nofilter
--name=doc-validator
--reporter=github-pr-review
env:
REVIEWDOG_GITHUB_API_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
lint-jsonnet:
runs-on: ubuntu-latest
needs:
- prepare
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
# Commands in the Makefile are hardcoded with an assumed file structure of the CI container
# Symlink ensures paths specified in previous commands don’t break
- name: Symlink Expected Path to Workspace
run: |
mkdir -p /go/src/github.com/grafana/mimir
ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Check Mixin
run: make BUILD_IN_CONTAINER=false check-mixin
- name: Check Mixin Tests
run: make BUILD_IN_CONTAINER=false check-mixin-tests
- name: Check Mixin with Mimirtool rules check
run: make BUILD_IN_CONTAINER=false check-mixin-mimirtool-rules
- name: Check Jsonnet Manifests
run: make BUILD_IN_CONTAINER=false check-jsonnet-manifests
- name: Check Jsonnet Getting Started
run: make BUILD_IN_CONTAINER=false check-jsonnet-getting-started
- name: Check Jsonnet Tests
run: make BUILD_IN_CONTAINER=false check-jsonnet-tests
lint-helm:
runs-on: ubuntu-latest
needs:
- prepare
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
# Commands in the Makefile are hardcoded with an assumed file structure of the CI container
# Symlink ensures paths specified in previous commands don’t break
- name: Symlink Expected Path to Workspace
run: |
mkdir -p /go/src/github.com/grafana/mimir
ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.8.2
- name: Check Helm Tests
run: make BUILD_IN_CONTAINER=false check-helm-tests
test:
runs-on: ubuntu-latest
strategy:
# Do not abort other groups when one fails.
fail-fast: false
# Split tests into 4 groups.
matrix:
test_group_id: [0, 1, 2, 3]
test_group_total: [4]
needs:
- prepare
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Symlink Expected Path to Workspace
run: |
mkdir -p /go/src/github.com/grafana/mimir
ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Get Go build cache path
id: gocache
run: |
echo "path=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
- name: Cache Go build cache
uses: actions/cache@v4
with:
# Cache is shared between test groups.
key: test-go-build-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum') }}
path: ${{ steps.gocache.outputs.path }}
- name: Run Tests
run: |
echo "Running unit tests (group ${{ matrix.test_group_id }} of ${{ matrix.test_group_total }}) with Go version: $(go version)"
./.github/workflows/scripts/run-unit-tests-group.sh --index ${{ matrix.test_group_id }} --total ${{ matrix.test_group_total }}
test-docs:
uses: ./.github/workflows/test-docs.yml
build:
runs-on: ubuntu-latest
needs:
- prepare
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Install Docker Client
run: ./.github/workflows/scripts/install-docker.sh
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Symlink Expected Path to Workspace
run: |
mkdir -p /go/src/github.com/grafana/mimir
ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Get Go build cache path
id: gocache
run: |
echo "path=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
- name: Cache Go build cache
uses: actions/cache@v4
with:
key: build-go-build-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum') }}
path: ${{ steps.gocache.outputs.path }}
- name: Build Multiarch Docker Images Locally
# Ignore mimir-build-image and mimir-rules-action.
run: |
./.github/workflows/scripts/build-images.sh /tmp/images $(make list-image-targets | grep -v -E '/mimir-build-image/|/mimir-rules-action/')
- name: Build Archive With Docker Images
run: |
tar cvf images.tar /tmp/images
- name: Upload Archive with Docker Images
uses: actions/upload-artifact@v4
with:
name: Docker Images
path: ./images.tar
- name: Build Mimir with race-detector
run: |
# When building uptodate_race target, we create two images since
# a Dockerfile.alpine exists. The alpine image is built with
# the `-alpine` suffix.
# We build both until we have finished migrating to distroless.
# We test the distroless race image in every integration test.
# We test the (legacy) alpine race image when deploying (aka pushing).
make BUILD_IN_CONTAINER=false cmd/mimir/.uptodate_race
export IMAGE_TAG_RACE=$(make image-tag-race)
export MIMIR_DISTROLESS_IMAGE="grafana/mimir:$IMAGE_TAG_RACE"
export MIMIR_ALPINE_IMAGE="grafana/mimir-alpine:$IMAGE_TAG_RACE"
docker save $MIMIR_DISTROLESS_IMAGE -o ./mimir_race_image_distroless
docker save $MIMIR_ALPINE_IMAGE -o ./mimir_race_image_alpine
- name: Upload archive with race-enabled Mimir
uses: actions/upload-artifact@v4
with:
name: Race-enabled Mimir
path: |
./mimir_race_image_alpine
./mimir_race_image_distroless
integration:
needs: [goversion, build, prepare]
runs-on: ubuntu-latest
strategy:
# Do not abort other groups when one fails.
fail-fast: false
# Split tests into 6 groups.
matrix:
test_group_id: [0, 1, 2, 3, 4, 5]
test_group_total: [6]
steps:
- name: Upgrade golang
uses: actions/setup-go@v5
with:
go-version: ${{ needs.goversion.outputs.version }}
cache: false # We manage caching ourselves below to maintain consistency with the other jobs that don't use setup-go.
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Install Docker Client
run: sudo ./.github/workflows/scripts/install-docker.sh
- name: Symlink Expected Path to Workspace
run: |
sudo mkdir -p /go/src/github.com/grafana/mimir
sudo ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Get Go build cache path
id: gocache
run: |
echo "path=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
- name: Cache Go build cache
uses: actions/cache@v4
with:
# Cache is shared between test groups.
key: integration-go-build-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum') }}
path: ${{ steps.gocache.outputs.path }}
- name: Download Archive with Docker Images
uses: actions/download-artifact@v4
with:
name: Docker Images
- name: Extract Docker Images from Archive
run: tar xvf images.tar -C /
- name: Load Mimirtool Image into Docker
run: |
export IMAGE_TAG=$(make image-tag)
# skopeo will by default load system-specific version of the image (linux/amd64).
# note that this doesn't use skopeo version from our build-image, because we don't use build-image when running integration tests.
# that's why we use docker run to run latest version.
docker run -v /tmp/images:/tmp/images -v /var/run/docker.sock:/var/run/docker.sock quay.io/skopeo/stable:v1.15.1 copy oci-archive:/tmp/images/mimirtool.oci "docker-daemon:grafana/mimirtool:$IMAGE_TAG"
- name: Download Archive with Docker Images
uses: actions/download-artifact@v4
with:
name: Race-enabled Mimir
- name: Load race-enabled mimir into Docker
run: |
export IMAGE_TAG_RACE=$(make image-tag-race)
docker load -i ./mimir_race_image_distroless
docker run "grafana/mimir:$IMAGE_TAG_RACE" --version
- name: Preload Images
# We download docker images used by integration tests so that all images are available
# locally and the download time doesn't account in the test execution time, which is subject
# to a timeout
run: go run ./tools/pre-pull-images | xargs -n1 -P4 docker pull
- name: Integration Tests
run: |
export IMAGE_TAG_RACE=$(make image-tag-race)
export MIMIR_IMAGE="grafana/mimir:$IMAGE_TAG_RACE"
export IMAGE_TAG=$(make image-tag)
export MIMIRTOOL_IMAGE="grafana/mimirtool:$IMAGE_TAG"
export MIMIR_CHECKOUT_DIR="/go/src/github.com/grafana/mimir"
echo "Running integration tests with image: $MIMIR_IMAGE (Mimir), $MIMIRTOOL_IMAGE (Mimirtool)"
echo "Running integration tests (group ${{ matrix.test_group_id }} of ${{ matrix.test_group_total }}) with Go version: $(go version)"
./.github/workflows/scripts/run-integration-tests-group.sh --index ${{ matrix.test_group_id }} --total ${{ matrix.test_group_total }}
integration-alpine:
needs: [goversion, build, prepare]
runs-on: ubuntu-latest
if: needs.prepare.outputs.is_deploy == 'true'
strategy:
# Do not abort other groups when one fails.
fail-fast: false
# Split tests into 6 groups.
matrix:
test_group_id: [0, 1, 2, 3, 4, 5]
test_group_total: [6]
steps:
- name: Upgrade golang
uses: actions/setup-go@v5
with:
go-version: ${{ needs.goversion.outputs.version }}
cache: false # We manage caching ourselves below to maintain consistency with the other jobs that don't use setup-go.
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Install Docker Client
run: sudo ./.github/workflows/scripts/install-docker.sh
- name: Symlink Expected Path to Workspace
run: |
sudo mkdir -p /go/src/github.com/grafana/mimir
sudo ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Get Go build cache path
id: gocache
run: |
echo "path=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
- name: Cache Go build cache
uses: actions/cache@v4
with:
# Cache is shared between test groups.
key: integration-go-build-${{ runner.os }}-${{ hashFiles('go.mod', 'go.sum') }}
path: ${{ steps.gocache.outputs.path }}
- name: Download Archive with Docker Images
uses: actions/download-artifact@v4
with:
name: Docker Images
- name: Extract Docker Images from Archive
run: tar xvf images.tar -C /
- name: Load Mimirtool Image into Docker
run: |
export IMAGE_TAG=$(make image-tag)
# skopeo will by default load system-specific version of the image (linux/amd64).
# note that this doesn't use skopeo version from our build-image, because we don't use build-image when running integration tests.
# that's why we use docker run to run latest version.
docker run -v /tmp/images:/tmp/images -v /var/run/docker.sock:/var/run/docker.sock quay.io/skopeo/stable:v1.15.1 copy oci-archive:/tmp/images/mimirtool.oci "docker-daemon:grafana/mimirtool:$IMAGE_TAG"
- name: Download Archive with Docker Images
uses: actions/download-artifact@v4
with:
name: Race-enabled Mimir
- name: Load race-enabled mimir into Docker
run: |
export IMAGE_TAG_RACE=$(make image-tag-race)
docker load -i ./mimir_race_image_alpine
docker run "grafana/mimir-alpine:$IMAGE_TAG_RACE" --version
- name: Preload Images
# We download docker images used by integration tests so that all images are available
# locally and the download time doesn't account in the test execution time, which is subject
# to a timeout
run: go run ./tools/pre-pull-images | xargs -n1 -P4 docker pull
- name: Integration Tests
run: |
export IMAGE_TAG_RACE=$(make image-tag-race)
export MIMIR_IMAGE="grafana/mimir-alpine:$IMAGE_TAG_RACE"
export IMAGE_TAG=$(make image-tag)
export MIMIRTOOL_IMAGE="grafana/mimirtool:$IMAGE_TAG"
export MIMIR_CHECKOUT_DIR="/go/src/github.com/grafana/mimir"
echo "Running integration tests with image: $MIMIR_IMAGE (Mimir), $MIMIRTOOL_IMAGE (Mimirtool)"
echo "Running integration tests (group ${{ matrix.test_group_id }} of ${{ matrix.test_group_total }}) with Go version: $(go version)"
./.github/workflows/scripts/run-integration-tests-group.sh --index ${{ matrix.test_group_id }} --total ${{ matrix.test_group_total }}
deploy:
needs: [prepare, build, test, lint, integration, integration-alpine]
# Only deploy images on pushes to the grafana/mimir repo, which either are tag pushes or weekly release branch pushes.
if: needs.prepare.outputs.is_deploy == 'true'
runs-on: ubuntu-latest
container:
image: ${{ needs.prepare.outputs.build_image }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Run Git Config
run: git config --global --add safe.directory '*'
- name: Install Docker Client
run: ./.github/workflows/scripts/install-docker.sh
- name: Symlink Expected Path to Workspace
run: |
mkdir -p /go/src/github.com/grafana/mimir
ln -s $GITHUB_WORKSPACE/* /go/src/github.com/grafana/mimir
- name: Download Archive with Docker Images
uses: actions/download-artifact@v4
with:
name: Docker Images
- name: Extract Docker Images from Archive
run: tar xvf images.tar -C /
- name: Deploy
run: |
if [ -n "$DOCKER_PASSWORD" ]; then
printenv DOCKER_PASSWORD | skopeo login -u "$DOCKER_USERNAME" --password-stdin docker.io
fi
./.github/workflows/scripts/push-images.sh /tmp/images grafana/ $(make image-tag)
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}