From 0bd2c4b65d55584efbe46465d15b750facb51965 Mon Sep 17 00:00:00 2001 From: Edgars Date: Thu, 23 Apr 2026 11:54:29 +0100 Subject: [PATCH] chore(release): cap auto-bumps at minor to avoid accidental majors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `{ breaking: true, release: "minor" }` as the first entry in `releaseRules` so that commits carrying a BREAKING CHANGE footer or `!:` marker produce a minor bump instead of a major one. Background: `@semantic-release/commit-analyzer` ships with a built-in default rule `{ breaking: true, release: "major" }`. That default is consulted whenever the user-provided `releaseRules` don't cover a commit. The existing user rules (`feat` → minor, `*` → patch) do not match on the `breaking` flag, so a stray "BREAKING CHANGE:" line in any commit body would immediately ship a major release — at the current 0.117.x state, that means 0.117.x → 1.0.0 without any intended stability declaration. By explicitly matching `breaking: true` first, we keep the default major-bump rule from being evaluated for those commits. Genuine major releases still work via an explicit `semantic-release --release major` override (or a deliberate config change). Mirrors the equivalent fixes shipped in: - genlayer-js (PR #159, release-it + whatBump) - genlayer-cli (PR #295, release-it + whatBump) User rules are evaluated before the defaults (per semantic-release's commit-analyzer documentation); defaults only apply when no user rule matches. Adding `breaking: true` at the top of `releaseRules` therefore prevents the default `major` rule from firing for breaking commits. Effect: - BREAKING CHANGE footer / `!:` marker → minor (was: major) - feat: → minor (unchanged) - everything else → patch (unchanged) --- release.config.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/release.config.js b/release.config.js index f048a1e0b..6b281a4aa 100644 --- a/release.config.js +++ b/release.config.js @@ -5,7 +5,19 @@ module.exports = { "@semantic-release/commit-analyzer", { "preset": "conventionalcommits", + // The first rule caps commits with a BREAKING CHANGE footer or `!:` + // marker at `minor`. Without it, semantic-release's built-in default + // rule `{ breaking: true, release: 'major' }` kicks in and auto-ships + // a major release the moment any commit body contains the words + // "BREAKING CHANGE". That's almost never what we want on 0.x — one + // stray commit would jump us straight to 1.0.0. Run semantic-release + // with an explicit `--release major` override for genuine major bumps. + // + // User rules are evaluated before the defaults; defaults only apply + // when no user rule matches. So capturing `breaking: true` here + // prevents the default major rule from being consulted at all. "releaseRules": [ + { "breaking": true, "release": "minor" }, { "type": "feat", "release": "minor" }, { "type": "*", "release": "patch" }, ],