feat(scripts): support stable and tagged (prerelease) version releases - #85
Open
GOODBOY008 wants to merge 10 commits into
Open
feat(scripts): support stable and tagged (prerelease) version releases#85GOODBOY008 wants to merge 10 commits into
GOODBOY008 wants to merge 10 commits into
Conversation
Add 'prerelease [identifier]' and 'stable' bump types to bump-version.mjs so both stable (vX.Y.Z) and tagged prerelease (vX.Y.Z-<id>.<n>) releases can be driven from the npm scripts. Prerelease/stable bumps rename the CHANGELOG section for the same release line instead of inserting duplicate sections. Adds version:prerelease / version:stable npm scripts and unit tests.
…tags The upload-updater-json and update-homebrew jobs only skipped tags containing 'alpha' or 'beta', so an rc tag (vX.Y.Z-rc.N) slipped through and would have replaced the stable latest.json / cask with a prerelease. Skip any tag with a dash (stable tags are always vX.Y.Z) so tagged prereleases never hijack the stable updater channel.
The release-version skill now covers both release kinds end-to-end: stable releases (vX.Y.Z, published with --latest, drives the in-app updater + Homebrew) and tagged prerelease releases (vX.Y.Z-<id>.<n>, published with --prerelease, never Latest). Also documents the prerelease bump types, CHANGELOG section handling, and verification steps.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds first-class support in R-Shell’s release tooling for tagged prereleases (e.g. v2.8.0-beta.1, v2.8.0-rc.1) and finalizing to stable (e.g. v2.8.0), covering version math, CHANGELOG handling, npm scripts, workflow safety-guards, and documentation.
Changes:
- Refactors
scripts/bump-version.mjsto export pure semver utilities, addprerelease [identifier]+stablebump types, and adjust CHANGELOG section behavior for prerelease lines. - Adds/updates
pnpmscripts and docs to expose the new bump commands and explain stable vs prerelease release flow. - Hardens
release.ymlgating so any dashed tag (vX.Y.Z-*) cannot update stable channels (latest.json, Homebrew).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/bump-version.mjs |
Implements prerelease/stable bumping, exports version math, and updates CHANGELOG logic. |
src/__tests__/bump-version.test.ts |
Adds unit tests for version transitions and CHANGELOG section behavior. |
package.json |
Adds version:prerelease and version:stable scripts. |
.github/workflows/release.yml |
Ensures stable-channel updater/Homebrew jobs only run for non-dashed tags. |
.github/skills/release-version/SKILL.md |
Documents stable vs tagged prerelease release procedure and verification. |
scripts/README.md |
Documents new bump commands and prerelease behavior. |
README.md |
Updates version bumping examples to include prerelease/stable flows. |
AGENTS.md |
Updates contributor-facing version bumping guidance for prerelease/stable. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+141
to
+146
| function renameSection(changelog, fromVersion, toVersion, date) { | ||
| return changelog.replace( | ||
| new RegExp(`^## \\[${escapeRegex(fromVersion)}\\]`, 'm'), | ||
| `## [${toVersion}] - ${date}` | ||
| ); | ||
| } |
Comment on lines
+16
to
+18
| pnpm run version:prerelease # stable -> 2.8.0-beta.1, or 2.8.0-beta.1 -> 2.8.0-beta.2 | ||
| pnpm run version:prerelease rc # continue/switch the prerelease line (alpha|beta|rc|...) | ||
| pnpm run version:stable # finalize a prerelease -> stable (2.8.0-beta.3 -> 2.8.0) |
Comment on lines
+287
to
+289
| pnpm run version:prerelease # 2.2.0 → 2.3.0-beta.1, or 2.3.0-beta.1 → 2.3.0-beta.2 (tagged) | ||
| pnpm run version:prerelease rc # 2.3.0-beta.3 → 2.3.0-rc.1 (switch prerelease line) | ||
| pnpm run version:stable # 2.3.0-beta.3 → 2.3.0 (finalize to stable) |
Comment on lines
+110
to
+112
| pnpm run version:prerelease # 0.7.1 → 0.8.0-beta.1, or 0.8.0-beta.1 → 0.8.0-beta.2 (tagged) | ||
| pnpm run version:prerelease rc # 0.8.0-beta.3 → 0.8.0-rc.1 (switch prerelease line) | ||
| pnpm run version:stable # 0.8.0-beta.3 → 0.8.0 (finalize to stable) |
Comment on lines
+56
to
+60
| pnpm run version:patch # 2.7.0 -> 2.7.1 (stable) | ||
| pnpm run version:minor # 2.7.0 -> 2.8.0 (stable) | ||
| pnpm run version:prerelease # 2.7.0 -> 2.8.0-beta.1 (tagged) | ||
| pnpm run version:prerelease rc # 2.8.0-beta.3 -> 2.8.0-rc.1 (tagged) | ||
| pnpm run version:stable # 2.8.0-beta.3 -> 2.8.0 (finalize) |
Comment on lines
+148
to
+169
| function insertSection(changelog, version, date) { | ||
| const newSection = ` | ||
| ## [${version}] - ${date} | ||
|
|
||
| ### Added | ||
|
|
||
| - _Add new features here_ | ||
|
|
||
| ### Changed | ||
|
|
||
| - _Add changes here_ | ||
|
|
||
| ### Fixed | ||
|
|
||
| - _Add bug fixes here_ | ||
| `; | ||
| // Insert after the Unreleased section | ||
| return changelog.replace( | ||
| /(## \[Unreleased\][^\n]*\n\n[^\n]*\n\n)/, | ||
| `$1${newSection}\n` | ||
| ); | ||
| } |
added 7 commits
August 21, 2026 23:22
…verification Extends PR #85's bump-version.mjs with release-tooling best practices borrowed from semantic-release / changesets and the openusage Tauri app: - Preflight guardrails: refuse to bump when the four version files (package.json, Cargo.toml, Cargo.lock, tauri.conf.json) disagree, or when the working tree has uncommitted tracked changes (--force bypass). - --dry-run prints the plan and CHANGELOG action without writing anything; --yes skips the interactive prompt for CI/agents. - Cargo.lock is updated by rewriting the root "r-shell" entry directly (like cargo set-version) instead of a full cargo build, with a cargo fallback and a post-edit verification. - CHANGELOG insertion is now robust (handles missing No Unreleased sections, multi-line entries, top-of-file insert) and asserts the section exists after updating; renameSection no longer leaves a duplicated "- YYYY-MM-DD" date on renamed headings. - New scripts/verify-release-tag.mjs validates a tag's semver shape and compares it against every version file (used by CI and version:verify). Tests: 61 unit tests for the module (was 29), full suite 626 passed.
Release hardening informed by openusage's publish workflow and tauri-apps/tauri-action semantics: - New validate-tag job fails fast before any build when the tag is not a valid semver tag (vX.Y.Z or vX.Y.Z-<prerelease>) or does not match the version in every version file. - tauri-action now creates tagged prereleases (vX.Y.Z-<id>.<n>) with prerelease: true; with the previous hardcoded false a prerelease tag could be auto-marked "Latest" and hijack releases/latest for stable users. - concurrency group serializes overlapping release runs so two tags can never race on the latest.json manifest upload.
- SKILL.md: note the pre-flight checks and --dry-run/--yes flags on the bump step, add a version:verify sanity check before tagging, and mention the workflow's validate-tag gate and auto-prerelease behavior. - scripts/README.md: document verify-release-tag.mjs, the new options (--dry-run/--yes/--force), and the direct Cargo.lock update. - AGENTS.md / README.md: add version:verify and the guardrail summary.
docs/VERSION_BUMP.md no longer exists; the authoritative release procedure now lives in .github/skills/release-version/SKILL.md.
Replaces the stale docs/VERSION_BUMP.md reference with the release-version skill and adds the prerelease/stable/verify commands to the instructions.
The '✓'/'⚠️ '/'—'/'…' glyphs made Vitest fail to load the module on Windows (and ubuntu) CI with 'SyntaxError: Invalid or unexpected token' - a pre-existing failure already present on this branch before the enhancement. Replace them with ASCII equivalents in log output and comments so the release tooling parses identically everywhere (verified pure-ASCII across the whole version-bumping dependency graph).
…orm tests Vitest fails to transform ESM imported from outside the project root (scripts/) on Windows CI with 'SyntaxError: Invalid or unexpected token'. The failure predates this enhancement (the original PR head had the same red windows run) and is specific to out-of-root imports in the test graph. Move all pure version/CHANGELOG/tag logic into src/lib/version-bump.mjs - inside the vitest transform root, with no Node built-ins and no import.meta.url in the shared module - and turn both CLI scripts into thin shells importing from it. Unit tests now import only from src/, so the module transforms identically on macOS, ubuntu, and windows. Also drop the leftover non-ASCII glyphs from the previous attempt; the whole versioning dependency graph is now pure ASCII.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes stable (
v2.8.0) and tagged (v2.8.0-beta.1,v2.8.0-rc.1) releases first-class in the r-shell release tooling, end to end — with release-tooling guardrails borrowed from semantic-release / changesets and the openusage Tauri app.Changes
src/lib/version-bump.mjs(new) — single source of truth for all pure version/CHANGELOG/tag logic, shared by the CLI scripts and the unit tests. Lives undersrc/so Vitest transforms it inside the project root (importing ESM fromscripts/outside the root trips a vite-node bug on Windows — see Notes).scripts/bump-version.mjs— thin CLI on top of the lib, with stablemajor/minor/patch,prerelease [identifier], andstablebump types:2.7.0 → 2.8.0-beta.1(opens the next minor line),2.8.0-beta.1 → 2.8.0-beta.2(continues),2.8.0-beta.3 → 2.8.0-rc.1(switches identifier),2.8.0-beta.3 → 2.8.0(finalize)--forcebypasses)--dry-runplan preview,--yesto skip the confirmation prompt,--helpUnreleasedsection) and asserted after writing, and renamed headings no longer duplicate the- YYYY-MM-DDdateCargo.lockupdated by editing the rootr-shellentry directly (likecargo set-version) with acargo buildfallback and post-edit verificationscripts/verify-release-tag.mjs(new, viapnpm run version:verify "vX.Y.Z") — validates a release tag's semver shape and compares it againstpackage.json,Cargo.toml,Cargo.lock, andtauri.conf.json; fails with a per-file report on any mismatch..github/workflows/release.yml:validate-tagjob fails fast before any build when the tag is malformed or mismatches the project versionprerelease: ${{ startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, '-') }}— tagged prereleases are now created as GitHub prereleases (never Latest); previously a hardcodedfalsecould let av2.8.0-rc.1tag auto-become Latest and hijackreleases/latestupload-updater-json/update-homebrewskip any tag with a dash (stable tags are alwaysvX.Y.Z), so tagged prereleases can never hijack the stable updater channel or the Homebrew caskconcurrencygroup serializes overlapping release runspackage.json—version:prerelease,version:stable, andversion:verifyscripts..github/skills/release-version/SKILL.md— documents both release kinds: stable (--latest, drives in-app updater + Homebrew) vs tagged prerelease (--prerelease, never Latest), including tag naming, CHANGELOG handling, the new guardrails /--dry-run, and a pre-tagversion:verifysanity check.Docs —
AGENTS.md,README.md,scripts/README.md,.github/copilot-instructions.mdupdated.Tests
src/__tests__/bump-version.test.ts(was 29) covering version transitions, semver edge cases, version-file drift detection, Cargo.lock rewriting, robust CHANGELOG insertion/rename (including the duplicate-date regression), and tag verificationNotes
bump-version.test.tswithSyntaxError: Invalid or unexpected token, because Vitest cannot transform ESM imported from outside the project root (scripts/); ubuntu also flaked on the file-browser follow test. Moving the shared logic intosrc/lib/fixed the Windows failure — the full matrix now passes (Windows runs 646 tests incl. merged main).docs/release-version-skilltip), with the enhancement as focused follow-up commits. Theb1f6cd5note from the base PR still applies.