a73x

76296277

build: pre-push hook runs make ci before pushing to main

a73x   2026-07-25 16:45

Commit message
build: pre-push hook runs make ci before pushing to main

Any push that updates main runs `make ci` client-side first, and a red run
blocks the push; feature-branch pushes and deletions run free, and a single
push can bypass with `--no-verify`. Enable per clone with `make hooks`.

.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