chore(ci): scan only commit subjects for version-bump classification#36
Merged
Merged
Conversation
Fixes the false-positive minor bump on PR #35 (docs restructure) that shipped v1.13.0 with no user-visible changes. The previous script scanned both subject (%s) and body (%b) of every commit since the last tag, hoping to catch conventional-commit type lines preserved in squash-commit bodies when the squash subject was derived from a branch name. That hope produced a false positive: the PR #35 description contained a literal back-tick-wrapped reference to PR #34's title (`feat(tui): add Stop daemon action`), and the regex `\bfeat[(:/]` matched the substring `feat(` inside those backticks exactly as if it had been a real `feat(tui):` commit. Fix: - Type classification (feat / fix / perf / bang-syntax) reads only the squash subject. The merger sets the subject explicitly during squash- merge — it is the authoritative classification, not the body. - BREAKING CHANGE detection still reads the body, because per the Conventional Commits spec it lives in the footer, not the subject. The regex is now anchored to line start (`^BREAKING[ -]CHANGE:` with trailing colon) so prose references like "this is not a BREAKING CHANGE" do NOT match. - The branch-name-derived subject case (`feat/foo-bar` when the merger forgets to retype) is still handled — the `[(:/]` character class already accepts `/` as a separator, so `feat/foo-bar` triggers a minor bump from subject scan alone. Self-test (run before commit): echo "BREAKING CHANGE: yes" | grep -qE '^BREAKING[ -]CHANGE:' → match (correct — real footer) echo "no BREAKING CHANGE here" | grep -qE '^BREAKING[ -]CHANGE:' → no match (correct — prose mention) echo "feat(api): add foo" | grep -qiE '\bfeat[(:/]' → match (correct — real commit) echo "this references feat(api):" | grep -qiE '\bfeat[(:/]' → match (no longer relevant — this string would now only appear in the body, which is no longer scanned for feat)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the false-positive minor bump on PR #35 (docs restructure) that shipped v1.13.0 with no user-visible changes.
The release pipeline was scanning both subject AND body of every commit since the last tag, hoping to catch type lines preserved in squash bodies when the subject was branch-name-derived. That heuristic produced this false positive: the #35 PR description contained the literal back-tick-wrapped reference
…and the regex
\bfeat[(:/]matched the substringfeat(inside the backticks just as readily as it would have matched a realfeat(tui):commit. The release job classified the PR asminorand shipped v1.13.0 with nothing user-facing in it.Fix
%s%n%b(subject + body)%s(subject only) — the merger sets the squash subject explicitly and it IS the authoritative classificationBREAKING CHANGEdetectionBREAKING CHANGE^BREAKING[ -]CHANGE:in body anchored to line start with trailing colon — the Conventional Commits footer form. Prose mentions like "this is not a BREAKING CHANGE" no longer match.feat/foo-bar)[(:/]regex on subjects acceptsfeat/foo-barform nativelyDiff is ~30 lines, all in
.github/workflows/release.yml.Why this never bit before
The body-scan was a defense-in-depth measure for branch-name-derived squash subjects. In practice, every merge in this repo's history has had a properly conventional subject set by the merger, so the body scan never had to do its intended job — it just sat there waiting to false-positive. PR #35 was the first PR whose description text contained a conventional-commit-style reference to another PR, and that's when the bug surfaced.
Self-test
Smoke-tested the new regex on the prose vs. footer distinction:
Why this PR doesn't bump
The PR is committed as
chore(ci):, which falls through to the "skip release" branch in the workflow itself. Nov1.14.1release will be cut by merging this; the next user-visible feature PR will bump as normal.Test plan
`feat(tui)`inside backticks)^BREAKING[ -]CHANGE:anchor matches the Conventional Commits footer form but not casual prosechore(ci):does not match the bump regexes — this PR's own merge will skip the release job (no v1.14.1 will ship)