Skip to content

Commit d0b5519

Browse files
authored
chore(release): cap auto-bumps at minor to avoid accidental majors (#295)
Convert `.release-it.json` → `.release-it.cjs` so we can pass a custom `whatBump` function to the conventional-changelog plugin. The function caps the recommended bump at `minor`, even when a commit contains a BREAKING CHANGE footer or `!:` marker. Background: a stray "BREAKING CHANGE:" line in any commit body would trip `conventional-recommended-bump` into recommending a major release, which in this CLI's current 0.38.x state would instantly ship 1.0.0 without any intended stability declaration. Matching the fix applied to genlayer-js (#159) so the two release pipelines behave the same. Net effect: - BREAKING CHANGE footer / `!:` marker → minor bump (was: major) - feat: → minor (unchanged) - fix: / chore: / docs: / ci: / etc. → patch (unchanged) - `release-it major` still forces a major when genuinely needed All other release-it settings (git, github, npm, types, hooks) carried over verbatim from the JSON config. JSON deleted because it takes precedence over CJS in release-it's config resolution order.
1 parent 2b5f177 commit d0b5519

2 files changed

Lines changed: 87 additions & 66 deletions

File tree

.release-it.cjs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* release-it configuration.
3+
*
4+
* Converted from `.release-it.json` to `.cjs` so we can supply a custom
5+
* `whatBump` function that caps the recommended bump at `minor`. Reason:
6+
*
7+
* `@release-it/conventional-changelog` forwards the default bump logic to
8+
* `conventional-recommended-bump`, whose `conventionalcommits` preset always
9+
* returns `major` when any commit's body contains a "BREAKING CHANGE" footer
10+
* (case-insensitive) or a `!:` marker. That would silently jump this CLI
11+
* from 0.x → 1.0.0 on a single stray commit, which is never what we want.
12+
*
13+
* This override forces the recommended bump to stop at `minor`. A genuine
14+
* major release still requires an operator to pass `release-it major`
15+
* explicitly, which is how most mature TS libraries handle it.
16+
*
17+
* `.release-it.json` takes precedence over `.release-it.cjs` in release-it's
18+
* config resolution order, so the JSON file must not exist.
19+
*/
20+
21+
module.exports = {
22+
git: {
23+
commitMessage: "Release v${version} [skip ci]",
24+
tagName: "v${version}",
25+
requireCleanWorkingDir: false,
26+
requireUpstream: false,
27+
requireCommits: false,
28+
push: true,
29+
},
30+
github: {
31+
release: true,
32+
tokenRef: "GITHUB_TOKEN",
33+
},
34+
npm: {
35+
publish: true,
36+
publishArgs: ["--provenance --access public"],
37+
skipChecks: true,
38+
},
39+
plugins: {
40+
"@release-it/conventional-changelog": {
41+
preset: "conventionalcommits",
42+
infile: "CHANGELOG.md",
43+
/**
44+
* Cap automatic bumps at minor. Levels: 0 = major, 1 = minor, 2 = patch.
45+
* BREAKING CHANGE footer or `!:` marker → minor (was: major)
46+
* feat: → minor (unchanged)
47+
* fix: / chore: / etc. → patch (unchanged)
48+
* Run `release-it major` manually for a genuine major release.
49+
*/
50+
whatBump: (commits) => {
51+
const hasBreaking = commits.some((c) => {
52+
const bangMarker = typeof c.header === "string" && /^[^:!\s]+!:/.test(c.header);
53+
const breakingFooter =
54+
Array.isArray(c.notes) && c.notes.some((n) => /BREAKING[ -]CHANGE/i.test(n.title ?? ""));
55+
return bangMarker || breakingFooter;
56+
});
57+
const hasFeat = commits.some((c) => c.type === "feat");
58+
59+
if (hasBreaking) {
60+
return {
61+
level: 1,
62+
reason:
63+
"BREAKING CHANGE detected; auto-bump capped at minor. Run `release-it major` to force a major release.",
64+
};
65+
}
66+
if (hasFeat) {
67+
return { level: 1, reason: "feat commits present → minor" };
68+
}
69+
return { level: 2, reason: "no feat/breaking commits → patch" };
70+
},
71+
types: [
72+
{ type: "feat", section: "Features" },
73+
{ type: "fix", section: "Bug Fixes" },
74+
{ type: "chore", section: "Improvement Tasks" },
75+
{ type: "ci", section: "Continuous Integration" },
76+
{ type: "docs", section: "Documentation" },
77+
{ type: "style", section: "Styles" },
78+
{ type: "refactor", section: "Refactor Tasks" },
79+
{ type: "perf", section: "Performance Improvements" },
80+
{ type: "test", section: "Testing" },
81+
],
82+
},
83+
},
84+
hooks: {
85+
"after:bump": "npm run build",
86+
},
87+
};

.release-it.json

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)