Problem
bin/gstack-pr-title-rewrite.sh corrupts a PR title that is a bare version with no description (e.g. v1.2.3), duplicating the version prefix instead of leaving it alone / replacing it.
The helper's header documents three cases: (1) already v<NEW_VERSION> -> no change, (2) different v<digits.dots> prefix -> replace, (3) no prefix -> prepend. But both the no-change case glob ("v$NEW_VERSION "*) and the strip sed (s/^v[0-9]+(\.[0-9]+)+ //) anchor on a trailing space. A title that is only a version (nothing after it) matches neither, so it falls through to case 3 (prepend).
Current behavior on main (cab774c / v1.56.0.0)
$ ./bin/gstack-pr-title-rewrite.sh 1.2.3.4 'v1.2.3.4'
v1.2.3.4 v1.2.3.4 # should be unchanged (case 1)
$ ./bin/gstack-pr-title-rewrite.sh 1.2.3.4 'v1.2.3'
v1.2.3.4 v1.2.3 # stale prefix kept + duplicated (should replace -> v1.2.3.4)
It is also not idempotent on these inputs, and it never self-heals: once the title is v1.2.3.4 v1.2.3.4, the duplicated form matches case 1 and is returned unchanged.
Why it matters (reachable in CI)
.github/workflows/pr-title-sync.yml runs on every PR opened/edited/synchronize, feeds the PR's real title through this helper, and then runs gh pr edit --title "$NEW_TITLE". A version-only PR title — the format ship/CHANGELOG uses for branch-ahead "version bump" PRs — gets rewritten to the duplicated form and written back to the PR.
Expected behavior
v1.2.3.4 (already correct, bare) -> v1.2.3.4 (no change)
v1.2.3 (different, bare) -> v1.2.3.4 (replace prefix)
- Titles with a description keep working exactly as today.
Duplicate search performed
Candidate fix shape
Match the bare "v$NEW_VERSION" form in the no-change case, change the strip regex to anchor on a space or end-of-string (( |$)), and emit a bare prefix when the stripped remainder is empty. Plus regression tests for bare-correct / bare-different / bare-idempotency that fail on current main.
PR incoming.
Problem
bin/gstack-pr-title-rewrite.shcorrupts a PR title that is a bare version with no description (e.g.v1.2.3), duplicating the version prefix instead of leaving it alone / replacing it.The helper's header documents three cases: (1) already
v<NEW_VERSION>-> no change, (2) differentv<digits.dots>prefix -> replace, (3) no prefix -> prepend. But both the no-changecaseglob ("v$NEW_VERSION "*) and the stripsed(s/^v[0-9]+(\.[0-9]+)+ //) anchor on a trailing space. A title that is only a version (nothing after it) matches neither, so it falls through to case 3 (prepend).Current behavior on
main(cab774c / v1.56.0.0)It is also not idempotent on these inputs, and it never self-heals: once the title is
v1.2.3.4 v1.2.3.4, the duplicated form matches case 1 and is returned unchanged.Why it matters (reachable in CI)
.github/workflows/pr-title-sync.ymlruns on every PRopened/edited/synchronize, feeds the PR's real title through this helper, and then runsgh pr edit --title "$NEW_TITLE". A version-only PR title — the format ship/CHANGELOG uses for branch-ahead "version bump" PRs — gets rewritten to the duplicated form and written back to the PR.Expected behavior
v1.2.3.4(already correct, bare) ->v1.2.3.4(no change)v1.2.3(different, bare) ->v1.2.3.4(replace prefix)Duplicate search performed
pr title rewrite,title duplicate version— no existing issue.pr-title-rewrite,title sync; scanned all open PRs for ones touchingbin/gstack-pr-title-rewrite.shor.github/workflows/pr-title-sync.yml— none. The only related PRs are v1.23.0.0 feat: always prefix PR titles with v<VERSION> #1284 (merged, the original feature) and v1.11.0.0 feat(ship): workspace-aware version allocation #1168 (merged, workspace-aware version allocation); neither addresses the bare-version case.Candidate fix shape
Match the bare
"v$NEW_VERSION"form in the no-changecase, change the strip regex to anchor on a space or end-of-string (( |$)), and emit a bare prefix when the stripped remainder is empty. Plus regression tests for bare-correct / bare-different / bare-idempotency that fail on currentmain.PR incoming.