Skip to content

test(changelog): assert the bump, and prove the control can fail - #48

Merged
GSTJ merged 1 commit into
mainfrom
fix/changelog-check-bump-assertions
Jul 28, 2026
Merged

test(changelog): assert the bump, and prove the control can fail#48
GSTJ merged 1 commit into
mainfrom
fix/changelog-check-bump-assertions

Conversation

@GSTJ

@GSTJ GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Flip chore from effect: "changelog" to effect: "bump" in tools/changelog-preset.mjs and pnpm run changelog:check passes clean. The type keeps rendering, so every existing assertion holds, and nothing looks at the version. That is the failure effect was added to prevent: a month of dependency chores driving a release past a patch.

Bump

The check now measures it, through conventional-recommended-bump against the same preset the release uses. feat! major, feat minor, fix patch, and build/refactor/chore/docs together no release at all. The sabotage above now fails on build/refactor/chore/docs alone do not bump (got patch). That number comes from running the bumper.

Policy

POLICY states each type's effect longhand, and the type list is asserted against it. Before, a type could drift in the list and only get caught sideways, through whatever it happened to do to the rendered output.

The section assertions still fail when they should: hiding chore failed before this change and fails now.

Negative control

The same synthetic history rendered through a type list with every visible type forced to hidden, failing if that run passes. All three breaking-change assertions still hold under that sabotage, the ci!: one included, because the writer un-discards any commit carrying a note whatever type it hangs off.

the sabotage the old control could not see

Changelog output

Untouched. node tools/changelog.mjs rebuilds CHANGELOG.md byte-identical (same md5 either side), and tools/changelog-history.md is still embedded verbatim, so nothing at or below the 1.3.0 freeze moved.

No release

Rehearsed with npm version patch on a throwaway clone: 1.3.5 -> 1.3.6, zero lines removed from CHANGELOG.md, annotated tag built from the new section. The 1.3.6 section comes out empty, since test: is a hidden type.

The check covered which sections render and nothing else. Flip `chore` from
`effect: "changelog"` to `effect: "bump"` and it still passes clean, because
the type keeps rendering and no assertion looks at the version. That is the
exact failure `effect` exists to prevent: a month of dependency chores
driving a release past a patch.

So it now measures the bump through conventional-recommended-bump against the
same preset: feat! is a major, feat a minor, fix a patch, and
build/refactor/chore/docs together are no release at all. The chore-to-bump
sabotage fails on `build/refactor/chore/docs alone do not bump (got patch)`.

The policy also moves into POLICY, stated longhand, and the type list is
asserted against it. Before, a type could drift in the list and only be
caught indirectly, through whatever it did to the rendered output.

Last, a negative control: the same synthetic history rendered through a type
list with every visible type forced to `hidden`, failing if that run passes.
An assertion that cannot fail is worth nothing, and this keeps proving these
can.

Changelog output is untouched. tools/changelog.mjs regenerates CHANGELOG.md
byte-identical, and tools/changelog-history.md still freezes everything at
and below 1.3.0.
@github-actions

Copy link
Copy Markdown

🎉 Congratulations on making your first pull request in '@gstj/safe-jsx'! We appreciate your contribution and will review it as soon as possible. Thank you for helping us make this project better.

@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Reviewed and verified locally.

The premise holds. I flipped chore from changelog to bump in the preset, ran main's check against it and it passed clean, then ran this branch's and it went red on two assertions. Restored, and clean again.

changelog control, sabotaged and restored

The bump semantics are right, and each assertion falls over on its own: flipping feat to changelog fails both feat is "bump" and a feat is a minor. The negative control is falsifiable too. I replaced the sabotaged type list with a plain copy of TYPES and the run died on negative control FAILED: hiding every visible type changed nothing.

Nothing blocking. The negative control only wraps assessRendering, so the type-list and bump assertions have no automated counterpart, though both fall over by hand as above. And .changelog-preset-sabotaged.<pid>.mjs is only cleaned in a finally, so a SIGKILL mid-run leaves it sitting in tools/ for oxlint and oxfmt to pick up, and it isn't in .gitignore.

Separately, resolving the CLI through import.meta.resolve is a real fix. Main's hardcoded ../node_modules/.bin/conventional-changelog died with ENOENT the first time I ran that script from outside the package root.

Merging.

@GSTJ
GSTJ merged commit 912d2a5 into main Jul 28, 2026
5 checks passed
@GSTJ
GSTJ deleted the fix/changelog-check-bump-assertions branch July 28, 2026 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant