Files
ISEP/scripts/test-github-contact-guard.sh
isep-hand 49a7145e70 兩支閘改看「指令要動的那個 repo」,不看 hook 自己的環境/cwd(inkstone/ISEP#109 → comment 6629)
① line-needs-own-worktree.sh:出路 `WORKTREE_OK=1 git -C … checkout …` 改認指令字串裡的字面前綴
   (舊版讀 hook 自己的環境變數,PreToolUse hook 跟指令不是同一個行程,那行永遠走不通)。
   判準是位置不是字:前綴必須掛在會移動 HEAD 的那條 git 指令上。
   lib/checkout_target_dir.py 加 `--escape NAME=1`;push_target_dir._classify 在 strip_env 時
   把前綴留在 verb 事件裡(find_push_target 行為不變,主線閘 10+19 條照綠)。
② github-contact-guard.sh:remote 名在「這條指令實際會推的那個 repo」裡解(沿用 lib/push_target_dir.py
   解 cd 鏈/-C/子殼),解不出來才退回 cwd。判準仍是 remote URL 主機,不是「有 -C 就放行」。

測試:A24 59→69(E 群把閘印的那一行原樣餵回去;舊閘 3 條紅)、
      A39 14→26(payload 帶 cwd、cwd≠目標 repo;舊閘 7 條紅=4 誤攔+3 漏擋)。
盤點表:61 支/85 條,改判準不加閘,當場數的。
版本:待總管定版。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4
2026-09-07 06:31:45 +00:00

77 lines
4.7 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# github-contact-guard 的測試(inkstone/InkStoneCo#23
# 判準:真的寫 GitHubgh CLI 高頻 API、git push/remote add 指向 github.com)要擋;
# 只是提到(heredoc body、同一行引號內的散文、commit message)不准擋;
# 讀取(clone/fetch/pull/curl 抓檔)一律放行,不管有沒有帶認證。
cd "$(dirname "$0")/.." || exit 1
H=hooks/github-contact-guard.sh
PASS=0; FAIL=0
run(){ # $1=want $2=cmd
printf '%s' "{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$2")}}" \
| bash "$H" >/dev/null 2>&1
got=$?
if [ "$got" = "$1" ]; then PASS=$((PASS+1)); printf ' ✅ '; else FAIL=$((FAIL+1)); printf ' ❌ '; fi
printf 'want=%s got=%s %.72s\n' "$1" "$got" "$2"
}
echo "── 該擋:真的在寫 GitHub ──"
run 2 'gh issue create --title x --body y'
run 2 'gh pr create --title x'
run 2 'git push https://github.com/example/example.git HEAD:main'
run 2 'git remote add github https://github.com/example/example.git'
run 2 'echo start && gh api repos/example/example/issues'
echo "── 不該擋:讀取一律放行 ──"
run 0 'git clone https://github.com/example/example.git'
run 0 'git fetch github'
run 0 'curl -sL https://github.com/example/example/releases/latest'
run 0 'gh --version'
echo "── 不該擋:只是提到、heredoc body、同一行引號內的散文 ──"
run 0 "$(printf 'cat > docs/TESTING.md <<%sEOF%s\nexample: git push https://github.com/example/example.git HEAD:main\nEOF\n' "'" "'")"
run 0 'git commit -m "docs: explain why gh api calls used to be mis-flagged"'
run 0 'python3 -c "requests.post(url, json={\"body\": \"quoting: git push origin main to github.com was mis-flagged as a real push\"})"'
run 0 'grep -n "gh api" hooks/github-contact-guard.sh'
run 0 'grep -rn "git push" installer/scripts/line-source-repo.mjs'
echo "── 判「push 到哪」要看這條指令實際會推的那個 repo,不是 hook 站的 cwdinkstone/ISEP#109 → comment 66292026-09-07 實撞)──"
# 為什麼這群非有不可:雲端薄殼的 cwd 是 GitHub 那份(origingithub.com),而總管在
# `InkStoneCo/`originGitea)推分支。舊版拿 **hook 收到的 cwd** 去解 `origin`
# 於是 `git -C <InkStoneCo> push origin x` 被判成「remote origin 指向 GitHub」擋下
# ——連 `-C` 都沒看。arcrun-hand 同日在 Arcrun#176 comment 6614 撞到同一支。
# 判準仍是唯一識別碼(remote 解出來的 URL 主機),不是名字;**不是「有 -C 就放行」**——
# 下面「該擋」那組就是 -C/cd 指到 GitHub 那份時照擋的證據。
W=$(mktemp -d "${TMPDIR:-/tmp}/isep-ghc.XXXXXX"); trap 'rm -rf "$W"' EXIT
W=$(cd "$W" && pwd -P)
mk(){ git init -q -b main "$1" && git -C "$1" remote add origin "$2"; }
mk "$W/shell" https://github.com/example/shell.git # 薄殼:originGitHub
mk "$W/body" https://git.example.invalid/inkstone/body.git # 真身:originGitea 的形狀(主機不是 github.com
mkdir -p "$W/body/sub"
runc(){ # $1=want $2=cwd $3=cmd —— 跟 run 一樣,只是 payload 帶 cwd(hook 真的會收到它)
LAST_ERR=$(printf '%s' "{\"tool_name\":\"Bash\",\"cwd\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$2"),\"tool_input\":{\"command\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$3")}}" \
| bash "$H" 2>&1 >/dev/null)
got=$?
if [ "$got" = "$1" ]; then PASS=$((PASS+1)); printf ' ✅ '; else FAIL=$((FAIL+1)); printf ' ❌ '; fi
printf 'want=%s got=%s cwd=%s %.60s\n' "$1" "$got" "${2#$W/}" "$3"
}
has(){ if printf '%s' "$LAST_ERR" | grep -qF -- "$1"; then PASS=$((PASS+1)); printf ' ✅ '; else FAIL=$((FAIL+1)); printf ' ❌ '; fi; printf '%s\n' "$2"; }
echo " · 該擋:這條指令實際推的那個 repo 的 origin 是 github.com"
runc 2 "$W/shell" 'git push origin x'
runc 2 "$W/body" "git -C $W/shell push origin x"
has "$W/shell" " 訊息說得出是哪個目錄的 remote 指向 GitHub(人才知道自己站錯地方還是推錯地方)"
runc 2 "$W/body" "cd $W/shell && git push origin x"
runc 2 "$W/shell" "(cd $W/body && true); git push origin x"
runc 2 "$W/shell" 'cd $SOMEWHERE && git push origin x'
echo " · 不該擋:這條指令實際推的那個 repo 的 origin 不是 github.com(★=6629 那天被擋的形狀)"
runc 0 "$W/shell" "git -C $W/body push origin x"
runc 0 "$W/shell" "git -C $W/body push -u origin feat/x"
runc 0 "$W/shell" "cd $W/body && git push origin x"
runc 0 "$W/body/sub" 'git push origin x'
runc 0 "$W/shell" "cd $W && git -C body push origin x"
runc 0 "$W/body" "(cd $W/shell && true); git push origin x"
echo
echo "$PASS/$((PASS+FAIL)) 通過"
[ "$FAIL" -eq 0 ]