926396352f
Three things the merge with #120 (ui/shell-polish) actually required, none of which a clean auto-merge could have told us. MOVED, not preserved. #120 left <header>'s markup alone but gave every child explicit styling and a stated reading order -- "what this is, which document, which view, which mode, what keys, what the peer is doing". A build identifier is "what this is", so the span moves from after #status to beside <h1>. Keeping it at the tail was loyalty to my own first draft: it read as metadata trailing #status, and with #hint's `flex: 1 1 auto` fighting for the slack a 40-char commit SHA there is the thing that crowds the bar. STYLED, because unstyled is illegible-by-default in a design system. It takes `var(--dim)` -- the same token #hint and #status use, so it tracks both themes by construction rather than by a hand-picked colour -- at 0.72rem, and clamps to 14ch. Measured under Chromium on the merged tree: a tag renders whole (scrollWidth == clientWidth, 69px), a 40-char SHA truncates to a 13-character prefix with an ellipsis, and `header` does not overflow in either case (scrollWidth == clientWidth == 1280). Contrast of rgb(107,103,95) on rgb(244,241,234) is ~5.0:1, above AA for small text. Selecting the text still copies the whole SHA -- text-overflow is a rendering clamp, not a truncation. NOT AN ID. `improvise-web.tar.gz` puts the token `improvise-web` in the tree, and AGENTS.md's audit matches `improvise-[a-z0-9]{3,8}` -- so the artifact name resolved to no ticket and read exactly like a dead id, which AGENTS.md calls worse than one. `improvise-installer.sh` escapes only by being ten characters, which is luck rather than a rule, so the exclusion list gains `web` and the paragraph gains the general case. RELEASING.md (which arrived in this same merge, from improvise-gx5d) listed what a tag publishes and was made wrong by omission; it now names the web capture and says plainly that it is not what Pages is serving. Verified on the merged tree: 1631 cargo tests over 37 binaries, node --test 47 -> 50 (so #120's three new shell tests survived the merge rather than being silently dropped), 42 Playwright tests green under Chromium, and the stamp gate re-proved by injecting the missed substitution again -- a header rewrite does not carry the old fault injection. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
84 lines
3.9 KiB
Markdown
84 lines
3.9 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`, `improvise-installer.sh` and
|
|
`improvise-web.tar.gz` — the assembled landing page and browser app, stamped
|
|
with the tag, which the page then shows in its header (improvise-oujb).
|
|
|
|
**`improvise-web.tar.gz` is a self-hostable copy and a rollback target, not
|
|
what the published site is serving.** GitHub Pages tracks `main` and a tag
|
|
does not deploy it, so the site and the release are deliberately different
|
|
code. Two things follow when the web half goes wrong. `release.yml` is
|
|
autogenerated, so never hand-edit it: change `dist-workspace.toml` and re-run
|
|
`dist generate`, which should leave the workflow byte-identical. And a
|
|
**pull-request** run of the Release workflow skips `build-global-artifacts`,
|
|
so a green PR says nothing about the web capture — to exercise it without
|
|
cutting a tag, run `dist build --artifacts=global` locally.
|
|
|
|
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.
|
|
|
|
The worked example is `v0.1.0-rc3`: it was pushed while every crate still said
|
|
`0.1.0-rc2`, `dist` refused, and the four jobs behind `plan` skipped. No release
|
|
was ever built from it.
|
|
|
|
**Ask which tags exist; do not trust a document that tells you.** `git tag -l`,
|
|
and `git ls-remote --tags <remote>` for each remote you push to. Which tags are
|
|
where is a fact with a shelf life — it changed twice while this file was being
|
|
written — so this file deliberately records no inventory of it. Cleaning up a
|
|
dead tag is a separate decision and is not a step in cutting a release.
|