Skip to content

fix(scripts): portable uppercase for branch-name acronym retention (bash 3.2)#3192

Merged
mnriem merged 4 commits into
github:mainfrom
PascalThuet:fix/branch-name-acronym-bash32
Jun 30, 2026
Merged

fix(scripts): portable uppercase for branch-name acronym retention (bash 3.2)#3192
mnriem merged 4 commits into
github:mainfrom
PascalThuet:fix/branch-name-acronym-bash32

Conversation

@PascalThuet

Copy link
Copy Markdown
Contributor

Description

Branch-name generation keeps short uppercase acronyms (e.g. AI) by re-checking the lowercased word against the original description with ${word^^}. That parameter expansion is bash 4+ only; on macOS's default bash 3.2 it errors with bad substitution, so the acronym / short-word retention branch never matches and those words are silently dropped (go AI now yields 001-now instead of 001-ai-now).

Replace ${word^^} with tr '[:lower:]' '[:upper:]', which is portable. Applies to both the core scripts/bash/create-new-feature.sh and the git extension's extensions/git/scripts/bash/create-new-feature-branch.sh. No behavior change on bash 4+.

CI runs on bash 4+/Linux, so the existing tests passed there; the bug only shows on the default macOS shell.

Testing

  • On macOS bash 3.2.57: test_branch_name_short_word_case_sensitivity and test_short_word_retention[go AI now-001-ai-now] now pass (they failed before this fix).
  • Full branch-naming suites green: test_timestamp_branches, test_git_extension, test_branch_numbering (99 passed, 35 skipped).
  • shellcheck --severity=error clean on both scripts.

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

An AI coding agent surfaced the failing tests while running the suite on macOS and pinned the root cause (${word^^} vs bash 3.2); the fix was written and reviewed by me.

Branch-name generation keeps short uppercase acronyms (e.g. "AI") by re-checking
the lowercased word against the original description with ${word^^}. That
parameter expansion is bash 4+ only; on macOS's default bash 3.2 it errors with
"bad substitution", so the acronym/short-word retention branch never matches and
those words are dropped ("go AI now" yields 001-now instead of 001-ai-now). Use
tr '[:lower:]' '[:upper:]' instead, which is portable.

Applies to both the core create-new-feature.sh and the git extension's
create-new-feature-branch.sh. The existing
test_branch_name_short_word_case_sensitivity / test_short_word_retention tests
cover this and now pass on bash 3.2 (CI runs on bash 4+/Linux, so they passed
there already).

(Disclosure: an AI coding agent surfaced the failure while running the suite on
macOS and pinned the root cause; fix written and reviewed by me.)
@PascalThuet PascalThuet requested a review from mnriem as a code owner June 27, 2026 06:17
- core create-new-feature.sh: match the acronym with `grep -qw` (POSIX
  whole-word) instead of `\b...\b` (GNU/BSD-only), matching the git extension
  and dropping a non-POSIX construct.
- lint: add a CI guard rejecting bash 4+ case-modification expansions in *.sh.
  shellcheck assumes bash 4+ from the shebang and can't flag them, and CI has no
  bash-3.2 lane, so this prevents silently re-shipping the macOS regression this
  PR fixes.
- update a stale PowerShell extension comment that cited the removed bash idiom.

(Disclosure: prompted by an AI code review of the PR; written and reviewed by me.)

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 fixes branch-name generation on macOS’s default Bash 3.2 by removing Bash-4-only ${var^^} case expansion from the short-word/acronym retention logic, replacing it with a portable tr-based uppercase conversion and a whole-word match.

Changes:

  • Replace ${word^^} with tr '[:lower:]' '[:upper:]' for acronym detection in both core and git-extension Bash scripts.
  • Align matching behavior to use grep -w whole-word matching rather than \b word boundaries.
  • Add a CI lint guard to prevent future use of Bash 4+ case-modification expansions in *.sh files, and document the fix in the changelog.
Show a summary per file
File Description
scripts/bash/create-new-feature.sh Uses portable uppercase conversion + whole-word matching to retain acronyms on Bash 3.2.
extensions/git/scripts/bash/create-new-feature-branch.sh Applies the same portable acronym retention logic in the git extension’s branch script.
extensions/git/scripts/powershell/create-new-feature-branch.ps1 Comment-only clarification about case-sensitive acronym matching parity.
CHANGELOG.md Documents the portability fix.
.github/workflows/lint.yml Adds a CI guard to reject Bash 4+ case-modification expansions in shell scripts.

Review details

Tip

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

  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread CHANGELOG.md Outdated
Comment thread .github/workflows/lint.yml Outdated

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please address Copilot feedback

Assisted-by: OpenAI Codex (model: GPT-5, autonomous)

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.

Review details

  • Files reviewed: 5/5 changed files
  • Comments generated: 3
  • Review effort level: Low

Comment thread scripts/bash/create-new-feature.sh
Comment thread extensions/git/scripts/bash/create-new-feature-branch.sh
Comment thread .github/workflows/lint.yml Outdated
@mnriem

mnriem commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Please address Copillot feedback. If not applicable, please explain why. And please resolve test & lint errors. Also please revert CHANGELOG.md as it is automatically generated.

Assisted-by: OpenAI Codex (model: GPT-5, autonomous)
@PascalThuet

Copy link
Copy Markdown
Contributor Author

Posted on behalf of @PascalThuet by OpenAI Codex (model: GPT-5).

Addressed the latest Copilot review round in commit 61470a2. The branch-description pipelines now use printf before grep in both bash implementations, the bash case-modification guard now requires the closing brace and catches trailing patterns, and the merge from origin/main keeps CHANGELOG.md generated-only by dropping the manual entry.

Validation: targeted pytest suite passed locally: 106 passed, 45 skipped.

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.

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Low

@mnriem mnriem self-requested a review June 30, 2026 14:33
@mnriem mnriem merged commit 86709f6 into github:main Jun 30, 2026
12 checks passed
@mnriem

mnriem commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

kanfil added a commit to tikalk/agentic-sdlc-spec-kit that referenced this pull request Jun 30, 2026
Upstream commits merged (19):
- Retire iflow/roo/windsurf integrations (github#3166, github#3167, github#3168, github#3211, github#3212, github#3213)
- Move version_satisfies to _utils.py, allow prereleases (github#2695)
- Workflow fan-out max_concurrency via bounded thread pool (github#3224)
- Reject bool max_iterations in while/do-while validation (github#3237)
- bash 3.2 portability: echo→printf, ${word^^}→tr (github#3192)
- --no-persist in common.sh for read-only path resolution (github#3025)
- Reject host-less catalog URLs (github#3209, github#3227)
- Extension updates: Intake v0.1.3, Architecture Workflow v1.2.2,
  Repository Governance, Workflow Preset v1.3.11
- Release 0.12.1 → 0.12.2 → 0.12.3.dev0 (github#3253, github#3259)
- CI Python matrix alignment + bash 3.2 portability (github#3244)
- Docs: Windsurf→Kilo Code references throughout

Conflicts resolved (2):
- pyproject.toml: kept fork name/description, bumped to 0.12.2+adlc1
- AGENTS.md: accepted upstream's condensed agent table (retired agents removed)

Assisted-by: opencode (model: glm-5.2, supervised)
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.

3 participants