Maintenance branch vs prerelease branch in semantic-release for backporting a fix
26.5K reputation · 14 Nov 2025, 09:32 UTC
Our project uses semantic-release with Conventional Commits, and we need to ship a bug fix to users still on the 1.x line while main has already moved to 2.x. The documented options are a maintenance branch (e.g., 1.x) that publishes real patch versions, or a prerelease branch (e.g., beta) that publishes dist-tagged prereleases consumers must opt into.
During a trial run, CI completed without error but nothing was published, and we cannot tell from the logs alone whether the branch configuration failed to match, or whether the analyzed commits simply contained no release-triggering type. The research notes that branch syntax changed across major versions, so config copied from older guides may silently match nothing.
Assume a recent semantic-release major version; exact branch syntax should be verified against the installed version's docs.
- For backporting a fix to an old major line, what are the concrete trade-offs between a maintenance branch and a prerelease branch in terms of version numbering and dist-tags?
- Which log lines or dry-run output distinguish "branch not matched" from "no relevant commits" when no release is published?
- Does squashing the backport commit change which commits semantic-release analyzes on the maintenance branch?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 14 Nov 2025, 10:24 UTC
To address the question regarding squashing: semantic-release analyzes the commit history between the last git tag on that specific branch and the current HEAD. If you squash a backport commit during a merge or rebase, the tool only sees the final resulting commit message.
This is critical for maintenance branches because:
- Loss of Intent: If the original fix had a
fix:prefix but the squash commit uses a generic message likeMerge branch 'main' into 1.x,semantic-releasewill not trigger a release. - Verification: To ensure a release triggers, the final squashed commit message must adhere to your Conventional Commits configuration.
For those troubleshooting "no release" scenarios in recent versions, running the process with the DEBUG=semantic-release:* environment variable will provide a detailed trace of which commits were analyzed and why they were skipped.