Release script - #1723
Release script#1723
Conversation
… branch on freeze
shellcheck SC2209: 'patch' is also a command name, so the unquoted assignment reads as a possible typo for RELEASE_TYPE=$(patch). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uirement release-README.md described publish as an unimplemented placeholder and code-freeze's old, non-idempotent behaviour. Bring it up to date: a "Before you start" section on the sibling-clone preflight both commands share, a corrected code-freeze step list (resume logic, per-step skips, test:jest not test), full publish documentation (options, preflight, the nine steps, the manual checklist), and Notes covering re-runnability and the deliberate divergence from the ClickUp process doc for hyperformula-tests. Drops the stale advice to delete release/<version> to redo a freeze - that bail-out no longer exists. Also documents the sibling-clone requirement in code-freeze's --help text.
…esume the demos branch from origin
…e resume Adds a warning register, factors the repeated branch handling into shared helpers, and fixes the code-freeze ordering that broke every resume. - warn/note register: 'warn' records a soft failure (the run could not do something), 'note' an advisory (worth checking). Both re-print as '[ ]' items at the top of the closing checklist, and a soft failure changes the closing banner, so a freeze that fell short cannot sign off as if it had not. Backed by temp files so subshells and the node here-doc can append. - checkout_branch, resolve_branch and merge_develop_into_version_branch: one implementation each for "get onto a branch", "name the ref a release is read from" and "carry demos' develop onto M.m.x". These replaced four hand-written copies of the same decision that had each drifted. - require_script: the preflight now checks a sibling clone carries the script the run will execute. It matters most for publish, whose demos script runs after the npm publish that cannot be undone. - code-freeze: create and push release/<version> in hyperformula-tests in step 2 rather than step 10. fetch-tests.sh pulls the matching branch from origin, so a branch an earlier attempt created locally but never pushed made every resume fail there. - Preflight: report both missing sibling clones, reject a date that does not exist, and treat a dirty tree as fatal for a fresh real freeze while exempting a dry run and a resume. - release-README.md: document both preflights and the recorded-failure markers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ Deploy Preview for hyperformula-dev-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
hyperformula-docs | fc55734 | Aug 06 2026, 06:49 AM |
Performance comparison of head (fc55734) vs base (bad1bfa) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## release/3.4.0 #1723 +/- ##
==============================================
Coverage 97.31% 97.31%
==============================================
Files 195 195
Lines 15734 15734
Branches 3456 3456
==============================================
Hits 15312 15312
Misses 414 414
Partials 8 8 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit fc55734. Configure here.
| const head = rnLines.slice(0, idx).join('\n').replace(/\s+$/, ''); | ||
| const tail = rnLines.slice(idx).join('\n').replace(/^\n+/, '').replace(/\s+$/, ''); | ||
| fs.writeFileSync(rnPath, head + '\n\n' + entry + '\n\n' + tail + '\n'); | ||
| console.log(' added "## ' + v + '" to ' + rnPath); |
There was a problem hiding this comment.
Empty notes pass on resume
Medium Severity
When [Unreleased] has no bullets, step 7 still writes an empty release-notes.md stub after warning. A later resume sees that heading, skips with already has, and does not re-check for content, so warning_count stays 0 and the freeze can sign off as ready with empty notes still committed.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit fc55734. Configure here.
| # explicitly instead of declaring the local branch authoritative: otherwise a | ||
| # colleague's commit on a shared branch is silently ignored here and | ||
| # surfaces as a raw non-fast-forward rejection at the next push. | ||
| run git merge --ff-only "origin/$1" |
There was a problem hiding this comment.
Stale sync without fetch
Low Severity
When a branch has no upstream, sync_branch fast-forwards to origin/<branch> without fetching first. The demos steps call this on develop with no prior fetch, so a cold or stale remote-tracking ref can be treated as current even though the comment says this path exists to pick up remote moves.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit fc55734. Configure here.


Summary
Implements the
publishhalf of the release automation and makescode-freezegenuinely re-runnable.On the base branch,
release.sh publishis a placeholder that prints "not implemented yet" and exits 1 — everything after the freeze (the merges, the tag, the npm publish, the sibling-repo updates) was still manual. This PR implements it end to end, and hardenscode-freezeso a run that fails part-way resumes instead of starting over.Both commands mirror the ClickUp release process doc, with the deliberate deviations listed below.
Note
Base is
release/3.4.0, notdevelop— this is an exception. The release-script work is stacked on the 3.4.0 freeze commit (bad1bfa1), sorelease/3.4.0is the only base that yields a clean two-file diff. Targetingdevelopwould drag in the 3.4.0 version bump, its CHANGELOG/release-notes entries and ~1,950 lines of lock-file churn.script/release/release.shscript/release/release-README.mdpublishcommandexit 1No files outside
script/release/are touched.What's new — the
publishcommandrelease/<version>intomasteras a merge commit, unless already merged<version>onmaster, unless it already exists inmaster's (ororigin/master's) historyrelease/<version>intodevelopverify:publish-packagefrommastermaster,developand the tag in one atomic push, before the npm publishhyperformula-tests(intomasteranddevelop), pushed atomicallynpm publish, then waits for registry visibilityhyperformula-demos: lock files ondevelop, then merges into theM.m.xbranchdevelop, where the next cycle startscode-freezehardening=marker, so a failed run is recovered by re-running the same command rather than unpicking a half-finished freeze.test/fetch-tests.shpulls the matching branch from origin, so arelease/<version>that an earlier attempt created locally but never pushed made every resume fail. Creating and pushing it beforetest:setup-privateruns fixes that, and publishes the branch for CI and for whoever adds tests during the freeze that much sooner.origin/develop, not the working tree — on a resumed freeze the tree already carries the bump, which used to read as a patch and silently skip the demos and CodeSandbox work.git add ., so unrelated work in your tree cannot ride along into the release commit.2026-02-30passed theYYYY-MM-DDregex and reachedht.config.jsverbatim while the release notes said March 2.Safety model
--real-run. Every mutating command is printed as a$line; generated content (the new CHANGELOG section, the release-notes entry, every rewritten demo URL as-/+) is previewed so it can be proofread first.origin, carrying the branches the run will move and the script it will execute inside them. This is checked before anything moves — inpublishthe demos script runs after the irreversible npm publish, so a wrong--demos-dirhas to be caught up front or not at all.developor a shared version branch. A localrelease/<v>that disagrees with origin's is fatal, so a late fix pushed to the freeze branch cannot be silently dropped.latest. A plainx.y.zpublishes underlatest; anything with an rc suffix publishes undernextand the GitHub release link carries&prerelease=1.Recorded failures
Anything you need to act on is recorded and re-printed as a
[ ]item at the top of the closing checklist — a lone marker line mid-run scrolls past in an output that also holds a full install, build and test log. Two kinds, and only one means the run fell short:!the script could not do it — a target file has been restructured, or[Unreleased]is empty. These change the closing banner, so a freeze that fell short cannot sign off as if it hadn't.iworth checking — the run did its job, but something deserves a look (a resume from a dirty tree, a demos branchpublishhad to create). Listed without changing the banner, so an ordinary resume does not announce itself as a failure.Deliberate deviations from the process doc
hyperformula-testsgets its ownrelease/<version>branch, whichpublishmerges back intomasteranddevelop. The doc still describes pointing itsmasteratdevelopby hand. The ClickUp doc needs updating to match.release/<v>is never deleted — the branch is kept in both repositories, unlikegit flow release finish.How to verify
Dry run is the default, so both commands can be previewed safely against a real clone:
Each prints its preflight, a plan, every command it would run, and the exact content it would write.
shellcheckis clean andbash -npasses.Review status
A full review of the final implementation was run against the process doc. Four findings are fixed in this branch:
-Ttext heuristic could silently drop a real markdown file from the demo-URL rewrite, under-reporting the file count with no warning.publish's preflight checks ran beforestep "Preflight", so a failure reaching the ERR trap was attributed to"startup"instead — inconsistent withcode-freeze.master-only, where the script also acceptsorigin/master's history.node/perledits are not echoed verbatim.Follow-ups (not in this PR)
git push --atomic origin master develop --tagspushes all local tags, not justrefs/tags/<version>. A stray local tag gets published as a side effect, and one tag conflicting with origin aborts the entire release push.Merge branch 'origin/release/<v>'instead ofrelease/<v>.Note
Medium Risk
Changes automate irreversible npm publish and multi-repo git merges/tags; mitigations include dry-run default, preflight pinning, typed confirmation, and atomic pushes, but operator error or partial failure still needs careful resume.
Overview
Replaces the
publishstub with an end-to-end flow: mergerelease/<version>intomasteranddevelop, tag, build and runverify:publish-package, atomic push of branches and tags (before npm), merge back inhyperformula-tests, typed npm publish confirmation (latestvsnextfor prereleases), then updatehyperformula-demos.code-freezeis reworked to be resumable (skip steps with=when already done) instead of exiting whenrelease/<version>exists. The tests repo branch is created and pushed in step 2 (beforetest:setup-private). Major/minor detection usesorigin/develop, commits use named paths notgit add ., and invalid calendar dates are rejected.Both commands share new infrastructure: warning register (
!/iin the closing checklist),checkout_branch/resolve_branch/merge_release_into, strict sibling-repo preflight (fixedtest/hyperformula-testspath; demos script verified before publish), and expandedrelease-README.mddocumenting behavior vs the script.Reviewed by Cursor Bugbot for commit fc55734. Bugbot is set up for automated code reviews on this repo. Configure here.