colophon
Tag the commit that actually landed.
A release orchestrator for any repository that uses Conventional Commits. It works out the version your commits have earned, opens the release as a merge request, and then tags the commit that actually landed on the target branch, resolved from the target itself rather than read back from the forge. Fast-forward merges, squashes, and a forge that reports a request merged a moment before its commit is reachable all end up tagging the right thing.
plan
Compute the next version and the commits that decide it, and print them. Writes nothing: no branch, no merge request, no tag. Safe to run anywhere, and the instrument for comparing colophon against the tool it replaces before a project switches.
propose
Re-cut the release branch from its target, write the changelog into it, and open or update the merge request that proposes the release. The branch is cut from the target on every run rather than kept up to date with it, so the merge request can never be behind.
publish
Find the merged release request, resolve the commit that actually landed on the target, tag it, and create the release on that tag. Safe to re-run: an already-tagged commit and an already-published release are not errors.
The thirty-second version¶
Ask what the commits so far have earned. Nothing is written, so this is safe anywhere:
$ colophon plan
0.40.0 → 0.41.0 (minor)
Decided by 3 commits:
87a7e68e minor feat(setup): say which refusal a forge returned
29f61ac2 patch fix(deps): take the forge family to the current round
15734d14 patch perf(generator): let a generation skip the golangci-lint pass
7 commits moved nothing.
propose turns that into a merge request. publish tags it once it has merged.
That last step is the one most release tooling gets subtly wrong. Under a fast-forward merge without a squash, a merge request's body is not in git, so the version cannot be read back out of it. And a forge will report a request merged a moment before its commit is reachable on the target, so anything that asks the forge which commit landed can be told the wrong one, or none at all.
colophon resolves the commit against the target branch itself, and takes the version from the changelog at that commit. The tag lands on what merged, rather than on what the forge said merged.
Status¶
Released, pre-1.0. colophon cuts its own releases, so every tag on this repository is one it resolved and created itself, and each one is published to the Go module proxy. The current version is whatever is at the top of the releases page; this page deliberately does not name it, because a version typed into prose is stale the next time the tool releases itself and has been three times already.
@latest above is right for trying it on your own machine. In a pipeline, pin
the tag: colophon decides what ships, so a job installing @latest can change
that decision without a commit saying so, and below 1.0 the CLI surface may
still move between minor versions.
Further reading¶
Everything written about the estate, including the curated guides, is on the blog.
Ask phpbotscout

He answers questions about the projects over on the Discord, citing the docs where they already cover it, and offering to raise an issue where they don't. Bring a bug, an idea, or a questionable engineering decision.