Skip to content

docs: add a release skill - #237

Merged
retr0h merged 3 commits into
mainfrom
docs/release-skill
Oct 1, 2026
Merged

retr0h merged 3 commits into
mainfrom
docs/release-skill

Conversation

@retr0h

@retr0h retr0h commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

/release for cutting a release in an osapi-io Go repository. One file.

We hit three of its four traps in a single afternoon, so they belong somewhere other than a transcript.

What it records

A valid tag is not a current one. gohai had a perfectly good v1.0.0 and 81 commits sitting behind it. I looked at the tag list, saw a valid semver, and said it was fine. The check that catches this is compare/<tag>...main --jq .ahead_by, not the tag list.

Go requires three-part versions. nats-client and nats-server were tagged v1.0. The module proxy ignores it, so both served v0.0.0-2026... pseudo-versions while looking released. An empty @v/list on a repo that has tags is the symptom.

A tag that fires a workflow which cannot authenticate leaves a tag with no release, and the tag is the half that cannot be taken back. GH_PAT had expired and nats-client's v1.0.1 landed without a release. The skill checks the workflow uses secrets.GITHUB_TOKEN before tagging, and explains why no repo here needs a PAT: none of the .goreleaser.yaml files has brews:, dockers:, nfpms: or publishers:, so nothing publishes outside its own repo.

A version the proxy has fetched is permanent. It is in sum.golang.org, which is append-only. Deleting and re-pushing that tag at another commit makes go get report a checksum mismatch, which Go treats as tampering rather than as a mistake. The skill says to create the missing release against the existing tag, and records that re-running the failed workflow does not work, because a re-run uses the workflow file as it was at that tag's commit and so does not include a token fix merged afterwards.

Version rule

feat: commits since the last tag mean a minor bump, fix: and chore: alone mean a patch. A repo that has never been tagged starts at v0.1.0, because v1.0.0 is a promise about API stability and a library makes that once. The first release of an application is a product decision, so the skill says to ask rather than pick.

It also names the two repos that should never be tagged: osapi-justfiles is consumed by curling from refs/heads/main, and specs is documentation.

just test passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c

Releasing turned out to have four traps and we hit three of them in one
afternoon, so they belong somewhere other than a transcript.

A valid tag is not a current one. gohai had a perfectly good v1.0.0 and
eighty-one commits sitting behind it, and the check that would have caught
that is ahead_by rather than the tag list.

Go requires three-part versions. nats-client and nats-server were tagged
v1.0, which the module proxy ignores, so both served pseudo-versions while
looking released.

A tag that fires a workflow which cannot authenticate leaves a tag with no
release, and the tag is the half that cannot be taken back. The GH_PAT
secret expired and nats-client's v1.0.1 landed without one.

A version the proxy has fetched is in sum.golang.org permanently. Deleting
and re-pushing that tag makes go get report a checksum mismatch, which Go
treats as tampering. The skill says to create the missing release against
the existing tag instead, and records that re-running the failed workflow
does not work because a re-run uses the workflow file as it was at that
tag's commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c
retr0h and others added 2 commits October 1, 2026 09:26
The rule said any feat: is a minor bump, which is how it produced exactly
the wrong answer for both nats repositories on the same afternoon it was
written.

nats-client had seven feat: commits and nats-server two, so counting made
nats-client look like the smaller release. nats-client's seven were Object
Store support, core Subscribe and PublishCore, KV CreateOrUpdate and OTel
trace propagation. nats-server's two were a justfile recipe and a coverage
gate, which no consumer can call. The recommendation that came out was
v1.0.1 for the repository with seven API additions and v1.1.0 for the one
with none.

The rule is now to read the list and ask which entries changed something a
consumer can call. The worked example is in the skill, because the failure
is not obvious from the rule alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c
Every other skill has a README and a row in the repository index. This one
shipped with neither, so it was findable only by an agent already looking
in .claude/skills.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c
@retr0h
retr0h merged commit d319c48 into main Oct 1, 2026
5 checks passed
@retr0h
retr0h deleted the docs/release-skill branch October 1, 2026 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant