release-bump: scaffolds the version heading below [Unreleased] instead of promoting it, shipping empty release notes #86

Open
opened 2026-07-28 20:22:18 +00:00 by crenshawdev · 0 comments
crenshawdev commented 2026-07-28 20:22:18 +00:00 (Migrated from github.com)

What happened

Cutting v1.5.0, release-bump.mjs bump --version 1.5.0 --date 2026-07-28 reported success:

{"ok":true,"action":"bumped","target":"1.5.0","changelog":{"changed":true}}

It bumped plugin.json correctly and added the [1.5.0] link reference correctly. What it did to the changelog body was insert a bare heading below the staged content:

   configured effort differs from `cad-reviewer`'s frontmatter-pinned `high`
   now names the difference in one line rather than silently ignoring it.
 
+## [1.5.0] - 2026-07-28
+
 ## [1.4.1] - 2026-07-28

So the release section was empty, and all four of the release's entries stayed under ## [Unreleased].

Why this is worse than it looks

changed: true and ok: true are both accurate and both misleading — the file was changed, just not into a shippable state. Nothing downstream catches it: self-verify does not read changelog structure, and the tests pass. Had the release gone out unexamined, v1.5.0's notes would have been blank while four entries continued to advertise themselves as unreleased, on a repo whose changelog is a user-facing artifact.

Caught by reading the diff before committing. That is not a control.

Why it happened, most likely

The scaffolder appears to assume the top of the changelog is where new content goes and inserts the dated heading above the previous release — which is correct when there is no [Unreleased] section, and which is how every prior release in this repo was structured. A persistent [Unreleased] section is new: it was added during the v1.5.0 cycle by the worktree.baseRef work, following Keep a Changelog, which this project's own changelog header claims to follow.

So the tool and the file format disagree about where staged entries live, and the tool wins silently.

What you want Cadence to do

Promote rather than scaffold. When [Unreleased] exists and has content, bump should rename it to the dated version heading and leave a fresh empty [Unreleased] above it. When it does not exist, current behaviour is right.

Two smaller things worth deciding at the same time:

  • Refuse an empty release. If the resulting version section would have no entries under it, that is almost certainly a mistake — ok:false is more useful than a silent empty section.
  • [1.4.1] was missing from the link-reference block and was added by hand during this cut. Worth checking whether the link-ref insertion has an off-by-one against the most recent release, or whether v1.4.1 simply went out without it.

Reproduction

Any changelog with a non-empty ## [Unreleased] section above the most recent version heading. Run bump; observe the new heading inserted below the staged content rather than replacing its header.

Files this touches

cadence-core/bin/release-bump.mjs, cadence-core/bin/release-bump.test.mjs.

Notes

Fixed by hand for v1.5.0 (497a4ea), so the shipped changelog is correct. This issue is about the next release, which will hit the same thing.

## What happened Cutting v1.5.0, `release-bump.mjs bump --version 1.5.0 --date 2026-07-28` reported success: ```json {"ok":true,"action":"bumped","target":"1.5.0","changelog":{"changed":true}} ``` It bumped `plugin.json` correctly and added the `[1.5.0]` link reference correctly. What it did to the changelog body was insert a **bare heading below the staged content**: ```diff configured effort differs from `cad-reviewer`'s frontmatter-pinned `high` now names the difference in one line rather than silently ignoring it. +## [1.5.0] - 2026-07-28 + ## [1.4.1] - 2026-07-28 ``` So the release section was empty, and all four of the release's entries stayed under `## [Unreleased]`. ## Why this is worse than it looks `changed: true` and `ok: true` are both accurate and both misleading — the file *was* changed, just not into a shippable state. Nothing downstream catches it: self-verify does not read changelog structure, and the tests pass. Had the release gone out unexamined, v1.5.0's notes would have been blank while four entries continued to advertise themselves as unreleased, on a repo whose changelog is a user-facing artifact. Caught by reading the diff before committing. That is not a control. ## Why it happened, most likely The scaffolder appears to assume the top of the changelog is where new content goes and inserts the dated heading *above the previous release* — which is correct when there is no `[Unreleased]` section, and which is how every prior release in this repo was structured. A persistent `[Unreleased]` section is new: it was added during the v1.5.0 cycle by the `worktree.baseRef` work, following Keep a Changelog, which this project's own changelog header claims to follow. So the tool and the file format disagree about where staged entries live, and the tool wins silently. ## What you want Cadence to do Promote rather than scaffold. When `[Unreleased]` exists and has content, `bump` should rename it to the dated version heading and leave a fresh empty `[Unreleased]` above it. When it does not exist, current behaviour is right. Two smaller things worth deciding at the same time: - **Refuse an empty release.** If the resulting version section would have no entries under it, that is almost certainly a mistake — `ok:false` is more useful than a silent empty section. - **`[1.4.1]` was missing from the link-reference block** and was added by hand during this cut. Worth checking whether the link-ref insertion has an off-by-one against the most recent release, or whether v1.4.1 simply went out without it. ## Reproduction Any changelog with a non-empty `## [Unreleased]` section above the most recent version heading. Run `bump`; observe the new heading inserted below the staged content rather than replacing its header. ## Files this touches `cadence-core/bin/release-bump.mjs`, `cadence-core/bin/release-bump.test.mjs`. ## Notes Fixed by hand for v1.5.0 (`497a4ea`), so the shipped changelog is correct. This issue is about the next release, which will hit the same thing.
Sign in to join this conversation.
No description provided.