rig/CHANGELOG.md

74 lines
4.3 KiB
Markdown
Raw Normal View History

# Changelog
History before 0.1.0 lives in git — rig grew its version surface (`VERSION`,
`rig --version`, the side-by-side `versions/<v>` install layout; #35/#36)
on the way to cutting its first release, and this file starts there.
## Unreleased
### Fixed
- **The release suite accepts the ceremony's own tree** (#44) —
`test/release.sh` demanded a literal `## Unreleased` heading in the real
`CHANGELOG.md`, extracting non-empty and containing `#32`. All three are
false by construction on the `release: X.Y.Z` tree the ceremony's own PR
produces (it stamps that heading into `## X.Y.Z — date`), so the first
real release PR turned CI red and the flow blocked itself — invisible to
both fork rehearsals, which tag a branch (`release.yml` runs; `ci.yml`
never does). The guard now asserts what it was for: whatever the TOP
`## ` section is — `Unreleased` between releases, the stamped version on
and right after one — the exact `changelog_section` the workflow runs
extracts it non-empty. The rotting issue-number grep is gone.
- **Headless credential prompts refuse loudly instead of dying silently**
(#42) — the interactive credential prompts (`TS_AUTHKEY` in `bootstrap`,
`RUNNER_TOKEN` in `runner install`, `RUNNER_REMOVE_TOKEN` in
`runner remove`, and both tokens in `runner repoint` — a site the new
no-bare-read test caught after the issue counted three) were bare
`read -rsp`: with stdin not a tty (CI,
`box exec`, any script), `read` fails, `set -e` ends the run, and the
log just *stops* — exit 1, no last word, measured live in the
2026-07-19 release drill. Each prompt now checks for a tty first and
dies naming the variable that unblocks an unattended run (`runner
remove` also names `--local`), and every `read` is `|| die`-guarded so
EOF at a real prompt gets the same courtesy. `db.sh` already held the
line here; now all of rig does.
### Added
feat: merging a release-labeled PR is the release (#47) The rig twin of heavy-duty/box#96, from the release-ceremony retro: the tag was a separate, manual, silent-when-forgotten step, and a forgotten tag produces no red X — the worst failure shape. The ship decision already lives in the release PR; merging it is "ship". After that, tagging is transcription, and transcription belongs to machines. release.yml now also fires on pull_request closed into main, gated on merged AND the `release` label. The job asserts in order, each fail-loud and creating nothing: VERSION at the merge commit is non--dev; VERSION changed in THIS PR (base vs merge — the interlock that fails a mislabeled ordinary PR); the changelog section for that version extracts non-empty via the existing changelog_section from release-lib.sh; and no tag or release exists yet. Then, in the same job, it API-creates the tag at the merge commit and publishes the release with the extracted notes. Same-job is load-bearing: a GITHUB_TOKEN-created tag does not fire the tag-push trigger, so the publish must live next to the tag and the fallback job cannot double-publish; the nothing-exists assert covers a manual race. The tag-push path survives verbatim as the documented manual fallback and backfill, and CONTRIBUTING's Releasing section now reads merge-is-ship with the manual tag as fallback. test/release.sh pins the merge path in the house grep-pin style: the merged+labeled gate, the four asserts, the same-job tag+publish (awk from release-on-merge: to EOF), the asserts-precede-the-tag ordering, and the surviving tag-push trigger. Fixes #47 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 15:19:47 +00:00
- **Merging a release-labeled PR IS the release** (#47) — the rig twin of
heavy-duty/box#96, born of the ceremony retro: the tag was a separate,
manual, silent-when-forgotten step, and a forgotten tag produces no red
X. `release.yml` now also fires when a PR into main closes, gated on
merged AND the `release` label, and asserts in order — fail-loud,
creating nothing: `VERSION` at the merge commit is non-`-dev`; `VERSION`
*changed in this PR* (the interlock that fails a mislabeled ordinary PR);
the changelog section for that version extracts non-empty via the same
`changelog_section`; no tag or release exists yet. Then, in the same job,
it API-creates the tag at the merge commit and publishes the release with
the extracted notes. A `GITHUB_TOKEN`-created tag never fires the
tag-push trigger, so the paths cannot double-publish — and that tag-push
path survives intact as the documented manual fallback and backfill.
- **Tagged releases, and an installer that installs them** (#32) — the rig
half of the flow designed in heavy-duty/box#83, near-verbatim. A release
is a PR, then a tag: the `release: X.Y.Z` PR bumps `VERSION` and stamps
this file's Unreleased section with version + date; the merge commit is
tagged bare `X.Y.Z` (box's tag scheme — no `v` prefix). `release.yml`
turns the tag into the GitHub release — after asserting tag == `VERSION`
(mismatch fails loudly and creates nothing) — with that version's section
of this file as the body, extracted by the same `changelog_section` the
test harness drives. No assets: for a pure-bash tree, GitHub's source
tarball for the tag IS the package. `install.sh` now defaults to the
**latest release**: the tag is resolved by following the
`releases/latest` redirect and reading the `Location` header — no API, no
token — and the download is `archive/refs/tags/<tag>.tar.gz`. `RIG_REF`
picks the other two channels: a tag pins (`refs/tags` outranks a
same-named branch), a branch (`RIG_REF=main`) tracks the development
tree. Until 0.1.0 is cut the default channel has nothing to resolve and
dies saying exactly that, naming `RIG_REF=main` as the way to install
today — it never falls back to main silently, because "I installed the
latest release" must not quietly mean "I installed whatever main was that
second". Step 5 of #32 — pinning `BOX_REF` in the host-installs-box path
— stays open until box cuts its next tagged release.