Skip to content

feat(release): enable ! notation for breaking changes in semantic-release#1658

Open
brtbrt wants to merge 19 commits into
masterfrom
mbertamini/1657-major-semantic-fix
Open

feat(release): enable ! notation for breaking changes in semantic-release#1658
brtbrt wants to merge 19 commits into
masterfrom
mbertamini/1657-major-semantic-fix

Conversation

@brtbrt

@brtbrt brtbrt commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix the ! notation for breaking changes in commit subjects (feat(scope)!: description), which used to be validated on PRs, but ignored as a major when releasing.

The whys

  1. ci workflow is using commit-analyzer 13.0.1 (the action is using it) . uses: amannn/action-semantic-pull-request@v5
  2. release was using another one: (10.0.0?) which was buggy about this

the two workflows used to work with different seantics, risky.

Changes

Core Fix

  • Upgrade @semantic-release/commit-analyzer from 10.0.0 to 13.0.1 (includes conventional-commits-parser 6.4.0)
  • Add explicit parserOpts.breakingHeaderPattern configuration to enable ! notation parsing
  • Update release workflow to pass NPM token to validate job for proper dry-run

Testing & Verification!

  • Verified ! notation correctly triggers major version bumps (e.g., 17.1.0 → 18.0.0 for feat(ci)!:)
  • Tested with semantic-release dry-run to confirm breaking change detection works

https://github.com/Telefonica/mistica-web/actions/runs/29528124907/job/87721546071
https://github.com/Telefonica/mistica-web/actions/runs/29513716048/job/87673343062

[4:03:02 PM] [semantic-release] › ℹ  The next release version is 18.0.0

Related Issues

Fixes #1657
Tracks #1660 (upstream issue - TODO to remove breakingHeaderPattern when fixed)

Migration

Breaking changes can now use the shorter syntax:

feat(api)!: remove legacy endpoint

Instead of:

feat(api): remove legacy endpoint

BREAKING CHANGE: legacy endpoint removed

Both syntaxes still work. The ! notation is now the preferred approach.

Testing

  • ✅ Verified feat(ci)!: ... correctly detected as major version bump
  • ✅ Verified dry-run shows correct next version
  • ✅ Verified CI validates PR titles with semantic-release action

closes #1657

brtbrt added 2 commits July 16, 2026 14:18
…eaking change support

The ! notation for breaking changes (e.g., feat(scope)!:) requires
conventional-commits-parser@3.3.0+. Commit-analyzer v10 includes this.

Fixes #1657
Adds a validate job that runs semantic-release --dry-run to show
what version will be bumped. The release job now depends on validate
and requires manual approval (via production environment), allowing
reviewers to check the dry-run output before proceeding.

Relates to #1657
Copilot AI review requested due to automatic review settings July 16, 2026 12:24
@brtbrt
brtbrt requested a review from a team as a code owner July 16, 2026 12:24
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

Size stats

master this branch diff
Total JS 15.8 MB 15.8 MB -1 B
JS without icons 1.91 MB 1.91 MB -1 B
Lib overhead 93 kB 93 kB 0 B
Lib overhead (gzip) 20.5 kB 20.5 kB 0 B

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the repo’s semantic-release setup so that Conventional Commits breaking changes using the ! notation (e.g. feat(scope)!:) are recognized correctly, and introduces a pre-release validation step that runs semantic-release --dry-run before the actual release proceeds.

Changes:

  • Upgraded @semantic-release/commit-analyzer to ^10.0.0 (and updated yarn.lock) to support ! breaking-change parsing.
  • Added a new validate job in the release workflow to run semantic-release --dry-run and gate the release job behind it.
  • Wired release to depend on validate, keeping the environment: production approval gate for the actual publish.

Reviewed changes

Copilot reviewed 2 out of 12 changed files in this pull request and generated 2 comments.

File Description
package.json Adds @semantic-release/commit-analyzer@^10.0.0 to address breaking-change ! parsing.
yarn.lock Locks the new analyzer version and its updated conventional-commits parser dependency chain.
.github/workflows/release.yml Adds a validate dry-run job and makes release depend on it.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread package.json
Comment on lines 81 to 83
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/commit-analyzer": "^10.0.0",
"@semantic-release/git": "^10.0.1",
Comment thread .github/workflows/release.yml Outdated
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy preview for mistica-web ready!

Project:mistica-web
Status: ✅  Deploy successful!
Preview URL:https://mistica-6cs8nsl4u-flows-projects-65bb050e.vercel.app
Latest Commit:9d602a8

Deployed with vercel-action

@Marcosld

Copy link
Copy Markdown
Contributor

I would not add a forced dry run validation. I'd just add a checkbox into the release job to perform a dry run.

@github-actions

Copy link
Copy Markdown

Accessibility report
✔️ No issues found

ℹ️ You can run this locally by executing yarn audit-accessibility.

Adds custom releaseRules to @semantic-release/commit-analyzer to ensure
commits marked as breaking (via ! notation or BREAKING CHANGE footer)
trigger major releases. This explicitly handles the breaking flag that
may not be recognized by default with the angular preset.

See #1657
@brtbrt

brtbrt commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Update: Custom releaseRules Configuration

Added explicit to the plugin to ensure breaking changes are properly recognized.

Why this is needed

The angular preset alone does not reliably recognize the feat(scope)! notation for breaking changes (see #3757, #231). By adding explicit releaseRules with { breaking: true, release: 'major' }, we ensure that commits marked as breaking (by the parser recognizing the ! notation) will trigger major releases.

What was added

"releaseRules": [
  { "breaking": true, "release": "major" },
  { "revert": true, "release": "patch" },
  { "type": "feat", "release": "minor" },
  { "type": "fix", "release": "patch" },
  { "type": "perf", "release": "patch" },
  { "scope": "no-release", "release": false }
]

The key rule is the first one: when a commit's breaking flag is true (set by conventional-commits-parser@6+ when it sees !), it triggers a major release.

@brtbrt
brtbrt force-pushed the mbertamini/1657-major-semantic-fix branch from bfe6119 to 70e8060 Compare July 16, 2026 13:17
Add explicit note that the ! notation is not supported by semantic-release
in the current configuration. Breaking changes must use the BREAKING CHANGE:
footer in the commit body instead.

See #1657
@brtbrt
brtbrt force-pushed the mbertamini/1657-major-semantic-fix branch from 70e8060 to f5f7d01 Compare July 16, 2026 13:36
brtbrt added 3 commits July 16, 2026 15:41
Add a validation step that rejects any PR title containing the ! character,
since the ! notation for breaking changes is not supported by semantic-release.
… jobs

Move CLI argument validation from the release job to the validate job.
Both jobs now use the same sanitized args, ensuring the dry-run shows
the exact version that will be released.

Output safe_args from validate job and pass to release job via needs.
Link to issue #1660 which tracks upstream semantic-release issues
blocking ! notation support. When those are resolved, these TODOs
should be addressed to re-enable the shorter breaking change syntax.
@brtbrt brtbrt changed the title fix(release): recognize breaking changes with ! notation + add dry-run validation fix(release): disallow breaking changes with ! notation on PRs + add dry-run validation when validating Jul 16, 2026
brtbrt added 2 commits July 16, 2026 17:41
… ! notation support

Fixes breaking change detection for ! notation in commit subjects. Version 13.0.1
includes conventional-commits-parser 6.4.0 which properly parses the ! prefix as
a breaking change indicator per the Angular convention.
Disable the ! notation guard to test if semantic-release properly detects
breaking changes with the new configuration.
@brtbrt
brtbrt force-pushed the mbertamini/1657-major-semantic-fix branch from 5e2f331 to 4b0cc14 Compare July 16, 2026 16:12
@brtbrt brtbrt changed the title fix(release): disallow breaking changes with ! notation on PRs + add dry-run validation when validating feat(release)!: enable ! notation for breaking changes in semantic-release Jul 16, 2026
@brtbrt

brtbrt commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

I would not add a forced dry run validation. I'd just add a checkbox into the release job to perform a dry run.
I like it, but I'd run it twice each time? it'd be cumbersome and even more error-prone

@brtbrt
brtbrt requested a review from Marcosld July 18, 2026 14:01
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.

fix: semantic-release not recognizing ! notation for breaking changes

3 participants