Repository navigation
ci(release): lock the release toolchain - #29
Merged
Merged
Conversation
The Release workflow has failed at generateNotes on every release-bearing push since 2026-09-04 (a4cb188, a409872, 47db176), so v2.3.2 was never published. conventional-changelog-conventionalcommits 10.4.0 requires conventional-changelog-writer 9. @semantic-release/release-notes-generator 14.1.1, the latest, still depends on writer ^8. The workflow installed the preset and ran semantic-release unpinned, so it picked up the incompatible pair. Pin the preset to 10.3.0 and semantic-release to 25.0.9. Verified with `semantic-release --dry-run` against main: 10.3.0 completes generateNotes for 2.3.2, 10.4.0 fails with the same "Missing helper" error as CI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017c4dMZ2kYs4E65ysXHH4Qz
…er 8 Preset 10.3.0 avoids the "Missing helper" error but emits writer-9 template options, so release-notes-generator 14.1.1 (writer ^8) renders only the version header. v2.3.1 shipped with exactly that empty body. 9.3.1 renders the Bug Fixes section in the same format as v2.3.0. Verified with `semantic-release@25.0.9 --dry-run` on main at 47db176. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017c4dMZ2kYs4E65ysXHH4Qz
`npx semantic-release@25.0.9` pinned only the top package. semantic-release loads its plugins from its own node_modules tree, and every dependency below it (release-notes-generator ^14.1.0, conventional-changelog-writer ^8.0.0, the GitHub plugin's Octokit stack) resolved fresh on each run with no lockfile. Any new npm release in that tree reached a job that holds a contents:write token, unreviewed. Move the toolchain into .github/release/package.json with a committed package-lock.json: semantic-release 25.0.9, commit-analyzer 13.0.1, release-notes-generator 14.1.1, github 12.0.9, conventionalcommits preset 9.3.1. The job installs it with `npm ci --ignore-scripts` (no package in the tree has an install script) and runs that binary from the repo root. It lives under .github/ so the operator checkout gets no root package.json. Node is pinned to 24, the version this was verified on. Verified on Node 24 against main at 47db176, running the two workflow steps as written with the full .releaserc and a GitHub token, `--dry-run --no-ci`, no root node_modules: next version 2.3.2, notes render Bug Fixes with #26, #27 and #28. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dqz4KWjLzxNEJuea75Avb7
inf-1oop
approved these changes
Sep 24, 2026
|
🎉 This PR is included in version 2.4.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Release workflow fails at
generateNoteson every push that should cut a release. No GitHub release has been published since v2.3.1 (2026-08-03), so #27, #26 and #28 are onmainwith no release. And v2.3.1 itself shipped with an empty body.Cause
The workflow installed the release tooling unpinned, with no lockfile:
npx semantic-releaseresolves to 25.0.9. Its@semantic-release/release-notes-generator14.1.1 (the latest) depends onconventional-changelog-writer ^8.npm install --no-save conventional-changelog-conventionalcommitsresolves to the latest preset. Preset v10 targets writer 9:Pinning only the top-level packages does not close this. semantic-release loads its plugins from its own
node_modulestree, and every range below it (release-notes-generator ^14.1.0,conventional-changelog-writer ^8.0.0, the GitHub plugin's Octokit stack) resolves fresh on each run. The job holds acontents: writetoken, so any new npm release in that tree runs with it, unreviewed.Fix
New
.github/release/package.json+ committedpackage-lock.jsonfor the toolchain:semantic-release@semantic-release/commit-analyzer@semantic-release/release-notes-generator@semantic-release/githubconventional-changelog-conventionalcommitsThe job installs it with
npm ci --ignore-scripts --prefix .github/release(no package in the tree has an install script) and runs.github/release/node_modules/.bin/semantic-releasefrom the repo root, so.releaserc.yamlis still the config.It lives under
.github/so the operator checkout gets no rootpackage.json..gitignorecovers itsnode_modules.Node pinned to
24, the version this was verified on.A comment in the workflow says when to bump the preset: once the notes generator ships writer 9.
Verification
Ran the two workflow steps as written, on Node 24 / npm 11, on a checkout of
mainat 47db176 with no rootnode_modules, the full.releaserc.yamland a GitHub token,--dry-run --no-ci:npm ciinstalls one deduped copy of each package; every plugin and the preset resolve from.github/release/node_modules.verifyConditionspasses, next version 2.3.2, notes render### Bug Fixeswith fix: add Prysm v7 config keys to the mainnet chain config #26, fix(caddy): block the unauthenticated beacon validator namespace from public (VANA-BC-001) #27, fix: point the validator REST endpoint at the beacon HTTP port #28, same format as v2.3.0.Preset comparison (same command pair, earlier run):
Cosmetic: #26's commit body contains the word "closes" before "compatibility", so its line gets a bogus
closes #compatibilitylink. Harmless; editing the release body after publish fixes it if wanted.Heads-up on merging
Merging this triggers the workflow on
main, which will publish v2.3.2 as a public GitHub release containing #26, #27 and #28 (Prysm v7 config keys, the deposit contract switch config, the validator REST fix). The GitHub plugin also comments "included in version 2.3.2" on those PRs and labels themreleased, as it did on #21 for v2.3.1. Anyone watching this repo's releases gets notified, so merge when that announcement is fine to go out.🤖 Generated with Claude Code
https://claude.ai/code/session_01Dqz4KWjLzxNEJuea75Avb7