Skip to content

Release on merge: one approval releases everything merged since the last release - #45

Merged
jasperblues merged 7 commits into
mainfrom
release-on-merge
Oct 28, 2026
Merged

jasperblues merged 7 commits into
mainfrom
release-on-merge

Conversation

@jasperblues

Copy link
Copy Markdown
Member

Releasing desk took a Prepare release run, a release PR, a merge and an approval, and a feature wasn't out until someone remembered to do all four. Now a merge is the release, held for one approval.

How it works (RELEASING.md has it all):

  • A merge to main that changes what the package ships (src/, README, llms.txt, package.json, the files that build it) starts Release: plan, CI gate, a dry-run pack, then a release job that waits in the release environment.
  • Batching. One release runs at a time and GitHub queues one more, a newer merge's replacing an older one's. Approve the one waiting: it releases everything merged since the last release, as one version. If more merged after its own merge, it says it was overtaken and does nothing, and the newest merge's release waits next.
  • Provenance names what was built. The job publishes its run's own commit, never a later main.
  • The version comes from scripts/release-plan.sh: the last release (newest tag, or npm's latest if later), bumped by the biggest change merged since. A release: major|minor|patch|none label decides; without one, a PR that changes src/ is minor, one that changes only other shipped files is patch, and one that ships nothing is none.
  • After publishing, the job commits the version to main ("Release vX.Y.Z", only package.json and the lock), tags it, and creates the GitHub release with notes since the last one.
  • Prepare release goes. A manual run of Release is a dry run, or, on main with publish ticked, releases what main holds.

Safety. It refuses to release on top of a version npm has but no tag records, stops the plan on any GitHub error rather than guessing a bump, retries the merge into main (with -X theirs, as the release commit changes only version lines), and gives the hand recovery for each failure in RELEASING.md. A pull request can't publish: the release environment deploys only from main, and npm's trusted publisher is bound to it.

Tested by simulating each step from the YAML under bash -e -o pipefail against local repos: fast-forward and moved main, conflicts, a same-version main, and sequences of merges approved in each order, including a release landing while another waits. release-plan.sh was run read-only against this repo: since v0.36.0 it finds #42 (none) and #43 (minor). npm run check passes.

Merging this starts no release, as it ships nothing.

…all of main as one version

A merge that changes what the package ships starts a release, which waits in the release environment. Approved, it releases main as it is then, versioned by scripts/release-plan.sh from the biggest change merged since the last tag: a release label on a pull request, or else what its files are. It publishes with provenance, commits the version to main, tags it and creates the GitHub release. Prepare release and release PRs go.
…re, and survive a same-version or conflicting merge

- release-plan.sh: only an unknown commit (HTTP 422) counts as pushed straight to main; any other gh error stops the plan instead of planning a minor. The release-commit skip matches a whole Release vX.Y.Z subject.
- publish.yml: the release plan step sets pipefail, so tee can't hide the plan failing, and requires npm reachable.
- publish.yml: the release commit allows a version main already has, a failed merge aborts and retries and ends with the hand-merge message, and a pull request changing release-pack.sh runs the dry run.
- RELEASING.md: the hand merge uses the workflow's message, and the GitHub release is made by hand after it.
…use the same script; Drivine has none, and none with bump
@jasperblues
jasperblues merged commit 20b77b6 into main Oct 28, 2026
5 checks passed
@jasperblues jasperblues mentioned this pull request Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant