Versioning
The single source of truth
Repo-root VERSION holds the canonical version string (first non-comment line). package.json's
"version" is kept in sync with it — bump both in the same commit. (There's no build step wiring them
together the way a compiled project would; it's a manual two-line sync, done together.)
Current: 2.0.0.
SemVer scheme
MAJOR.MINOR.PATCH[-prerelease]:
- PATCH (
2.0.0 → 2.0.1 → …) — the default. Almost every change: bug fixes and ordinary features. Not capped at 9. - MINOR (
2.0.x → 2.1.0) — a notable feature set or milestone. - MAJOR (
2.x → 3.0.0) — a breaking change or a stability promise. The project leader's call (junebug12851); never bump automatically.
2.0.0 itself was a MAJOR bump because the ESM + Node-24 + dependency-major move breaks anyone on an old Node or relying on the CommonJS module shape.
How to bump
- Edit the version line in
VERSION. - Set the same value in
package.json"version". - Commit both together with the change that warranted the bump (and its changelog entry).
Docs/notes-only or test/CI-only commits don't move the number.
Where the number lives (keep these in sync)
| Place | Role |
|---|---|
VERSION |
The canonical number — the only thing a human edits. |
package.json "version" |
The Node package number — kept equal to VERSION in the same commit. |
web-app/package.json "version" |
The SPA's number — keep it in step with the root when the SPA ships as part of a release. |
There is no compiled pse_version.h-style generation here (this isn't a compiled app); the sync is the
manual two-line (three with the SPA) edit above, done in the one commit that warrants the bump. If you
ever add a place that needs the version (e.g. a footer in the web UI), derive it from
package.json at build time — never add a new hardcoded literal.
Releases and git tags (the version gate)
Releases are cut by .github/workflows/release.yml, gated on the tag v<VERSION> not already
existing — so a release happens exactly when master advances on a commit that bumped VERSION:
- Bump
VERSION(+package.json) ondev, commit with its changelog entry, go green. - Fast-forward
master(the standing workflow). IfVERSIONchanged,release.ymlcreates tagvX.Y.Zand publishes the Release; if it didn't, the tag already exists and the run is a no-op. - A
-alpha/-beta/-rclabel marks the GitHub Release as a prerelease.
workflow_dispatch with dry_run=true builds the artifacts without publishing. The full pipeline is in
deployment.md.
Don't confuse this with
../version.md. This file is the version-number scheme.version.mdis the changelog (the per-commit narrative).