Skip to content

fix: dispatch to conventional-changelog-writer v9 for render-function presets - #1021

Open
Mearman wants to merge 1 commit into
semantic-release:masterfrom
Mearman:support-conventional-changelog-writer-v9
Open

Mearman wants to merge 1 commit into
semantic-release:masterfrom
Mearman:support-conventional-changelog-writer-v9

Conversation

@Mearman

@Mearman Mearman commented Aug 3, 2026

Copy link
Copy Markdown

Fixes #992

conventional-changelog-writer@9 replaced its Handlebars-string templates (mainTemplate, headerPartial, etc.) with plain render functions, and renamed the root template option from mainTemplate to template. conventional-changelog-conventionalcommits@10 already builds against the new architecture. This plugin still pins conventional-changelog-writer@^8.0.0, so writerOpts.template (a function) never gets rendered — generateNotes doesn't error, it just silently produces the version header with no ### Features/### Bug Fixes body. Reproduced this directly against the real packages before writing any fix, not from the issue report alone.

#996 bumps conventional-changelog-writer to ^9.0.0 but leaves conventional-changelog-angular (the bundled default preset) at ^8.0.0 — still Handlebars-based. Writer@9 can't render angular@8's string templates (headerPartial is not a function, confirmed by testing it directly), so merging #996 as-is would fix the reported bug and break the default no-preset-specified path in the same stroke.

This PR takes a different approach: depend on both writer majors at once via npm aliasing (conventional-changelog-writer-v9), and dispatch on typeof writerOpts.template === "function" — mutually exclusive between the two architectures, verified against angular@8/9 and conventionalcommits@9.3.1/10 directly. Old presets keep resolving through the existing v8 writer unchanged; new presets resolve through v9. Every existing test still passes unmodified — that's the actual proof this doesn't break the default path, not just a claim.

Built test-first: test/load-changelog-config.test.js gets one new test proving the conventional-changelog-conventionalcommits-v10 aliased devDependency resolves and its writerOpts.template is a function; test/integration.test.js gets one test double-based test proving the dispatch picks the v9 wrapper when writerOpts.template is a function (and never touches the v8 wrapper), and one end-to-end test against the real v10 package proving ### Bug Fixes/### Features actually render — the literal bug, now fixed, not simulated.

One disclosed side effect: conventional-changelog-writer@9 and conventional-changelog-conventionalcommits@10 both require Node >=22. Bumped engines.node accordingly and dropped the 20.8.1 CI matrix leg. Node 20 reached its own upstream end of life on 2026-04-30, so this isn't asking anyone to give up currently-supported infrastructure.

Also fixed a latent lint:prettier mismatch in wrappers/conventional-changelog-writer.js (single quotes, trailing blank line) that surfaced only because I ran prettier --write across the touched directories — unrelated to the fix itself but caught along the way.

… presets

conventional-changelog-writer@9 replaced its Handlebars-string templates
with plain render functions and renamed the root template option from
mainTemplate to template. Presets built against the new writer (e.g.
conventional-changelog-conventionalcommits@10) set writerOpts.template as
a function; the writer this plugin depends on (^8.0.0) doesn't know how to
render that, so generateNotes silently produced just the version header
with no Features/Bug Fixes sections instead of erroring.

Depend on both writer majors simultaneously via npm aliasing
(conventional-changelog-writer-v9) and dispatch on typeof
writerOpts.template at the call site in index.js, extracted into
lib/select-writer.js. Old presets (conventional-changelog-angular@8, any
preset never updated) keep resolving through the existing v8 writer
unchanged; new presets resolve through v9. Adds
conventional-changelog-conventionalcommits-v10 as an aliased devDependency
to exercise the real v10 package end to end in test/integration.test.js,
alongside the existing 9.3.1-pinned conventionalcommits tests, which are
untouched.

conventional-changelog-writer@9 and conventional-changelog-conventionalcommits@10
both require Node >=22, so this also raises engines.node to >=22.0.0 and
drops the 20.8.1 CI matrix leg. Node 20 reached its own upstream end of
life on 2026-04-30.

BREAKING CHANGE: the minimum required node version is now v22.0.0; node
v20 and v21 are no longer supported

Fixes semantic-release#992
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedconventional-changelog-conventionalcommits@​10.2.11001009092100
Addedconventional-changelog-writer@​9.2.01001009495100

View full report

github-actions Bot pushed a commit to strausmann/mcp-dockhand that referenced this pull request Aug 9, 2026
## [1.10.0](v1.9.1...v1.10.0) (2026-08-09)

### Features

* **server:** bound Streamable HTTP session lifecycle ([4166a6d](4166a6d))

### Bug Fixes

* **release:** migrate presetConfig.types hidden-Feld zu effect (ccc@10) ([40f0719](40f0719))
* **release:** render changelog on ccc@10 via conventional-changelog-writer@9 override ([6a49c1b](6a49c1b)), references [#113](#113) [semantic-release/release-notes-generator#1021](semantic-release/release-notes-generator#1021)
* **server:** protect founding session from eviction; run DELETE cleanup ([85b3f29](85b3f29)), references [#133](#133)
* **tools:** align stack, system and favorites API contracts ([#131](#131)) ([1dc0b31](1dc0b31))
* **tools:** send pull/build/forceRecreate body from deploy_stack ([#117](#117)) ([99e42a9](99e42a9))
strausmann added a commit to strausmann/mcp-dockhand that referenced this pull request Aug 9, 2026
The override pinned conventional-changelog-writer to the exact version
9.2.0 (fix for #139), which would freeze the resolved version forever
and block any future patch/minor releases within the 9.x line.

Relax the pin to a caret range (^9.2.0) so npm can resolve newer 9.x
releases automatically, while still enforcing writer>=9 (required for
correct changelog rendering with conventional-changelog-conventionalcommits@10).

Verified with a clean install (npm ci), semantic-release --dry-run
(plugin chain loads and generateNotes renders correctly with writer
9.2.0), npm run build, and the full vitest suite (371 tests passing).

The override can be removed entirely once
semantic-release/release-notes-generator#1021 is released upstream.
github-actions Bot pushed a commit to strausmann/mcp-dockhand that referenced this pull request Aug 10, 2026
## [1.11.0](v1.10.0...v1.11.0) (2026-08-10)

### Features

* **tools:** extend validate-mcp-tools.mjs with query-param diff ([59ec907](59ec907)), references [#81](#81) [#95](#95)

### Bug Fixes

* **auth:** normalize base URL for login + surface tool errors ([#159](#159)) ([600a25d](600a25d)), closes [#116](#116) [#116](#116), references [#116](#116)
* **docker:** healthcheck uses 127.0.0.1 to avoid IPv6 localhost failure on Alpine ([#158](#158)) ([af6c513](af6c513)), closes [#92](#92) [#84](#84)
* **registries:** align get_registry_catalog with the real /api/registry/catalog contract ([6511cf2](6511cf2)), closes [#147](#147) [#150](#150)
* **registries:** align search_registry with the real /api/registry/search contract ([62d7799](62d7799)), closes [#146](#146)
* **release:** keep package version in sync via @semantic-release/npm (npmPublish:false) ([15c5f3a](15c5f3a)), closes [#139](#139)
* **release:** relax conventional-changelog-writer override to ^9.2.0 ([7c15fd4](7c15fd4)), closes [#139](#139), references [semantic-release/release-notes-generator#1021](semantic-release/release-notes-generator#1021)
* **tools:** align exec_container with the real Docker-exec-instance contract ([ec79b47](ec79b47)), closes [#81](#81), references [#81](#81) [#81](#81)
* **tools:** correct image-prune settings and trigger HTTP methods ([#141](#141)) ([6bfce61](6bfce61)), closes [#138](#138)
* **tools:** correct required/optional query params for 6 tools ([#153](#153)) ([bffc498](bffc498)), closes [#152](#152)
* **tools:** required/optional-aware query-param check, no manual triage ([7e79e54](7e79e54)), references [#148](#148)
* **tools:** update_container — optional settings, explicit fields, reject unknown keys ([#154](#154)) ([65a71b2](65a71b2)), closes [#142](#142)

### Documentation

* **readme:** document mcp-proxy workaround for Claude Desktop (remote) ([#157](#157)) ([cef7aaf](cef7aaf)), closes [#90](#90)
Seger85 pushed a commit to Seger85/mcp-dockhand that referenced this pull request Aug 27, 2026
…riter@9 override

conventional-changelog-conventionalcommits@10 switched its writer-facing
template config from Handlebars strings to function-based templates
(upstream breaking change). @semantic-release/release-notes-generator@14
still pulls conventional-changelog-writer@8, which does not know how to
call the new function templates and silently renders an empty changelog
body (only the version header, no "### Bug Fixes"/"### Chores" sections).

Bump conventional-changelog-conventionalcommits to 10.2.1 (supersedes
the Dependabot PR strausmann#113) and pin conventional-changelog-writer to 9.2.0
via "overrides" — the first writer release that understands the new
function-template API. Both commit-analyzer and release-notes-generator
plugins already use "preset": "conventionalcommits", so the override
does not affect the (unused) default angular preset's Handlebars path.

Verified with an isolated repro against real repo commits and the real
.releaserc.json presetConfig: writer@8.4.0 renders 0 sections, writer@9.2.0
renders the expected sections. Upstream tracking:
semantic-release/release-notes-generator#1021 — override removable once
that dependency bump ships upstream.
strausmann added a commit to strausmann/n8n-nodes-jmap-packet that referenced this pull request Sep 13, 2026
The release run got past npm authentication and then failed rendering the
notes: conventional-changelog-conventionalcommits 10 hands its templates
to the writer as bound functions, while release-notes-generator still
resolves conventional-changelog-writer 8, which expects handlebars
strings. Version 9 of the writer was rebuilt for the function form.

This is a forward pin, not a downgrade of the preset — an override on the
writer alone, so the preset stays current. It is safe here because both
commit-analyzer and release-notes-generator set "preset":
"conventionalcommits" explicitly; with the implicit angular default,
writer 9 fails with "headerPartial is not a function".

The override can be dropped once release-notes-generator dispatches
between writer 8 and 9 at runtime (semantic-release/release-notes-generator#1021).
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.

preset: conventionalcommits produces empty release notes with conventional-changelog-conventionalcommits v10

1 participant