76296277
build: pre-push hook runs make ci before pushing to main
a73x 2026-07-25 16:45
Commit message
.githooks/pre-push
| Old | New | ||
|---|---|---|---|
| @@ -0,0 +1,34 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # | ||
| 3 | # pre-push — the merge gate. Any push that updates the shared `main` branch must | ||
| 4 | # pass `make ci` first (the same gate CI enforces). This is the guard that was | ||
| 5 | # missing when work merged to main red. | ||
| 6 | # | ||
| 7 | # Scope: ONLY pushes that update the remote refs/heads/main are gated. Feature- | ||
| 8 | # branch pushes and branch deletions run free. In a genuine emergency, bypass | ||
| 9 | # with `git push --no-verify`. | ||
| 10 | # | ||
| 11 | # Enable once per clone with: make hooks | ||
| 12 | set -euo pipefail | ||
| 13 | |||
| 14 | protected="refs/heads/main" | ||
| 15 | zero="0000000000000000000000000000000000000000" | ||
| 16 | |||
| 17 | # git feeds pre-push one line per ref being pushed: | ||
| 18 | # <local ref> <local oid> <remote ref> <remote oid> | ||
| 19 | gate=0 | ||
| 20 | while read -r _local_ref local_oid remote_ref _remote_oid; do | ||
| 21 | [ "$remote_ref" = "$protected" ] || continue # not touching main | ||
| 22 | [ "$local_oid" = "$zero" ] && continue # deleting main — nothing to test | ||
| 23 | gate=1 | ||
| 24 | done | ||
| 25 | |||
| 26 | [ "$gate" -eq 1 ] || exit 0 | ||
| 27 | |||
| 28 | echo "pre-push: '$protected' is being updated — running 'make ci' (bypass: git push --no-verify)" | ||
| 29 | if ! make ci; then | ||
| 30 | echo >&2 | ||
| 31 | echo "pre-push: BLOCKED — 'make ci' failed. Fix it, or override with 'git push --no-verify'." >&2 | ||
| 32 | exit 1 | ||
| 33 | fi | ||
| 34 | echo "pre-push: make ci is green — allowing the push to $protected" | ||
Makefile
| Old | New | ||
|---|---|---|---|
| @@ -12,7 +12,14 @@ LINT_WARN := errcheck,revive,gocyclo,funlen,gocritic,misspell,unconvert,nakedret | |||
| 12 | 12 | ||
| 13 | .PHONY: build build-go web test vet proto smoke smoke-go devstack sandbox clean \ | 13 | .PHONY: build build-go web test vet proto smoke smoke-go devstack sandbox clean \ |
| 14 | lint lint-extra arch cover tidy-check proto-check shape shape-check api api-check ci deadcode \ | 14 | lint lint-extra arch cover tidy-check proto-check shape shape-check api api-check ci deadcode \ |
| 15 | deploy | 15 | deploy hooks |
| 16 | |||
| 17 | # Enable the repo's client-side merge gate: point git at .githooks, whose | ||
| 18 | # pre-push hook runs `make ci` before any push that updates main. Run once per | ||
| 19 | # clone. Bypass a single push with `git push --no-verify`. | ||
| 20 | hooks: | ||
| 21 | git config core.hooksPath .githooks | ||
| 22 | @echo "git hooks enabled -> .githooks (pre-push runs 'make ci' on pushes to main)" | ||
| 16 | 23 | ||
| 17 | # Build the SvelteKit SPA and stage it into the Go embed dir. Requires Node. | 24 | # Build the SvelteKit SPA and stage it into the Go embed dir. Requires Node. |
| 18 | # `go build` works without this (the server serves a "UI not built" notice until | 25 | # `go build` works without this (the server serves a "UI not built" notice until |