Skip to content

feat(release): a stable channel that becomes releases/latest - #1035

Merged
Juliusolsson05 merged 4 commits into
mainfrom
feat/release-stable-channel
Sep 19, 2026
Merged

Juliusolsson05 merged 4 commits into
mainfrom
feat/release-stable-channel

Conversation

@Juliusolsson05

Copy link
Copy Markdown
Owner

Why (Stage 8 of the release-readiness ledger)

release.yml could not make a production release:

  • The publish step hardcoded prerelease: true and never set make_latest.
  • Every release on GitHub is a prerelease, so releases/latest, and with it the landing page's stable download button, returns 404.
  • The dispatch inputs defaulted to v0.0.2-beta.1, a release that already exists.

Change

  • A new channel input: prerelease (default; exactly what every beta was) or stable.
  • scripts/release/identity.mjs replaces the inline identity bash, following nightly.mjs's pattern:
    • it derives the tag and name from package.json when the inputs are empty;
    • it emits tag, name, prerelease and make_latest;
    • it refuses a mismatch before the 26-minute build: a stable channel with a -beta version, a prerelease channel with a stable version (which would take the stable tag), a tag that doesn't match package.json, or an unknown channel.
  • validate-release exposes those outputs. package-macos now also needs validate-release, and publishes with them. A beta is never made latest.
  • The drift mirror (reusable-app-build-macos.yml) has no publish step, so nothing needs mirroring.

Tests

testing/system/release/identity.test.ts: 8 cases that run the script as a real process with the workflow's env and a real GITHUB_OUTPUT file. The versions are the real published beta (0.0.2-beta.1) and the planned stable (0.1.0).

The workflow YAML parses, and @action-validator/cli passes.

Not in this PR

The version bump itself: 0.1.0 is the ledger default and still an owner call.

🤖 Generated with Claude Code

Juliusolsson05 and others added 4 commits September 19, 2026 01:01
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A stable release of 0.1.0 is v0.1.0, not a prerelease, and becomes latest.
A prerelease is exactly what the betas were. The default is prerelease.
Channel and version must agree both ways, the tag must match package.json,
and an unknown channel is refused before any build. The versions are the
real published beta and the planned stable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
release.yml hardcoded prerelease: true and never set make_latest, so no
stable release could be made and releases/latest (the landing page's
download button) 404'd. Its tag and name defaulted to v0.0.2-beta.1, a
release that already exists.

A new channel input (prerelease by default, or stable) goes through
scripts/release/identity.mjs. That script derives the tag and name from
package.json, refuses a mismatched channel, version or tag before the
build, and emits prerelease and make_latest for the publish step. A beta
is never made latest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… metadata

From the #1035 review (APPROVE with recommendations):
- target_commitish is the built SHA. A stable release is published from
  a draft, and GitHub creates the tag then, on the default branch's head
  at that moment, which can be a commit merged during the build.
- A newline in release_name could append tag= to GITHUB_OUTPUT and
  replace the validated tag, so line breaks are refused.
- 0.1.0+build-5 was read as a prerelease; only the version core decides.
- The prerelease-of-a-stable error now suggests the NEXT patch's beta,
  which sorts after the stable.
- Re-publishing an older stable taking latest back is documented as a
  known limit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Juliusolsson05

Copy link
Copy Markdown
Owner Author

Review (APPROVE) recommendations applied in 239b3c59:

  • target_commitish: ${{ github.sha }}, so the tag names the commit that was built.
  • Line breaks in the tag or name are refused.
  • +build metadata no longer reads as a prerelease.
  • The error message now suggests the next patch's beta.
  • Re-publishing an older stable, which takes latest back, is documented as a known limit.

11/11 tests pass and actionlint is clean. I'll merge once CI is green.

@Juliusolsson05
Juliusolsson05 merged commit 39323fd into main Sep 19, 2026
2 checks passed
@Juliusolsson05
Juliusolsson05 deleted the feat/release-stable-channel branch September 19, 2026 08:34
Juliusolsson05 added a commit that referenced this pull request Sep 20, 2026
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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