feat(hooks): one-command install-hooks.sh (worktree-safe) #170

Merged
clawdie merged 2 commits from fix/wiki-format-drift into main 2026-06-24 14:17:28 +02:00
3 changed files with 28 additions and 4 deletions

View file

@ -108,9 +108,9 @@ cargo build --workspace --release
./scripts/ci-checks.sh # fmt --check, clippy -D warnings, test, markdown gate, wiki-lint --strict
```
A `git push` to `main` also runs this gate through the pre-push hook (install
once: `ln -sf ../../scripts/pre-push .git/hooks/pre-push`). The hook rejects
the push if any gate fails; bypass only in emergencies with `--no-verify`.
A `git push` to `main` also runs this gate through the pre-push hook
(activate once: `./scripts/install-hooks.sh`). The hook rejects the push if
any gate fails; bypass only in emergencies with `--no-verify`.
`.forgejo/workflows/ci.yml` encodes the same checks, but **no Actions runner is
currently registered**, so nothing enforces them server-side. Until a runner is

View file

@ -11,7 +11,7 @@ A change is not "done" until the gate passes locally:
```
The pre-push hook (`scripts/pre-push`) runs this same gate on every `git push`
to `main`install once with `ln -sf ../../scripts/pre-push .git/hooks/pre-push`.
to `main`activate once per clone with `./scripts/install-hooks.sh`.
The hook rejects the push if any gate fails; bypass only in emergencies with
`--no-verify`.

24
scripts/install-hooks.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh
# Install git hooks for this clone. Run once per clone (idempotent).
#
# ./scripts/install-hooks.sh
#
# After this, every `git push` runs ci-checks.sh + wiki-lint --strict and
# rejects the push if the gate fails. Bypass only with --no-verify.
set -eu
repo_root="$(git rev-parse --show-toplevel)"
src="${repo_root}/scripts/pre-push"
[ -f "$src" ] || { echo "error: ${src} not found" >&2; exit 1; }
chmod +x "$src"
# --git-path resolves the real hooks dir even in worktrees / custom git dirs,
# where .git is a file or the hooks live outside <repo>/.git/hooks.
cd "$repo_root"
hooks_dir="$(git rev-parse --git-path hooks)"
mkdir -p "$hooks_dir"
# Symlink to the absolute source path → robust regardless of where the hooks
# dir actually lives (a relative target breaks for worktrees).
ln -sf "$src" "${hooks_dir}/pre-push"
echo "hooks installed: pre-push -> ${src}"