feat: lib/version.sh — one version abstraction, two backends #28
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#28
Loading…
Reference in a new issue
No description provided.
Delete branch "build/3-version-lib"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #3
Acceptance criteria
Test plan
The issue's enumerated cases, all in
test/version.test.sh(22 checks):undefined).version_is_dev:1.2.3-devyes;1.2.3no;1.2.3-rc1no.version_next_dev:0.9.0 → 0.9.1-dev;0.9.9 → 0.9.10-dev; refuses-dev,-rc1, garbage.version_write file: file is exactly<ver>\n(byte-compared viacmp).version_write package-json: against a fixture with a real npm-generatedpackage-lock.json; asserts package.json AND both lockfile version spots carry the new version afterwards.CEREMONY_REQUIRE_NPMit prints the SKIP notice and exits 0; with it (as ci.yml now sets) the skip is a counted failure and the suite exits 1.bash test/run.sh→ 22 passed, 0 failed; shellcheck 0.10.0 sweep clean (6 scripts); actionlint 1.7.12 clean.Changelog
CHANGELOG.mddoes not exist yet — it arrives with the dogfood issue (#11), same as PR #25's precedent. Stated per the template.Notes
ci.ymlgains only anenv: CEREMONY_REQUIRE_NPM: 1on the existing Tests step — the issue's "assert in ci.yml that the npm case was not skipped", with the decision kept in the test script (workflows gather facts, scripts decide).10#$patchin the arithmetic so a zero-padded patch can't be read as octal.Round log
🔎 reviewing head
36fc98bf40🔎 reviewing head
36fc98bf40🔎 reviewing head
36fc98bf40All issue #3 acceptance criteria are met at head
36fc98bf409b19df36bb495c236d5462291a0603.Verified the whole merged tree:
bash test/run.sh(22 passed), the repository shellcheck sweep, actionlint sweep, andgit diff --checkall pass. I also exercised the explicit missing-Node path (exit 1 with the required clear message) and zero-padded patch arithmetic (1.2.09→1.2.10-dev). The implementation preserves the issue #1 fail-loud, whole-version, lockfile-sync, no-regex, and mawk-portability constraints.Verdict: approve
Head
36fc98bf409b19df36bb495c236d5462291a0603meets issue #3's acceptance criteria.Acceptance criteria
CEREMONY_REQUIRE_NPM: 1on the Tests step; npm write path exercised (write package-json: succeeds+ both package.json and lockfile assertions)lib/version.shandtest/version.test.shclean; no awk in the changenpm cimismatch rationale, pkg_version no-regex discipline, rc-vs-dev refusal (prefix-confusion lore) all presentInterface vs issue #3
version_read file|package-json [dir]— whitespace-stripped file read; node parser (not regex) for package-json; loud fail on missing node, missing file, empty/absent version; unknown backend refusedversion_is_dev— literal*-devonly;1.2.3-rc1is not devversion_next_dev— bareX.Y.Zonly; refuses-dev/-rc1/garbage;0.9.9 → 0.9.10-dev;10#$patchavoids octal trapversion_write— file is exactver\n; package-json uses cast'snpm pkg set+npm install --package-lock-only --ignore-scripts; pure (no git)Tests
Contract cases from the issue are all present: file read/whitespace/missing/empty, package-json read/missing/no-version-field, is_dev trio, next_dev arithmetic + refusals, file write byte-exact via
cmp, package-json write + dual lockfile spots, unknown backends, and the skip-if-no-npm / CI-require gate. Theeqhelper correctly exact-matches (not substring) so whitespace stripping is real.Non-blocking nits
None that I would spend a round on. Changelog absence is correctly called out (no
CHANGELOG.mdyet; same precedent as #25).CI green on this head. Approve.
Approve — head
36fc98bfVerified against issue #3's spec, not just read.
What I ran:
bash test/run.sh→ 16/19 pass locally, the 3 failures being exactly the lib's designed loud-refusal (node is required for version-source: package-json) — this box has no node, so the package-json cases are covered by CI instead: run 29946217145 on head36fc98bis green, and its Tests log shows all 22 checks ok, including the three npm write cases (no SKIP), with Shellcheck and Actionlint steps also green.version_next_dev 0.9.09→0.9.10-dev(the10#octal trap is handled);1.2.3.4andgarbagerefused;version_is_devglob only matches the literal-devsuffix.CEREMONY_REQUIRE_NPM=1 bash test/version.test.sh→ counted FAIL, exit 1; without it → SKIP notice. Matches the issue's "CI must run it" requirement, and ci.yml sets the var while the decision stays in the script (workflows gather facts, scripts decide).Against the acceptance criteria:
npm pkg set+ lockfile-only install with--ignore-scriptsmatch cast's incantation; the comments carry the why (lockfile-sync, no-regex, rc refusal) with the lineage pointers.eq,cmp) where substring matching couldn't prove stripping.CHANGELOG.mdarrives with #11).Non-blocking nits:
version_next_dev 01.02.03→01.02.4-dev— major/minor pass through verbatim while patch is10#-normalized. Out of spec's scope (input is only ever a just-released version); mentioning only so it's on record.Panel note: verdicts from codex and grok still pending; the ball is theirs.
Round summary — handoff
What shipped (single commit
36fc98bf):lib/version.sh, the one version abstraction with two backends —fileandpackage-json— behind four functions:version_read,version_write,version_is_dev,version_next_dev. Reads strip whitespace and fail loud on missing/empty sources; the package-json backend parses with node (never regex) and writes vianpm pkg set+npm install --package-lock-only --ignore-scriptsso both lockfile version spots stay in sync. Alongside it:test/version.test.sh(22 checks) with a committed fixture pair including a real npm-generatedpackage-lock.json, and one line inci.yml—CEREMONY_REQUIRE_NPM: 1on the existing Tests step, so the npm cases can never silently skip in CI while the skip/fail decision stays in the script.What each round changed: one round was all it took. The panel was requested at head
36fc98bf; all three reviewers (codex, grok, kimi) approved that same head with no changes requested, so the head reviewed is exactly the head being handed off.What was verified:
1.2.09→1.2.10-dev).CEREMONY_REQUIRE_NPM=1with npm absent → counted FAIL exit 1; unset → SKIP notice exit 0), and hand-tested the refusal and octal-trap edges.blocker:*labels.Post-merge residue:
CHANGELOG.mdentry — the file doesn't exist yet; it arrives with the dogfood issue #11 (same precedent as PR #25).version_next_devnormalizes only the patch segment with10#(a zero-padded major/minor passes through verbatim — input is only ever a just-released version), and the no-npm skip covers the npm-absent-but-node-present case; a fully node-less box fails the three package-json read tests loudly instead, which is the lib's designed behavior.Handing off per BUILDER.md: requesting @danmt's review and setting
state:needs-human. The PR is yours.