Skip to content

Release from GitHub Releases with versions derived from commits - #27

Merged
lambdalisue merged 2 commits into
mainfrom
feat/release-flow
Oct 10, 2026
Merged

lambdalisue merged 2 commits into
mainfrom
feat/release-flow

Conversation

@lambdalisue

Copy link
Copy Markdown
Member

Summary

  • Releases come from GitHub Releases. Publishing a Release with a calendar tag (v20261008.01) runs publish.yml, which plans the versions, attaches versions.json, appends a version table (with the commits per package) to the release notes, and publishes the released packages to npm (latest) and JSR.
  • Versions are derived, not kept in the repo (scripts/release_plan.ts):
    • packages with commits touching packages/<name>/ since the previous release (tests excluded) are released;
    • level from Conventional Commits — breaking (!, BREAKING CHANGE:, BREAKING(...)) → major, feat → minor, others → patch, /unstable → patch; in 0.x major and minor both bump the minor version;
    • every package depending on a released one gets a patch (siblings pin each other exactly);
    • base = latest stable npm version, falling back to JSR for the first Bun release (so e.g. builder 0.5.2 → 0.6.0).
  • scripts/apply_versions.ts writes a plan into the manifests (optional -next.N suffix) and replaces set_prerelease.ts.
  • scripts/publish.ts publishes the planned packages to npm (skipping versions already there) and runs jsr publish at the workspace root (orders members, skips published versions; GitHub OIDC, no token).
  • Pre-release Releases are dry runs (plan only). Manual runs publish <planned>-next.<run> to npm next.
  • .claude/rules/repository.md describes the new release process.

Why

JSR publishing has been missing since the Deno publish workflow was removed, and the npm latest path published the placeholder manifest versions (the same numbers as the Deno builds on JSR). Versions are now decided per release from the history, as agreed for this repository: one calendar-tagged Release for the repository, independent semver per package.

Re-runs reuse the attached versions.json, so a failed run never bumps twice. Release tags are validated before anything is published. Pre-releases are dry runs because install.sh and Homebrew in probitas follow the latest release, which pre-releases never become.

Test Plan

  • bun run verify (incl. new tests for commit classification, version bumping, dependency cascade, base selection, version application)
  • First-release plan against the live registries: every package bumps from its JSR version (0.5.2 → 0.6.0, …)
  • Incremental plan against an older commit: patch levels and per-package commit lists in the notes
  • End-to-end dry run on a scratch copy: plan → apply → build → pack → jsr:sync → npm publish --dry-run for all 20 packages with exact sibling versions → jsr publish --dry-run succeeds for all 20
  • After merge: publish a pre-release Release to check the dry run in Actions, then the first real release

🤖 Generated with Claude Code

https://claude.ai/code/session_01N3xvJ1TaozjYSE6eoyo9mq

lambdalisue and others added 2 commits October 10, 2026 18:34
…release

Releases are cut as GitHub Releases with a repository-wide calendar tag,
and package versions are no longer bumped by hand, so something has to
decide them. release_plan.ts releases every package with commits
touching its directory (tests excluded) since the previous release tag,
at the level its Conventional Commits call for (0.x maps breaking
changes to minor), and gives a patch to every package depending on a
released one, because siblings pin each other exactly. Versions start
from the latest stable npm release, falling back to JSR for the first
release of the Bun build. The plan is written as versions.json so a
re-run reuses it instead of bumping again.

apply_versions.ts writes a plan into the manifests, with an optional
prerelease suffix, and replaces set_prerelease.ts: `next` builds are the
planned versions plus `-next.<run>`, instead of the manifest versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3xvJ1TaozjYSE6eoyo9mq
publish.yml now runs when a GitHub Release is published: it plans the
versions, attaches versions.json and appends the version table to the
release notes, then publishes the released packages to npm (`latest`)
and JSR. JSR publishing was missing since the Deno workflow was removed;
it goes through `jsr publish` at the workspace root, which orders the
members and skips versions already published, with GitHub OIDC instead
of a token.

A Release marked as a pre-release is a dry run that only computes and
attaches the plan. Pre-releases never become the "latest" release, so
the workflow can be tried without affecting install.sh and Homebrew,
which follow the latest release. Running the workflow manually still
publishes `next` prereleases. Release tags must look like v20261008.01,
so a mistyped tag fails before anything is published.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3xvJ1TaozjYSE6eoyo9mq
Copilot AI balanced review requested due to automatic review settings October 10, 2026 09:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@lambdalisue
lambdalisue merged commit d661eda into main Oct 10, 2026
3 checks passed
@lambdalisue
lambdalisue deleted the feat/release-flow branch October 10, 2026 13:38
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.

2 participants