ceremony/test/refs-not-closing.test.sh

104 lines
4 KiB
Bash
Raw Normal View History

2026-08-03 20:29:51 +00:00
#!/usr/bin/env bash
# Contract tests for actions/refs-not-closing (issue #218). Bodies and
# closing-reference sets are fixtures: no network and no pull request are
# involved. set -u, not -e: failures are behavior for the harness to inspect.
set -u
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=test/harness.sh
. "$ROOT/test/harness.sh"
SCRIPT="$ROOT/actions/refs-not-closing/refs-not-closing.sh"
ACTION="$ROOT/actions/refs-not-closing/action.yml"
WORKFLOW="$ROOT/.github/workflows/refs-guard.yml"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
body() {
local name="$1"
shift
printf '%s\n' "$@" >"$TMP/$name.md"
}
guard() {
local name="$1"
shift
bash "$SCRIPT" "$TMP/$name.md" "$@"
}
body ref-5 'Refs #5'
check "Refs target with empty closing set passes" 0 "no Refs target" guard ref-5
check "Refs target with itself closing fails" 1 "#5" guard ref-5 5
check "Refs target with another issue closing passes" 0 "no Refs target" guard ref-5 9
body ordinary 'Closes #5'
check "ordinary Closes PR remains green" 0 "no Refs target" guard ordinary 5
body mixed 'Refs #5' '' 'This PR legitimately Closes #9.'
check "Refs #5 plus Closes #9 remains green" 0 "no Refs target" guard mixed 9
body prose 'Refs #5' '' 'Triage closes #5 by hand after the live proof.'
check "closing prose for a Refs target fails" 1 "closes #5" guard prose 5
check "failure prints the surrounding sentence" 1 \
"sentence: Triage closes #5 by hand after the live proof" guard prose 5
check "failure offers number-first rewrite" 1 "#N is" guard prose 5
check "failure offers number-free rewrite" 1 "closes the issue" guard prose 5
2026-08-03 20:34:35 +00:00
body code-span 'Refs #5' '' "The body must not contain \`Closes #5\` anywhere."
2026-08-03 20:29:51 +00:00
check "backticked closing keyword still fails" 1 "Closes #5" guard code-span 5
check "backtick failure explains that code spans do not protect" 1 \
"Backticks do not protect" guard code-span 5
body adjacency 'Refs #5' '' 'Triage closes #9 and #5 after the proof.'
check "non-adjacent #5 does not join closing set #9" 0 "no Refs target" \
guard adjacency 9
body empty ''
check "empty body remains green" 0 "no Refs target" guard empty 5
body incidents-211 'Refs #209' 'Triage closes #209 by hand.'
check "#211 incident replays red" 1 "#209" guard incidents-211 209
body incidents-214 'Refs #212' 'Triage closes #212 and #209 on that evidence.'
check "#214 incident replays red" 1 "#212" guard incidents-214 212
2026-08-03 20:34:35 +00:00
body incidents-200 'Refs #199' "A later edit added \`Closes #199\`."
2026-08-03 20:29:51 +00:00
check "#200 incident replays red" 1 "#199" guard incidents-200 199
body multiple 'Refs #5 and Refs #7.' 'Triage closes #5 and fixes #7 by hand.'
check "failure names every intersecting issue" 1 \
"scheduled to close: #5 #7" guard multiple 5 7
2026-08-03 20:29:51 +00:00
for number in 207 191 190 176 165 164; do
body "incident-$number" "Refs #$number"
check "#$number incident replays green" 0 "no Refs target" \
guard "incident-$number"
done
check "missing body is a loud failure" 1 "missing or unreadable" \
bash "$SCRIPT" "$TMP/missing.md"
check "invalid closing set is a loud failure" 1 "invalid closing issue" \
guard ref-5 nope
# The action owns the network boundary. These structural assertions keep a
# future edit from suppressing a failed/partial GraphQL read or splitting the
# one authoritative query into several drifting reads.
2026-08-03 20:34:35 +00:00
one_graphql_read() {
[ "$(grep -c "gh api graphql" "$ACTION")" -eq 1 ]
printf '1\n'
}
2026-08-03 20:29:51 +00:00
check "action performs exactly one GraphQL read" 0 "1" \
2026-08-03 20:34:35 +00:00
one_graphql_read
2026-08-03 20:29:51 +00:00
check "action refuses a partial closing-reference page" 0 "hasNextPage" \
grep -F "hasNextPage" "$ACTION"
check "action does not suppress GraphQL failure" 1 "" \
grep -E 'gh api graphql.*(\|\| true|\| true)' "$ACTION"
check "workflow wakes on body edits" 0 "types: [opened, edited, reopened, synchronize]" \
grep -F "types: [opened, edited, reopened, synchronize]" "$WORKFLOW"
check "workflow is pull_request-only" 1 "" grep -E '^ (push|pull_request_target|workflow_dispatch):' "$WORKFLOW"
check "workflow grants read-only pull request access" 0 "pull-requests: read" \
grep -F "pull-requests: read" "$WORKFLOW"
summary