Skip to content

ci: run .claude/hooks/*.selftest.sh on every PR touching the hooks - #6022

Merged
yinlianghui-tw merged 1 commit into
mainfrom
claude/issue-5754-ci-runs-hook-selftests
Aug 24, 2026
Merged

yinlianghui-tw merged 1 commit into
mainfrom
claude/issue-5754-ci-runs-hook-selftests

Conversation

@yinlianghui-tw

Copy link
Copy Markdown
Collaborator

Fixes #5754

What

Adds .github/workflows/hook-selftests.yml: a required check that runs
.claude/hooks/guard-main-checkout-bash.selftest.sh and
.claude/hooks/guard-shared-stash.selftest.sh on every PR (and push to main)
that touches .claude/hooks/** or the workflow file itself, and fails the
build
the moment either self-test matrix reports a failing case. This is a
runner only — .claude/** (the hooks and their self-tests) is untouched, per
this card's ruling.

Measured before wiring anything (Zone 2)

On origin/main @ 53dc89db8, both self-tests were already green:

guard-main-checkout-bash.selftest.sh: 100 passed, 0 failed  — real 0m3.198s
guard-shared-stash.selftest.sh:        32 passed, 0 failed  — real 0m0.637s

Both need only jq and git (both preinstalled on ubuntu-latest) — no
install, no build. Runtime cost of the new job is therefore ~4s of self-test
execution plus a checkout.

Paired writes (PR #5984 shape)

  • content/docs/guide/ci-cd-pipeline.md — workflow-inventory table row +
    a new ### Hook Self-Tests (hook-selftests.yml) section, plus the
    OPTIONAL_CONTEXTS enumeration in the Dependabot Auto-Merge prose.
  • scripts/dependabot-merge-gate.mjs — classifies the new Hook
    Self-Tests
    check as OPTIONAL_CONTEXTS (path-filtered like Changeset Bump Policy / Bundle Analysis: present → must be success; absent → a
    Dependabot bump never touches .claude/hooks/**, so it is never waited
    for).

scripts/__tests__/ci-cd-pipeline-doc.test.ts and
scripts/__tests__/dependabot-merge-gate.test.ts went red before these two
writes (undocumented workflow / unclassified produced check) and pass now —
that is them working correctly.

Why path-filtered, unlike control-bytes.yml

control-bytes.yml carries no paths filter because a raw control byte can
land in a markdown-only PR as easily as a TypeScript one. That does not
transfer here: both self-tests assert the current hook script's behaviour
against a fixture they build themselves — nothing about a docs-only PR can
move the result. So this workflow mirrors changeset-guard.yml's
path-filtered shape instead (see the workflow's own header for the full
reasoning and cost note).

Tests


Generated by Claude Code

Adds .github/workflows/hook-selftests.yml, a required check that runs the
guard-main-checkout-bash and guard-shared-stash self-test matrices whenever
.claude/hooks/** changes, and fails the build the moment either goes red.
Neither self-test's own instruction to "run after touching the hook" had a
gate behind it before this.

Paired writes (PR #5984 shape): content/docs/guide/ci-cd-pipeline.md gets
the workflow's inventory row + section, and scripts/dependabot-merge-gate.mjs
classifies the new "Hook Self-Tests" check as OPTIONAL_CONTEXTS (path-filtered,
same as Changeset Bump Policy). Does not modify the hooks or their self-tests
— .claude/** stays untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
@yinlianghui-tw
yinlianghui-tw marked this pull request as ready for review August 24, 2026 14:13
@yinlianghui-tw
yinlianghui-tw added this pull request to the merge queue Aug 24, 2026
Merged via the queue into main with commit 69a27ef Aug 24, 2026
23 checks passed
@yinlianghui-tw
yinlianghui-tw deleted the claude/issue-5754-ci-runs-hook-selftests branch August 24, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] Nothing in CI runs the .claude/hooks/*.selftest.sh matrices — a broken PreToolUse guard lands green

2 participants