Skip to content

Commit 4038d37

Browse files
mnriemCopilot
andauthored
chore: align CI Python matrix with devguide lifecycle + fix bash 3.2 portability (#3244)
* chore: align CI Python matrix with devguide release lifecycle Run the pytest matrix only on the bugfix (maintenance) releases — 3.13 and 3.14 — instead of 3.11/3.12/3.13, and point the ruff lint job at the latest interpreter (3.14). The supported floor stays at requires-python >= 3.11 (oldest non-EOL security release): older security versions are supported by claim and fixed reactively rather than gated on a wide per-commit matrix. Also add macos-latest to the OS matrix so macOS regressions are caught. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: make bash scripts portable to bash 3.2 (macOS system /bin/bash) Adding macos-latest to the CI matrix surfaced two pre-existing bash 3.2 incompatibilities (macOS ships bash 3.2 as /bin/bash): 1. update-agent-context.sh embedded Python heredocs inside $(...) command substitution. bash 3.2 mis-parses an apostrophe in a heredoc body nested in $(...), failing with "unexpected EOF while looking for matching `''". Removed the apostrophes from the affected $()-nested heredoc body and documented the constraint to prevent regressions. 2. create-new-feature-branch.sh and create-new-feature.sh used the bash 4+ ${word^^} uppercase parameter expansion, which errors as a "bad substitution" on bash 3.2 and caused short uppercase acronyms (e.g. "GO") to be dropped from derived branch names. Replaced with a portable `tr '[:lower:]' '[:upper:]'` pipeline. Verified the full test suite passes under bash 3.2.57 and shellcheck (--severity=error) is clean. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address review feedback on bash 3.2 portability changes - create-new-feature.sh: replace the non-portable `\b...\b` grep word-boundary (BSD grep treats `\b` as a backspace, so the acronym branch could silently fail) with `grep -qw`, matching its twin create-new-feature-branch.sh, and pipe the description via `printf '%s'` instead of `echo`. - create-new-feature-branch.sh: switch the acronym check to `printf '%s'` as well so both twins are identical and avoid `echo` on user-provided text. - update-agent-context.sh: reword the apostrophe-free self-seeding comment to be clearer and less easy to misread. Verified under bash 3.2.57 (full bash-script suite green) and shellcheck --severity=error. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ea18277 commit 4038d37

4 files changed

Lines changed: 19 additions & 12 deletions

File tree

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Set up Python
2222
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
2323
with:
24-
python-version: "3.13"
24+
python-version: "3.14"
2525

2626
- name: Run ruff check
2727
run: uvx ruff check src/
@@ -30,8 +30,8 @@ jobs:
3030
runs-on: ${{ matrix.os }}
3131
strategy:
3232
matrix:
33-
os: [ubuntu-latest, windows-latest]
34-
python-version: ["3.11", "3.12", "3.13"]
33+
os: [ubuntu-latest, windows-latest, macos-latest]
34+
python-version: ["3.13", "3.14"]
3535
steps:
3636
- name: Checkout
3737
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

extensions/agent-context/scripts/bash/update-agent-context.sh

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ case "$(uname -s 2>/dev/null || true)" in
5959
esac
6060

6161
# Parse extension config once; emit context files as JSON, followed by marker strings.
62+
#
63+
# NOTE (bash 3.2 / macOS portability): the embedded Python heredocs below run
64+
# inside $(...) command substitution. bash 3.2 (the system /bin/bash on macOS)
65+
# mis-parses a single-quote/apostrophe in a heredoc body nested in $(...),
66+
# failing with "unexpected EOF while looking for matching `''". Keep these
67+
# $(...)-nested heredoc bodies free of apostrophes (use double quotes in Python
68+
# string literals and avoid contractions in comments).
6269
if ! _raw_opts="$("$_python" - "$EXT_CONFIG" "$_case_insensitive_context_files" "$PROJECT_ROOT" <<'PY'
6370
import json
6471
import sys
@@ -113,11 +120,11 @@ if isinstance(raw_files, list):
113120
if not context_files:
114121
add_context_file(get_str(data, "context_file"))
115122
if not context_files:
116-
# Self-seed: the agent-context extension owns its lifecycle, so when its
117-
# own config declares no target it derives one from the active integration
118-
# recorded in init-options.json, using the extension's OWN bundled mapping
119-
# (agent-context-defaults.json). This is independent of the Specify CLI by
120-
# design — nothing here imports specify_cli.
123+
# Self-seed: the agent-context extension manages its own lifecycle, so when
124+
# its config declares no target, it derives one from the active integration
125+
# recorded in init-options.json, mapped through the bundled
126+
# agent-context-defaults.json file. This is independent of the Specify CLI
127+
# by design; nothing here imports specify_cli.
121128
project_root = sys.argv[3] if len(sys.argv) > 3 else "."
122129
integration_key = ""
123130
try:
@@ -144,15 +151,15 @@ if not context_files:
144151
except Exception:
145152
print(
146153
"agent-context: unable to read %s; cannot self-seed the context "
147-
"file. Set 'context_file' in the extension config." % defaults_path,
154+
"file. Set context_file in the extension config." % defaults_path,
148155
file=sys.stderr,
149156
)
150157
mapping = {}
151158
add_context_file(mapping.get(integration_key, "") or "")
152159
if not context_files:
153160
print(
154161
"agent-context: no default context file is known for integration "
155-
"'%s'. Set 'context_file' in the extension config to choose one."
162+
"%s. Set context_file in the extension config to choose one."
156163
% integration_key,
157164
file=sys.stderr,
158165
)

extensions/git/scripts/bash/create-new-feature-branch.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ generate_branch_name() {
288288
if ! echo "$word" | grep -qiE "$stop_words"; then
289289
if [ ${#word} -ge 3 ]; then
290290
meaningful_words+=("$word")
291-
elif echo "$description" | grep -qw -- "${word^^}"; then
291+
elif printf '%s' "$description" | grep -qw -- "$(printf '%s' "$word" | tr '[:lower:]' '[:upper:]')"; then
292292
meaningful_words+=("$word")
293293
fi
294294
fi

scripts/bash/create-new-feature.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ generate_branch_name() {
152152
if ! echo "$word" | grep -qiE "$stop_words"; then
153153
if [ ${#word} -ge 3 ]; then
154154
meaningful_words+=("$word")
155-
elif echo "$description" | grep -q "\b${word^^}\b"; then
155+
elif printf '%s' "$description" | grep -qw -- "$(printf '%s' "$word" | tr '[:lower:]' '[:upper:]')"; then
156156
# Keep short words if they appear as uppercase in original (likely acronyms)
157157
meaningful_words+=("$word")
158158
fi

0 commit comments

Comments
 (0)