From 5f9c202d653771b478bcaa94698c77997db28dc2 Mon Sep 17 00:00:00 2001 From: Niklas Ye Date: Tue, 1 Sep 2026 22:09:15 +0200 Subject: [PATCH] =?UTF-8?q?Beskriv=20hur=20ett=20sl=C3=A4pp=20g=C3=A5r=20t?= =?UTF-8?q?ill,=20och=20vad=20som=20=C3=A4r=20s=C3=A4rskilt=20h=C3=A4r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Repot kom in under den gemensamma släppprocessen i 1081260 utan att någon dokumentation sa det. README hade Kubernetes och Development men ingenting om vägen från en commit till något som rullar i klustret, och till skillnad från riksdata och rd-web fanns ingen CLAUDE.md alls. Två saker om just det här repot är värda att stå skrivna, eftersom båda avviker från syskonrepona och båda upptäcktes mitt i ett släpp: Pipelinen har ingen bildskanning. riksdata och rd-web kör trivy efter publiceringen; .gitea/workflows/release.yaml här har test, binaries, image och chart och inget mer. Ett grönt släpp är alltså inget belägg för att bilden är fri från kända sårbarheter, och en släppnot får inte antyda det. Wrapperchartets values.yaml har två tag:-rader, appbilden och python-sidovagnen för säkerhetskopiering, så chart-bump behöver --image för att veta vilken som flyttas. Utan den vägrar den, vilket är rätt. Samtidigt: varför det inte finns några build- eller push-mål, varför chartet publiceras enbart från taggen (766f439), och varför make test kör -race när CI inte gör det. Helm-exemplet pekade fortfarande på 0.9.0 och går till 0.9.2. Claude-Session: https://claude.ai/code/session_01S7R4gWTz5wh5xCY4nCSJjN --- CLAUDE.md | 32 ++++++++++++++++++++++++++++++++ README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6c69290 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,32 @@ +## Release + +Say **"Release"** (or "Release X.Y.Z") and the `release` skill runs it: commit, push, tag, +wait for the pipeline, then open the wrapper-chart PR against `Ryuvia/charts`. It stops +there — merging and the Flux reconcile stay manual, deliberately. + +Preconditions and the plan, without side effects: + +```sh +~/.claude/skills/release/scripts/release-preflight # state + suggested version +~/.claude/skills/release/scripts/release-preflight vX.Y.Z # validate that release +``` + +Config is `.release.conf` here plus `make release-vars`. The process itself lives in +`~/.claude/skills/release/`; why it is shaped this way is in README.md §Releasing. + +Two things about this repo specifically: + +- **The pipeline has no image scan.** `.gitea/workflows/release.yaml` runs `test`, + `binaries`, `image` and `chart`. A green release run is not evidence the image is + CVE-clean, and a release note must not imply it is. +- **The wrapper chart has two `tag:` lines** — the app image and the python backup sidecar — + so `chart-bump` needs `--image "$IMAGE"` to know which one moves. + +## Checks + +`make fmt lint test helm-lint` mirrors `.gitea/workflows/ci.yaml`, so a green gate here means +a green pipeline there. The one deliberate difference is `-race`, which CI does not run; see +the comment on the `test` target. + +There are deliberately no `build`/`push`/`helm-push` targets — the workflow owns publishing, +and it builds multi-arch. Publishing happens by pushing a tag. diff --git a/README.md b/README.md index cd200c0..013a08a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ with the app — chart `x.y.z` is always app `vx.y.z`: ```bash helm upgrade --install terdut-server oci://git.ryuvia.com/niklas/terdut-server \ - --version 0.9.0 \ + --version 0.9.2 \ --namespace terdut-server --create-namespace \ --set networking.hostname=terdut.example.com ``` @@ -661,3 +661,52 @@ go test ./... # run all tests go build ./... # compile all packages go run ./cmd/terdut # run locally ``` + +`make fmt lint test helm-lint` is the gate. It mirrors `.gitea/workflows/ci.yaml` step for +step, so a green run here means a green pipeline — with one deliberate exception: `make test` +adds `-race`, which CI does not. The sweeper, the notifier goroutine and the dead man's switch +sweep all touch the same single database connection, and a race between them would surface as +a flaky incident in production rather than as a red build. + +## Releasing + +``` +push to main → ci.yaml gofmt, go vet, go test +push tag vX.Y.Z → release.yaml same gate, then publish: + git.ryuvia.com/niklas/terdut-server:vX.Y.Z + oci://git.ryuvia.com/niklas/terdut-server X.Y.Z +PR to Ryuvia/charts → bump the wrapper chart to X.Y.Z; on merge + Flux reconciles and the release rolls out +``` + +Both artifacts go to the **personal** Gitea namespace rather than `ryuvia`, because Gitea +scopes package visibility to the owner with no per-package override — so `ryuvia/*` is private +because the org is. Publishing to `niklas` keeps them anonymously pullable, which is why no +pull secret is needed in the cluster. Same reasoning, and the same choice, as riksdata and +rd-web. + +Saying **"Release"** runs all three rows: the `release` skill commits, pushes, tags, waits for +the pipeline, and opens the `Ryuvia/charts` PR, stopping before the merge. See +`~/.claude/skills/release/`, or `.release.conf` here for this repo's part of it. + +The chart is published **only** from the tag, by the `chart` job. There used to be a second +publisher on every `charts/**` push to main, and the two raced for the same chart version with +different answers — chart 0.9.0 went out reading `appVersion: "latest"` that way. One +publisher, triggered by the tag (`766f439`). The cost is that a chart-only change has no +version of its own and rides the next app tag. + +There is deliberately **no** `make build` / `make push`. The workflow builds +`linux/amd64,linux/arm64` through buildx; a local single-platform push would land on top of +the multi-arch tag and stay invisible, because the tag would still resolve — just not on +arm64. Publishing happens by pushing a tag. + +Two things the release process needs to know about this repo: + +- **The pipeline has no image scan**, unlike riksdata and rd-web. A green release run is not + evidence the image is CVE-clean. +- **The wrapper chart's `values.yaml` has two `tag:` lines** — the app image and the python + backup sidecar — so `chart-bump` is given `--image` to say which one moves. + +The wrapper chart must have **its own `version:` bumped in the same commit**. Flux reconciles +with `reconcileStrategy: ChartVersion`, so a chart whose version did not change produces no +new artifact and the change is never deployed — with no error anywhere.