-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathTaskfile-build.yml
More file actions
533 lines (500 loc) · 22.1 KB
/
Copy pathTaskfile-build.yml
File metadata and controls
533 lines (500 loc) · 22.1 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
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
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'
vars:
IMG: '{{.IMG | default "controller:latest"}}'
CONTAINER_TOOL: '{{.CONTAINER_TOOL | default "docker"}}'
HELM: '{{.HELM | default "helm"}}'
CONTROLLER_GEN: '{{.CONTROLLER_GEN | default "controller-gen"}}'
ENVTEST: '{{.ENVTEST | default "setup-envtest"}}'
GOLANGCI_LINT: '{{.GOLANGCI_LINT | default "golangci-lint"}}'
SCC: '{{.SCC | default "scc"}}'
INSTALL_NAME: '{{.INSTALL_NAME | default "gitops-reverser"}}'
NAMESPACE: '{{.NAMESPACE | default "gitops-reverser"}}'
DEFAULT_AUDIT_REDIS_ADDR: '{{.DEFAULT_AUDIT_REDIS_ADDR | default "valkey:6379"}}'
ENVTEST_K8S_VERSION:
sh: |
go list -m -f '{{"{{"}} .Version {{"}}"}}' k8s.io/api \
| awk -F'[v.]' '{printf "1.%d", $3}'
ENVTEST_STAMP: '.stamps/envtest-{{.ENVTEST_K8S_VERSION}}.ready'
# Fuzzing (dynamic analysis) targets, one "package:FuzzTarget" pair per line.
# `go test -fuzz` fuzzes exactly one target per invocation, so the fuzz tasks
# loop over these. See docs/finished/dynamic-analysis-fuzzing-plan.md.
FUZZ_TARGETS: >-
./internal/git/manifestedit:FuzzManifestEdit
./internal/webhook:FuzzDecodeEventList
FUZZ_SMOKE_TIME: '{{.FUZZ_SMOKE_TIME | default "15s"}}'
FUZZ_TIME: '{{.FUZZ_TIME | default "2m"}}'
# Which markdown files the docs linters see: `gated` (the files .docs-lint-scope
# lists) or `all` (every tracked file). hack/docs-files.sh resolves it and is the
# only place that builds the list.
#
# The two linters default differently because their backlogs are two orders of
# magnitude apart. Structure (markdownlint) is clean tree-wide, so it gates `all`.
# Prose (Vale) still has ~1,100 errors across the tree, so it stays `gated` and the
# .docs-lint-scope list grows as files are cleaned. `DOCS_SCOPE` overrides both:
# task lint-markdown DOCS_SCOPE=gated
# task lint-prose DOCS_SCOPE=all # the backlog view
MARKDOWN_SCOPE: '{{.DOCS_SCOPE | default "all"}}'
PROSE_SCOPE: '{{.DOCS_SCOPE | default "gated"}}'
tasks:
manifests:
desc: Generate ClusterRole and CustomResourceDefinition objects
deps:
- generate
sources:
- api/**/*.go
- internal/**/*.go
- cmd/**/*.go
- exclude: api/**/*_test.go
- exclude: internal/**/*_test.go
- exclude: cmd/**/*_test.go
- exclude: api/**/zz_generated.deepcopy.go
- exclude: internal/**/zz_generated.deepcopy.go
- exclude: cmd/**/zz_generated.deepcopy.go
generates:
- config/crd/bases/configbutler.ai*.yaml
- config/rbac/role.yaml
cmds:
- |
set -e
mkdir -p config/crd/bases config/rbac
# Write CRDs straight into the bases dir, overwriting in place. The
# marker predates the run, so afterwards any base controller-gen did
# not (re)write — i.e. a renamed/removed type — is older than it and
# gets pruned. Avoiding the old up-front rm keeps file watchers (e.g.
# Tilt) from seeing missing CRDs mid-regeneration.
marker="$(mktemp)"
trap 'rm -f "$marker"' EXIT
{{.CONTROLLER_GEN}} \
rbac:roleName=gitops-reverser \
crd \
paths=./api/... \
paths=./internal/controller/... \
paths=./internal/watch/... \
paths=./cmd/... \
output:crd:artifacts:config=config/crd/bases
find config/crd/bases -maxdepth 1 -name '*.yaml' ! -newer "$marker" -delete
helm-sync:
desc: Sync CRDs and roles from config/crd/bases into the Helm chart
deps:
- manifests
sources:
- api/**/*.go
- internal/**/*.go
- cmd/**/*.go
- exclude: api/**/*_test.go
- exclude: internal/**/*_test.go
- exclude: cmd/**/*_test.go
- exclude: api/**/zz_generated.deepcopy.go
- exclude: internal/**/zz_generated.deepcopy.go
- exclude: cmd/**/zz_generated.deepcopy.go
generates:
- charts/gitops-reverser/crds/configbutler.*.yaml
- charts/gitops-reverser/config/role.yaml
cmds:
- |
mkdir -p charts/gitops-reverser/crds charts/gitops-reverser/config
rm -f charts/gitops-reverser/crds/*.yaml charts/gitops-reverser/config/*.yaml
cp config/crd/bases/*.yaml charts/gitops-reverser/crds/
cp config/rbac/role.yaml charts/gitops-reverser/config/role.yaml
generate:
desc: Generate DeepCopy implementations
sources:
- api/**/*.go
- hack/boilerplate.go.txt
- exclude: api/**/*_test.go
- exclude: api/**/zz_generated.deepcopy.go
generates:
- api/v1alpha3/zz_generated.deepcopy.go
cmds:
- '{{.CONTROLLER_GEN}} object:headerFile="hack/boilerplate.go.txt" paths=./api/...'
fmt:
desc: Run go fmt against code
cmds:
- go fmt ./...
vet:
desc: Run go vet against code
cmds:
- go vet ./...
setup-envtest:
desc: Setup envtest binaries for unit tests
method: timestamp
sources:
- go.mod
generates:
- '{{.ENVTEST_STAMP}}'
cmds:
- |
echo "Setting up envtest binaries for Kubernetes version {{.ENVTEST_K8S_VERSION}}..."
mkdir -p "$(pwd)/bin" "$(dirname '{{.ENVTEST_STAMP}}')"
{{.ENVTEST}} use {{.ENVTEST_K8S_VERSION}} --bin-dir "$(pwd)/bin" -p path
touch '{{.ENVTEST_STAMP}}'
test:
desc: Run unit tests
deps:
- manifests
- fmt
- vet
- setup-envtest
# cmd's chart-args test runs `helm template`, which evaluates every template —
# including rbac.yaml, which reads the gitignored chart/config/role.yaml this
# syncs. Without it a fresh checkout fails the unit suite.
- helm-sync
cmds:
- |
export KUBEBUILDER_ASSETS="$({{.ENVTEST}} use {{.ENVTEST_K8S_VERSION}} --bin-dir "$(pwd)/bin" -p path)"
go test $(go list ./... | grep -Ev '/test/e2e$') -coverprofile cover.out
- task: cover-check
cover-check:
desc: Self-ratcheting local coverage gate; fails if total drops below the high-water baseline
cmds:
- |
set -eu
if [ ! -f cover.out ]; then
echo "cover.out not found; run 'task test' first" >&2
exit 1
fi
# .coverage-baseline is a committed high-water mark (local equivalent of
# Codecov's project ratchet). The gate fails only on a drop beyond TOL%
# (noise slack); any improvement auto-raises the baseline so it climbs on
# its own. Commit the bumped file to advance the floor for everyone.
tol=0.5
baseline="$(cat .coverage-baseline 2>/dev/null || echo 0)"
total="$(go tool cover -func=cover.out | awk '/^total:/ {gsub("%","",$3); print $3}')"
if awk -v t="${total}" -v b="${baseline}" -v tol="${tol}" 'BEGIN{exit !(t+0 < b-tol)}'; then
printf "❌ unit coverage %s%% dropped more than %s%% below baseline %s%%\n" "${total}" "${tol}" "${baseline}"
exit 1
fi
if awk -v t="${total}" -v b="${baseline}" 'BEGIN{exit !(t+0 > b+0)}'; then
printf '%s\n' "${total}" > .coverage-baseline
printf "✅ unit coverage %s%% — raised baseline %s%% → %s%% (commit .coverage-baseline)\n" "${total}" "${baseline}" "${total}"
else
printf "✅ unit coverage %s%% (baseline %s%%, tolerance %s%%)\n" "${total}" "${baseline}" "${tol}"
fi
fuzz-smoke:
desc: Short fuzzing smoke — briefly active-fuzz each target under the race detector
cmds:
- |
set -eu
for entry in {{.FUZZ_TARGETS}}; do
pkg="${entry%%:*}"; target="${entry##*:}"
echo "==> fuzz-smoke ${target} (${pkg}) for {{.FUZZ_SMOKE_TIME}}"
go test "${pkg}" -run '^$' -fuzz="^${target}$" -fuzztime={{.FUZZ_SMOKE_TIME}} -race
done
fuzz:
desc: >-
Release-time dynamic analysis — longer fuzz discovery run per target under the race
detector. Crash reproducers land under <pkg>/testdata/fuzz/<Target>/ (commit them).
See docs/finished/dynamic-analysis-fuzzing-plan.md.
cmds:
- |
set -eu
for entry in {{.FUZZ_TARGETS}}; do
pkg="${entry%%:*}"; target="${entry##*:}"
echo "==> fuzz ${target} (${pkg}) for {{.FUZZ_TIME}}"
go test "${pkg}" -run '^$' -fuzz="^${target}$" -fuzztime={{.FUZZ_TIME}} -race
done
lint:
desc: Run all linters (Go, Dockerfiles, workflows, Helm chart, docs); deps run in parallel where safe
deps:
- lint-golang
- lint-dockerfiles
- lint-actions
- lint-helm
- lint-docs
lint-docs:
desc: All documentation checks — references, markdown structure, and prose
# The three docs linters do not overlap and each is bad at the others' job, so
# they stay three tasks and this aggregates them. See docs/design/docs-linting.md.
#
# lint-doc-links references resolve, including doc paths inside Go comments
# lint-markdown markdown structure: fences, headings, lists, blank lines
# lint-prose English against docs/style-guide.md
#
# This kept the name `lint-docs` because AGENTS.md, docs/style-guide.md, and the
# CI cache assertion all name it. It is now a superset of what it used to do, so
# every existing instruction to "run task lint-docs" is still true.
deps:
- lint-doc-links
- lint-markdown
- lint-prose
lint-doc-links:
desc: Check that every doc reference resolves — markdown links, and docs/**.md cited in Go comments
# Re-run whenever a doc moves or a Go comment changes. Task fingerprints these
# under .task/ and skips the run otherwise.
#
# This exists because nothing off the shelf covers the second surface: markdownlint
# does not check links, and link checkers (lychee, markdown-link-check) extract URLs
# from markdown -- they never look inside a Go comment for a repo-relative doc path.
# Those are the references that rot silently, and seventeen of them were dangling
# before this check was written.
# Deliberately un-fingerprinted: this task has no `sources:`, so it always runs.
#
# Its real input is "every git-tracked .md, .go, .yml, .yaml and .sh", which Task
# cannot express. Approximating it with globs went wrong twice. An unrooted
# '**/*.go' makes Task walk every path under the repo root -- including the 1.2 GB
# of upstream checkouts in external-sources/ -- and fingerprinting that costs tens
# of GB inside the Task process, enough to OOM the host. (`exclude:` does not help:
# Task expands the glob first and filters afterwards, so the walk still happens.)
# A hand-maintained per-tree list avoids that, but then silently drifts out of sync
# with the file types doccheck scans, and a stale "up to date" means the check
# never runs -- which is how a non-compiling file reached a commit here once.
#
# The whole check takes ~0.2s. That is not worth a cache that can be wrong.
cmds:
- go run ./hack/doccheck
lint-markdown:
desc: 'Markdown structure (markdownlint-cli2), over every tracked file. DOCS_SCOPE=gated narrows it'
# Scope is the whole tree. It started as the .docs-lint-scope list because 102 of
# the 174 linted files failed; that residue has since been cleared, so structure
# is gated everywhere and a new document cannot regress it. `DOCS_SCOPE=gated`
# narrows it back to the list, which is only useful when reproducing what the
# prose gate sees. See docs/design/docs-linting.md.
#
# No `sources:`. Same reasoning as lint-doc-links above: the real input is "every
# tracked .md", which Task cannot express without an unrooted `**` that walks
# external-sources/ and has OOM-killed the host. Both tools finish the whole tree
# in under three seconds, so this always runs. CI's cache assertion exempts it.
cmds:
- ./hack/docs-files.sh {{.MARKDOWN_SCOPE}} | xargs -r markdownlint-cli2
lint-markdown-fix:
desc: 'Apply the safe, mechanical markdown fixes (markdownlint-cli2 --fix)'
# Deterministic and reviewable rule by rule: blank lines, bullet style, hard tabs.
# It does NOT clear everything -- over the whole tree it fixes 466 of 723 findings
# and leaves 257 that need a human, led by MD013 line-length (119), MD040 missing
# fence languages (54), and MD036 emphasis-used-as-heading (43). There is no
# equivalent for prose: Vale can suggest, but nothing here rewrites English.
#
# Not `xargs`, unlike the two checking tasks, because this one has to tell the
# exit codes apart and xargs collapses every one of them to 123. Measured:
# 0 clean, 1 findings remain, 2 config or usage error. The word split is safe
# because git tracks no markdown path containing a space.
cmds:
- |
files="$(./hack/docs-files.sh {{.MARKDOWN_SCOPE}})"
[ -n "${files}" ] || exit 0
rc=0
# shellcheck disable=SC2086
markdownlint-cli2 --fix ${files} || rc=$?
# Exit 1 means findings remain, which is the normal outcome: --fix cannot
# repair a long line, a missing fence language, or bold used as a heading.
# Tolerated so `task lint-fix` still reaches the Go half. Never silent: the
# note below says work is left, and `task lint-markdown` names it.
[ "${rc}" -le 1 ] || exit "${rc}"
[ "${rc}" -eq 0 ] || echo "note: findings remain that --fix cannot repair; run 'task lint-markdown' to see them" >&2
lint-prose:
desc: 'Prose against docs/style-guide.md (Vale), over .docs-lint-scope. DOCS_SCOPE=all shows the backlog'
# Still scoped by .docs-lint-scope, unlike lint-markdown: 145 of the 167 linted
# files carry at least one error, almost all of them em dashes, and
# docs/style-guide.md says that cleanup must not land as one sweeping commit. The
# list grows as files are cleaned; `DOCS_SCOPE=all` shows the whole backlog.
#
# Vale's exit code tracks errors only, so the gate is EmDash, Spelling, and
# ProductName. Headings, WordsToCut, and Correctives print and do not block, which
# is what .vale.ini's level table is for.
cmds:
- ./hack/docs-files.sh {{.PROSE_SCOPE}} | xargs -r vale
lint-golang:
desc: Run golangci-lint
deps:
# The Helm lint branch also reaches manifests -> generate via helm-sync.
# Wait for generated Go/CRD files to settle before golangci-lint scans api/**/*.go.
- manifests
# golangci-lint's real inputs: the module's Go sources (including tests, which it
# lints), the lint config, and the dependency graph. The external-sources/* trees
# are separate modules and are not linted, so they are deliberately not listed.
sources:
- api/**/*.go
- cmd/**/*.go
- hack/**/*.go
- internal/**/*.go
- pkg/**/*.go
- test/**/*.go
- .golangci.yml
- go.mod
- go.sum
cmds:
- '{{.GOLANGCI_LINT}} run'
lint-actions:
desc: Lint GitHub Actions workflows with actionlint
# Re-lint whenever any workflow changes (glob covers new pipelines too).
sources:
- .github/workflows/*.yml
- .github/workflows/*.yaml
# No path arg: actionlint auto-discovers every workflow under
# .github/workflows/, so newly added pipelines are checked automatically.
cmds:
- actionlint
lint-dockerfiles:
desc: Lint the project Dockerfiles with hadolint
# Only re-lint when a Dockerfile or the hadolint config changes; Task
# fingerprints these (checksum) under .task/ and skips the run otherwise.
sources:
- .devcontainer/Dockerfile
- Dockerfile
- .hadolint.yaml
cmds:
- hadolint .devcontainer/Dockerfile Dockerfile
lint-helm:
desc: Lint the Helm chart with helm lint
# Depends on helm-sync so the chart's generated CRDs/role are present and current
# before linting -- a complete check that also works on a fresh checkout (e.g. CI),
# where those files are gitignored and absent. This pulls in manifests/controller-gen,
# which re-runs on every invocation, so `task lint` is not a strict no-op; that is an
# accepted trade for a complete check. The generated CRDs are gitignored, so the
# resync never produces a stray git diff. Fingerprint every chart YAML/template so an
# edit to a template *or* a regenerated CRD re-triggers the lint.
deps:
- helm-sync
sources:
- charts/gitops-reverser/**/*.yaml
- charts/gitops-reverser/**/*.tpl
cmds:
- helm lint charts/gitops-reverser
lint-fix:
desc: Apply every safe automatic fix (Go and markdown)
# Folds in lint-markdown-fix so there is one "fix what can be fixed" entry point.
# Both halves are deterministic. Neither touches prose: Vale findings are always
# hand-edits, by design, because a machine rewriting English changes meaning.
deps:
- lint-markdown-fix
cmds:
- '{{.GOLANGCI_LINT}} run --fix'
lint-config:
desc: Verify golangci-lint configuration
cmds:
- '{{.GOLANGCI_LINT}} config verify'
loc:
desc: Count lines of project code with scc (excludes vendored external-sources)
cmds:
- '{{.SCC}} --exclude-dir external-sources,vendor,bin,dist {{.CLI_ARGS}}'
gitops-layouts-baseline:
desc: Regenerate the GitOps layout corpus behavioural baseline (test/fixtures/gitops-layouts/support-today.md)
# The baseline is generated, never hand-edited, so that a change to the
# acceptance boundary shows up in review as a diff of exactly which fixtures
# moved and in which direction. See test/fixtures/gitops-layouts/README.md.
sources:
- test/fixtures/gitops-layouts/**/*
- internal/manifestanalyzer/**/*.go
- cmd/manifest-analyzer/**/*.go
- hack/gitops-layouts-baseline.sh
generates:
- test/fixtures/gitops-layouts/support-today.md
cmds:
- bash hack/gitops-layouts-baseline.sh
build:
desc: Build manager binary
deps:
- manifests
- fmt
- vet
cmds:
- go build -o bin/manager ./cmd
run:
desc: Run a controller from your host
deps:
- manifests
- fmt
- vet
cmds:
- go run ./cmd
docker-build:
desc: Build docker image with the manager
cmds:
- |
GIT_COMMIT="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
GIT_DIRTY=0
[ -z "$(git status --porcelain 2>/dev/null)" ] || GIT_DIRTY=1
BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
VERSION="$(git describe --tags --always --dirty 2>/dev/null || echo dev)"
VERSION="${VERSION#gitops-reverser-v}"
{{.CONTAINER_TOOL}} build \
--build-arg VERSION="${VERSION}" \
--build-arg GIT_COMMIT="${GIT_COMMIT}" \
--build-arg GIT_DIRTY="${GIT_DIRTY}" \
--build-arg BUILD_DATE="${BUILD_DATE}" \
-t {{.IMG}} .
docker-push:
desc: Push docker image with the manager
cmds:
- '{{.CONTAINER_TOOL}} push {{.IMG}}'
docker-buildx:
desc: Build and push docker image for cross-platform support
vars:
PLATFORMS: '{{.PLATFORMS | default "linux/arm64,linux/amd64,linux/s390x,linux/ppc64le"}}'
cmds:
- |
GIT_COMMIT="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
GIT_DIRTY=0
[ -z "$(git status --porcelain 2>/dev/null)" ] || GIT_DIRTY=1
BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
VERSION="$(git describe --tags --always --dirty 2>/dev/null || echo dev)"
VERSION="${VERSION#gitops-reverser-v}"
sed -e '1 s/\(^FROM\)/FROM --platform=\${BUILDPLATFORM}/; t' \
-e '1,// s//FROM --platform=\${BUILDPLATFORM}/' Dockerfile > Dockerfile.cross
{{.CONTAINER_TOOL}} buildx create --name gitops-reverser-builder || true
{{.CONTAINER_TOOL}} buildx use gitops-reverser-builder
{{.CONTAINER_TOOL}} buildx build --push --platform={{.PLATFORMS}} \
--build-arg VERSION="${VERSION}" \
--build-arg GIT_COMMIT="${GIT_COMMIT}" \
--build-arg GIT_DIRTY="${GIT_DIRTY}" \
--build-arg BUILD_DATE="${BUILD_DATE}" \
--tag {{.IMG}} -f Dockerfile.cross .
{{.CONTAINER_TOOL}} buildx rm gitops-reverser-builder || true
rm -f Dockerfile.cross
docker-push-dev:
desc: Build and push the image to your dev registry (DEV_IMG, set in .env)
requires:
vars:
- DEV_IMG
cmds:
- task: docker-build
vars:
IMG: '{{.DEV_IMG}}'
- task: docker-push
vars:
IMG: '{{.DEV_IMG}}'
dist-install:
desc: Generate the split installer bundle (dist/crds.yaml + dist/install.yaml) from the Helm chart
deps:
- helm-sync
sources:
- api/**/*.go
- internal/**/*.go
- cmd/**/*.go
- charts/gitops-reverser/Chart.yaml
- charts/gitops-reverser/values.yaml
- charts/gitops-reverser/templates/**
- charts/gitops-reverser/crds/*.yaml
- exclude: api/**/*_test.go
- exclude: internal/**/*_test.go
- exclude: cmd/**/*_test.go
- exclude: api/**/zz_generated.deepcopy.go
- exclude: internal/**/zz_generated.deepcopy.go
- exclude: cmd/**/zz_generated.deepcopy.go
generates:
- dist/crds.yaml
- dist/install.yaml
cmds:
- |
mkdir -p dist
# CRDs ship as their OWN file, applied FIRST. The bundle contains the reserved `default`
# ClusterProvider — a custom resource that cannot be applied in the same `kubectl apply` as
# the CRD defining it: kubectl builds its RESTMapper up front and fails with
# `no matches for kind "ClusterProvider"`. So: kubectl apply -f dist/crds.yaml, then
# kubectl apply -f dist/install.yaml. `helm install` is unaffected — it installs
# charts/gitops-reverser/crds/ in its own first phase, which is why --include-crds is gone
# here. Each chart CRD file already begins with its own `---`, so a plain cat is valid
# multi-doc YAML.
cat charts/gitops-reverser/crds/*.yaml > dist/crds.yaml
{{.HELM}} template {{.INSTALL_NAME}} charts/gitops-reverser \
--namespace {{.NAMESPACE}} \
--set labels.managedBy=kubectl \
--set createNamespace=true \
--set queue.redis.addr={{.DEFAULT_AUDIT_REDIS_ADDR}} \
--set queue.redis.auth.existingSecret=valkey-auth \
> dist/install.yaml
clean:
desc: Remove build artifacts, coverage, generated dist files, and stamps
cmds:
- rm -rf bin/ cover.out dist/ .stamps/