From 0cfe88bf52a4efaaf8883ea44386970b70096231 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 23 Oct 2026 12:44:01 -0400 Subject: [PATCH 1/2] fix(check-affected): leave the guardrails git-hook copies to the excluded lint The pre-push check-affected job shellchecks every changed .sh file, so a commit that installs or refreshes the plugin-owned .githooks/guardrails/ copies cannot be pushed, though the workflow's shellcheck step excludes them. The job runs the merge-base copy of this script, so the fix must land first. Co-Authored-By: Claude Opus 5.5 --- scripts/check-affected.sh | 3 +++ scripts/check-affected.test.sh | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/check-affected.sh b/scripts/check-affected.sh index f94893feb0d..6db3272df0b 100755 --- a/scripts/check-affected.sh +++ b/scripts/check-affected.sh @@ -242,6 +242,9 @@ declare -a md=() sh=() py=() shebang=() plugins=() skill_touched=0 for f in ${changed[@]+"${changed[@]}"}; do case "$f" in + # Plugin-owned git-hook copies, linted where they are sourced; the workflow's + # lint step excludes them too. + .githooks/guardrails/*) ;; *.md) md+=("$f") ;; *.sh | *.bash) sh+=("$f") ;; *.py) py+=("$f") ;; diff --git a/scripts/check-affected.test.sh b/scripts/check-affected.test.sh index 30708b93dc0..ce5cb3ca747 100755 --- a/scripts/check-affected.test.sh +++ b/scripts/check-affected.test.sh @@ -329,7 +329,14 @@ if grep -q -- --rcfile <<<"$(shellcheck --help 2>&1)"; then run -- --uncommitted check "--uncommitted lints a changed shell file with the repository's .shellcheckrc" \ '[[ $RC == 1 && $ERR == *"FAIL shellcheck"* && $ERR == *"SC2292"* && $ERR != *"unrecognized option"* ]]' - rm -f "$repo/.shellcheckrc" "$repo/lint-me.sh" + rm -f "$repo/lint-me.sh" + mkdir -p "$repo/.githooks/guardrails" + printf '#!/usr/bin/env bash\nif [ -n "${1:-}" ]; then echo hi; fi\n' >"$repo/.githooks/guardrails/copy.sh" + chmod +x "$repo/.githooks/guardrails/copy.sh" + run -- --uncommitted + check "--uncommitted leaves the plugin-owned .githooks/guardrails copies to the workflow's excluded lint" \ + '[[ $RC == 0 && $ERR != *"FAIL shellcheck"* ]]' + rm -rf "$repo/.shellcheckrc" "$repo/.githooks" else ok "SKIP --uncommitted shellcheck case (no shellcheck with --rcfile here)" fi From 4a2d77c7f05b3cde65d9275f7dac053754042ebf Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 23 Oct 2026 12:51:20 -0400 Subject: [PATCH 2/2] fix(check-affected): skip only the copies' shell files and exclude them in CI too Review follow-up: the skip arm covers .sh and .bash only, matching what the workflow excludes; the workflow's ShellCheck step gets the matching exclude so the comment holds on main; the stay-quiet case asserts the routing message. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/pr-require-checks.yml | 2 ++ scripts/check-affected.sh | 6 +++--- scripts/check-affected.test.sh | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-require-checks.yml b/.github/workflows/pr-require-checks.yml index e2083c3ad25..6470b77c16f 100644 --- a/.github/workflows/pr-require-checks.yml +++ b/.github/workflows/pr-require-checks.yml @@ -1504,6 +1504,8 @@ jobs: with: files: ${{ steps.changed_shell.outputs.files }} rcfile: .shellcheckrc + # Plugin-owned guardrails git-hook copies, linted at their plugins/guardrails sources. + exclude: .githooks/guardrails/ - name: Aggregate hygiene results if: always() diff --git a/scripts/check-affected.sh b/scripts/check-affected.sh index 6db3272df0b..16c989236a1 100755 --- a/scripts/check-affected.sh +++ b/scripts/check-affected.sh @@ -242,9 +242,9 @@ declare -a md=() sh=() py=() shebang=() plugins=() skill_touched=0 for f in ${changed[@]+"${changed[@]}"}; do case "$f" in - # Plugin-owned git-hook copies, linted where they are sourced; the workflow's - # lint step excludes them too. - .githooks/guardrails/*) ;; + # Plugin-owned guardrails git-hook copies, linted at their plugins/guardrails + # sources; the workflow's ShellCheck step excludes .githooks/guardrails/ too. + .githooks/guardrails/*.sh | .githooks/guardrails/*.bash) ;; *.md) md+=("$f") ;; *.sh | *.bash) sh+=("$f") ;; *.py) py+=("$f") ;; diff --git a/scripts/check-affected.test.sh b/scripts/check-affected.test.sh index ce5cb3ca747..37e0cf5425b 100755 --- a/scripts/check-affected.test.sh +++ b/scripts/check-affected.test.sh @@ -335,7 +335,7 @@ if grep -q -- --rcfile <<<"$(shellcheck --help 2>&1)"; then chmod +x "$repo/.githooks/guardrails/copy.sh" run -- --uncommitted check "--uncommitted leaves the plugin-owned .githooks/guardrails copies to the workflow's excluded lint" \ - '[[ $RC == 0 && $ERR != *"FAIL shellcheck"* ]]' + '[[ $RC == 0 && $ERR != *"FAIL shellcheck"* && $ERR == *"SKIP shellcheck (no changed shell)"* ]]' rm -rf "$repo/.shellcheckrc" "$repo/.githooks" else ok "SKIP --uncommitted shellcheck case (no shellcheck with --rcfile here)"