From 446380e3a928664420ad8fd09f8ff543dcaa3030 Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Tue, 18 Aug 2026 19:40:43 -0400 Subject: [PATCH] docs: a CI-only change is ci:, not fix(ci): The commit-analyzer reads the type and ignores the scope, so `fix` is a patch whatever sits in the brackets. Two commits touching nothing but .gitea/workflows/unclaim.yml were written `fix(ci):` and cut v0.2.1 and v0.2.2 -- real releases, published to Arch, Homebrew and the APK registry, containing no user-facing change. CLAUDE.md already warned that a mistyped feat ships a minor version. That was not enough, because this was not a mistyped type: `fix` was chosen deliberately, in the belief that the (ci) scope qualified it. The version bump is the small half, which is why this gets a paragraph rather than a clause. A merge to main starts two workflows; if release.yml then pushes a tag, that tag push starts four more -- arch-package, homebrew-formula, android-apk and desktop-assets -- on a runner with capacity 1, where the APK build alone is tens of minutes and publishes a signed artifact to a public registry. So a mistyped type is six workflow runs, not an odd-looking changelog. `make release-dry` answers this before the merge instead of after, and is cheaper than any one of those runs. The two releases are staying: they are already published, and a version that vanishes is worse for whoever pulled it than one that turns out to be empty. Closes #111 --- CLAUDE.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index a2b6346..0f75b48 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2369,6 +2369,23 @@ Pre-commit hooks verify generated code is fresh — always run `make generate` a mistyped `feat` ships a minor version. `make release-dry` answers "what would this merge release" without pushing. + **The analyzer reads the type and ignores the scope, so a CI-only change + is `ci:` and never `fix(ci):`.** The scope is decoration; `fix` is a + patch whatever is in the brackets. Two commits touching nothing but + `.gitea/workflows/unclaim.yml` were written `fix(ci):` and cut `v0.2.1` + and `v0.2.2` — real releases, published to Arch, Homebrew and the APK + registry, containing no user-facing change. They were left in place + rather than deleted, because a version that vanishes is worse for + whoever pulled it than one that turns out to be empty. + + **The blast radius is bigger than the version number**, which is what + makes this worth a paragraph. A merge to `main` starts two workflows; + if `release.yml` then pushes a tag, that tag push starts **four more** + (`arch-package`, `homebrew-formula`, `android-apk`, `desktop-assets`) — + on a runner with capacity 1, where the APK build alone is tens of + minutes. `make release-dry` before merging is how you find out, and it + is cheaper than every one of those. + **`@semantic-release/github` is not in that config and must not be.** Gitea's API is `/api/v1` and is not GitHub's surface, so `@semantic-release/exec` calls `scripts/gitea-release.sh` instead — one