b5a4d227fe
FOUND BY RUNNING THE COMMAND THE CLAIM IMPLIED. `git ls-remote --tags` against each of gh, origin and gitea: v0.1.0-rc3 exists on gh ONLY. origin and gitea carry v0.1.0-rc1 and v0.1.0-rc2 and nothing else. The claim originates in aa4e901's commit message and was repeated from there into context/code/tooling.md and, an hour ago, into RELEASING.md by me -- three copies of a fact nobody had asked a remote about. That commit message is superseded on this point and cannot be corrected, which is the case context/design-principles.md section 6 makes for not letting an argument live only in one; the correction is therefore recorded in tooling.md, naming the commit. The irony is local. The false claim sat two paragraphs from the sentence "an empty log is a statement about RETENTION, not about history", which is the same failure in the same section: a fact about a remote asserted instead of asked. Writing that sentence did not stop me repeating the neighbouring instance of it, which is the more useful half of this commit. What it changes and what it does not. The rule is untouched -- a published tag is not moved, and gh is the remote carrying the release machinery, so the preflight's reason for existing is unaffected. What moves is the SCOPE of any cleanup, from three remotes to one, and that is precisely the sort of detail a reader following RELEASING.md at 2am would act on. RELEASING.md now says which remote and tells the reader to run ls-remote rather than assume the mirrors agree -- they did not. No version bumped, no tag cut, no tag deleted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
72 lines
3.0 KiB
Markdown
72 lines
3.0 KiB
Markdown
# Releasing
|
|
|
|
A checklist, not an explanation. The reasoning is `context/code/tooling.md` §4;
|
|
read it if a step surprises you, not before.
|
|
|
|
Its own file rather than a `README.md` section because `README.md` §Installation
|
|
addresses someone *installing* improvise and this addresses the one person
|
|
*publishing* it — folding them together lengthens the user-facing document for
|
|
no user benefit.
|
|
|
|
## The one rule
|
|
|
|
**Bump the version and commit it BEFORE you tag.** `dist` matches the tag
|
|
against the root package's version and refuses when they disagree — and by the
|
|
time CI tells you, the tag is already published and a published tag is not
|
|
moved. Every step below exists to put that check before the irreversible one.
|
|
|
|
## Cutting a release
|
|
|
|
1. **Bump the version.** `Cargo.toml`'s `[package]` version is the one `dist`
|
|
announces (`dist-workspace.toml` says `members = ["cargo:."]`). Keep the
|
|
crates under `crates/` in step with it; `gp-tree` sits at its own version
|
|
deliberately, and the preflight lists such crates as a note rather than an
|
|
error.
|
|
|
|
2. **Commit the bump**, and let `Cargo.lock` be part of that commit.
|
|
|
|
3. **Run the preflight**, with the tag you intend to push:
|
|
|
|
```sh
|
|
scripts/release-preflight.sh vX.Y.Z
|
|
```
|
|
|
|
It refuses a dirty tree, refuses a tag that does not match the version, runs
|
|
`dist plan` as a second opinion when `dist` is on `PATH`, and prints the tag
|
|
commands only once it has passed. It cuts nothing itself.
|
|
|
|
4. **Tag and push**, using the commands it printed:
|
|
|
|
```sh
|
|
git tag -a vX.Y.Z -m "vX.Y.Z"
|
|
git push gh vX.Y.Z
|
|
```
|
|
|
|
Push the tag to **`gh`** — `.github/workflows/release.yml` triggers on a tag
|
|
push there, matching `**[0-9]+.[0-9]+.[0-9]+*`. `origin` and `gitea` are
|
|
mirrors and build nothing.
|
|
|
|
5. **Watch the run.** A green release takes about three minutes and publishes
|
|
tarballs for all four targets with their `.sha256` files, `sha256.sum`,
|
|
`dist-manifest.json`, `source.tar.gz` and `improvise-installer.sh`.
|
|
|
|
The failure signature is unmistakable once you know it: **`plan` fails in
|
|
about twenty seconds and the four jobs behind it skip.** That is the tag not
|
|
matching the version — see below. A run that gets past `plan` is building.
|
|
|
|
## When a tag has already been pushed against the wrong version
|
|
|
|
**Leave it dead and cut the next one.** Do not move or re-push the tag: it is
|
|
already public, and a published tag that changes meaning is worse than one that
|
|
never built. Bump to the next version, commit, run the preflight, and tag that.
|
|
|
|
`v0.1.0-rc3` is the standing example — pushed to `gh` while every crate still
|
|
said `0.1.0-rc2`, so `dist` refused and the four jobs behind `plan` skipped. It
|
|
has no GitHub release and is left as it is. (It is on `gh` **only**; `origin`
|
|
and `gitea` carry `rc1` and `rc2`. Check with `git ls-remote --tags <remote>`
|
|
rather than assuming the mirrors agree — they did not.)
|
|
|
|
A tag with no release is not a tag to clean up on the way to cutting one;
|
|
whether the stale `rc` tags are ever removed is a separate decision, and not a
|
|
step here.
|