You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Four of the fourteen post-1.0 releases carry no changelog entry at all — 1.0.4, 1.0.11, 1.0.12 and 1.0.14 all read **Note:** Version bump only for package @mittwald/flow-project. There are two separate causes behind that, and only one of them is a bug.
Why it happens
Two independent criteria decide, and they can never agree:
Whether a push releases is decided by PATHS. The decide job in publish.yml classifies the changed files with .github/scripts/release-relevance-lib.mjs. Its denylist knows only repo-root prefixes (.github/, apps/, docs/, dev/, …), so everything under packages/** is publish-relevant wholesale. The commit type plays no role.
What lands in the changelog is decided by TYPE. The conventionalcommits preset marks docs, style, chore, refactor, test, build and ci as hidden: true. Only feat, fix, perf and revert render. Nothing left to write → lerna emits "Version bump only".
The bump happens either way.lerna version --force-publish --conventional-commits: the preset's whatBump returns level 2 (patch) for any non-empty commit range unless bumpStrict is set, and --force-publish bypasses changed-package detection by design (Publish holes: versioned-but-unpublished releases break exact peer pins #2887).
Evidence
Version
Trigger
Reaches a tarball?
1.0.14
build(components)#3010 — only packages/components/.storybook/preview.tsx
No.files: ["*.md", "dist"]; the Storybook config is never built
Needless releases (1.0.14, 1.0.12). The relevance gate is too coarse insidepackages/**. .storybook/, package-local dev/, e2e/, src/tests/ and a scripts-only diff in a package manifest provably cannot affect a consumer. The scripts case stings twice: classifyRootManifestChange exists for exactly that reason (test(docs): check the documentation's internal links in CI #2970) but is applied to the root manifest only.
Real releases with an empty changelog (1.0.11, and every chore(deps): bump). chore(deps): bump framer-motion … changes what consumers resolve — the changelog never says so. Suppressing those releases would be wrong; the changelog is what has to admit them.
The denylist direction stays as it is: unknown paths are relevant, so a forgotten docs path costs one needless version while a forgotten source path would swallow a real release. Only paths that are provably not consumer-visible get added.
What to check
Extend the denylist with package-local non-shipping paths: packages/*/.storybook/**, packages/*/dev/**, packages/*/e2e/**, packages/*/src/tests/**, plus *.stories.tsx and *.test.*. IRRELEVANT_PREFIXES is matched with startsWith today, so per-segment or glob matching is new machinery — keep it minimal and cover it with tests.
Apply the key-diff refinement to packages/*/package.json too: a scripts-only change cannot reach a consumer. classifyRootManifestChange is reusable, but the decide job then has to fetch before/after for every changed package manifest, not just the root one. Note that published tarballs do contain scripts — the argument is "no consumer effect", not "not in the tarball". Write that down where the code says it.
Decide what to do about problem 2. Either give chore/build/refactor a visible changelog section (changelogPreset in lerna.json accepts an object with types), or accept "Version bump only" as the honest signal for them and document it. Note the preset is pinned to ^9 for the reason in docs/release-workflow.md.
Verify the next line behaves symmetrically — it runs through the same decide job.
Acceptance criteria
A merge touching only packages/*/.storybook/**, packages/*/dev/**, packages/*/e2e/**, packages/*/src/tests/**, or carrying a scripts-only package-manifest diff, produces no npm publish, no tag, no GitHub Release and no chore(release): commit.
A merge touching package source, locales, SCSS, generated code, a package's shipped *.md or any dependency block publishes exactly as today.
A mixed merge publishes.
workflow_dispatch still forces a publish — the manual escape hatch stays.
The skip is visible in the run (::notice::) and names the rule that fired.
release-relevance-lib.test.mjs covers every new path, incl. the mixed case and the scripts-only manifest.
docs/release-workflow.md updated: the denylist section names the new package-local exclusions and the reasoning.
Four of the fourteen post-1.0 releases carry no changelog entry at all —
1.0.4,1.0.11,1.0.12and1.0.14all read**Note:** Version bump only for package @mittwald/flow-project. There are two separate causes behind that, and only one of them is a bug.Why it happens
Two independent criteria decide, and they can never agree:
decidejob inpublish.ymlclassifies the changed files with.github/scripts/release-relevance-lib.mjs. Its denylist knows only repo-root prefixes (.github/,apps/,docs/,dev/, …), so everything underpackages/**is publish-relevant wholesale. The commit type plays no role.conventionalcommitspreset marksdocs,style,chore,refactor,test,buildandciashidden: true. Onlyfeat,fix,perfandrevertrender. Nothing left to write → lerna emits "Version bump only".lerna version --force-publish --conventional-commits: the preset'swhatBumpreturns level 2 (patch) for any non-empty commit range unlessbumpStrictis set, and--force-publishbypasses changed-package detection by design (Publish holes: versioned-but-unpublished releases break exact peer pins #2887).Evidence
build(components)#3010 — onlypackages/components/.storybook/preview.tsxfiles: ["*.md", "dist"]; the Storybook config is never builtci:#3006 — inremote-react-components:package.json(scriptsonly,--project=unit→unit*),CONTRIBUTE.md,dev/cross-version/**,src/tests/visual/**files: ["dist"]docs(ColumnLayout)#2954 — incl.packages/components/AGENTS.md*.mdships. The release is correct by design;docs:is merely invisibledocs: upgrade fumadocs-mdx#2959 — anapps/docsdependency + the lockfileTwo problems, not one
packages/**..storybook/, package-localdev/,e2e/,src/tests/and ascripts-only diff in a package manifest provably cannot affect a consumer. Thescriptscase stings twice:classifyRootManifestChangeexists for exactly that reason (test(docs): check the documentation's internal links in CI #2970) but is applied to the root manifest only.chore(deps):bump).chore(deps): bump framer-motion …changes what consumers resolve — the changelog never says so. Suppressing those releases would be wrong; the changelog is what has to admit them.The denylist direction stays as it is: unknown paths are relevant, so a forgotten docs path costs one needless version while a forgotten source path would swallow a real release. Only paths that are provably not consumer-visible get added.
What to check
packages/*/.storybook/**,packages/*/dev/**,packages/*/e2e/**,packages/*/src/tests/**, plus*.stories.tsxand*.test.*.IRRELEVANT_PREFIXESis matched withstartsWithtoday, so per-segment or glob matching is new machinery — keep it minimal and cover it with tests.packages/*/package.jsontoo: ascripts-only change cannot reach a consumer.classifyRootManifestChangeis reusable, but thedecidejob then has to fetch before/after for every changed package manifest, not just the root one. Note that published tarballs do containscripts— the argument is "no consumer effect", not "not in the tarball". Write that down where the code says it.chore(deps):andrefactor:routinely change the tarball; a type gate would silently swallow those releases. This is why Docs- and CI-only merges publish a full release of all 12 packages #2931 chose paths.chore/build/refactora visible changelog section (changelogPresetinlerna.jsonaccepts an object withtypes), or accept "Version bump only" as the honest signal for them and document it. Note the preset is pinned to^9for the reason indocs/release-workflow.md.nextline behaves symmetrically — it runs through the samedecidejob.Acceptance criteria
packages/*/.storybook/**,packages/*/dev/**,packages/*/e2e/**,packages/*/src/tests/**, or carrying ascripts-only package-manifest diff, produces no npm publish, no tag, no GitHub Release and nochore(release):commit.*.mdor any dependency block publishes exactly as today.workflow_dispatchstill forces a publish — the manual escape hatch stays.::notice::) and names the rule that fired.release-relevance-lib.test.mjscovers every new path, incl. the mixed case and thescripts-only manifest.docs/release-workflow.mdupdated: the denylist section names the new package-local exclusions and the reasoning.References
scriptscase that cut 1.0.9docs/release-workflow.md§ "Not every merge releases"