Intelligent Git Pre-Commit and Pre-Push Workflow
This document details the architecture, configuration, operation, and troubleshooting of the Git hook workflow for the GitHub Backup Automation System monorepo. The work is split so commits stay fast:
.githooks/pre-commitruns fast checks only: secret scan, formatting and lint, static analysis, and the unit tests of the areas that changed..githooks/pre-pushre-runs those checks for the commits being pushed and adds the slow builds: static Go binaries, the Next.js production build, and Docker images when Docker files change.
1. Architecture Overview
The repository is a polyglot monorepo containing three codebases:
- Go Backend, Worker CLI & MCP Server: Go 1.25 module (
github.com/MishraShardendu22/github-backup) powering the Fiber REST/WebSocket API, the backup worker and the MCP server. - AI Observatory Service: FastAPI + LangChain Tool-Calling RAG application managed with
uvundersrc/services/github-backup-observatory/. - Dashboard Application: Next.js 16 (App Router, Turbopack, React 19, Biome, Tailwind CSS v4, the Observatory design system packages) under
src/apps/github-backup-dashboard/.
flowchart TD
A["git commit"] --> B["pre-commit: detect staged files"]
B --> C{"Affected subsystems"}
C -->|"Go files"| D1["gofmt, go vet, go test\n(changed services only)"]
C -->|"Python files"| D2["Pyright, Observatory test suites"]
C -->|"Frontend files"| D3["Biome lint, tsc --noEmit"]
C -->|"Docs / assets / app.db only"| D4["Fast path, no checks"]
C -->|"Hooks, scripts, workflows, Makefile"| D5["All fast checks"]
P["git push"] --> Q["pre-push: commits being pushed"]
Q --> R["Re-run pre-commit checks for that range"]
R --> S{"Changed areas"}
S -->|"Go code"| T1["CGO_ENABLED=0 go build ./..."]
S -->|"Frontend"| T2["pnpm run build"]
S -->|"Dockerfile / .dockerignore / compose"| T3["docker buildx build (cache only)"]
2. Why Native Tracked Git Hooks (.githooks/)?
Rather than imposing heavyweight JavaScript wrappers (Husky) or third-party binary managers (Lefthook) on a polyglot codebase, the repository uses tracked native Git hooks located in .githooks/:
- Zero External Dependencies: Reuses the repository's native toolchains (
go,uv,pnpm,docker,bash). - Cross-Platform Compatibility: Portable bash that also runs on the bash 3.2 macOS ships (no associative arrays,
mapfileor${var,,}), as well as Linux, Windows Git Bash and WSL.tests/githooks_test.shexercises both hooks with stub tools. - Version Controlled: The hooks are tracked in Git, so all contributors share identical validation rules.
- Fail-Fast & Dependency-Ordered: Validations run in order of speed (Formatting, Static Analysis, Tests, then Builds in pre-push).
3. Validation Matrix
Pre-commit (fast checks)
| Subsystem | Stage | Validation Command | Remediation Command |
|---|---|---|---|
| All | Secret scan | Staged .env, key files and token patterns | git restore --staged <file> |
| Go | Formatting | gofmt -l <staged_files> | make format or gofmt -w <file> |
| Go | Static Analysis | go vet <changed service packages> | Fix the reported issues |
| Go | Unit Tests | go test <changed service packages> | make test-go |
| Python | Static Typecheck | cd src/services/github-backup-observatory && uv run --with pyright pyright | make typecheck |
| Python | Test Suites | cd src/services/github-backup-observatory && uv run pytest | make test-py / make test-agents |
| Frontend | Lint & Format | cd src/apps/github-backup-dashboard && pnpm run lint (biome check) | make format / pnpm run format |
| Frontend | Type Check | cd src/apps/github-backup-dashboard && pnpm exec tsc --noEmit | Fix the reported type errors |
| Frontend | Unit Tests | cd src/apps/github-backup-dashboard && pnpm test (Vitest) | make test-dashboard |
Go checks are scoped to the service that changed (./src/backend/github-backup-api/..., ./src/backend/github-backup-mcp/... plus the Vercel entry ./api/..., or ./src/services/github-backup-worker/...). Changes to go.mod, go.sum or shared Go code check ./....
Pre-push (builds)
| Trigger | Build Command |
|---|---|
Go code, go.mod or go.sum changed | CGO_ENABLED=0 go build ./... |
| Dashboard files changed | cd src/apps/github-backup-dashboard && pnpm run build |
A service Dockerfile changed | docker buildx build --output type=cacheonly -f <Dockerfile> . for that image |
.dockerignore or docker-compose.yml changed | The same, for every image |
Hooks, scripts or Makefile changed | Go and Next.js builds |
Docker builds are skipped with a warning when Docker or buildx is not available; CI builds and smoke-tests every image (make smoke).
4. Installation & Activation
To activate the hooks in your local repository clone:
# Recommended: Using Makefile
make hooks-install
# Or directly via installer script:
./scripts/install-hooks.sh
# Or manually configure Git:
git config core.hooksPath .githooks
chmod +x .githooks/*
5. Selective vs Full Validation
- Targeted Subsystem Execution (pre-commit):
- Staging only Go files runs gofmt, go vet and go test for the affected services.
- Staging only Python files runs Pyright and the Observatory test suites.
- Staging only Frontend files runs Biome and
tsc --noEmit; the Next.js build waits for pre-push.
- Documentation Fast Path:
- Staging only documentation files (
*.md,*.txt,*.png,.gitignore,*.env.example) or only*.dbsnapshots skips every check.
- Staging only documentation files (
- Full Monorepo Validation:
- Modifying global configuration (
Makefile,.github/,scripts/,.githooks/) or runningmake pre-committriggers every fast check.
- Modifying global configuration (
- Pushed-Range Validation (pre-push):
- The hook reads the refs git is pushing, re-runs the pre-commit checks for exactly those commits (
PRECOMMIT_RANGE=<base>..<head>), then builds the changed areas. A new branch is compared with where it forked frommain. Without push information (for examplemake pre-push) it checks and builds everything.
- The hook reads the refs git is pushing, re-runs the pre-commit checks for exactly those commits (
6. Developer CLI Commands
The Makefile provides unified developer shortcuts:
# Run every fast pre-commit check manually
make pre-commit
# Run the full pre-push gate (checks + Go, Next.js and Docker builds) without pushing
make pre-push
# Build and smoke-test the whole Docker Compose stack
make smoke
# Auto-format all Go and Frontend source code
make format
# Run Pyright (Python) and TypeScript compiler checks
make typecheck
# Run all linters (Biome, Go vet, Pyright)
make lint
# Run all unit and AI agent test suites
make test
7. Environment Variables & Bypass Overrides
In specific development scenarios (e.g. drafting intermediate commits or quick emergency docs), the hooks support explicit environment overrides:
- Bypass Test Suites (pre-commit, and the checks pre-push re-runs):
SKIP_TESTS=1 git commit -s -S -m "chore: quick update"
- Bypass Builds (pre-push; pre-commit no longer builds):
SKIP_BUILDS=1 git push
- Bypass Docker Image Builds Only (pre-push):
SKIP_DOCKER=1 git push
- Force Full Validation:
PRECOMMIT_ALL=1 git commit -s -S -m "feat: monorepo change"PREPUSH_ALL=1 git push
- Skip a Hook Entirely:
SKIP_HOOKS=1 git commit -s -S -m "wip: draft checkpoint" # or PRECOMMIT_BYPASS=1PREPUSH_BYPASS=1 git push
- Complete Git Bypass (Native Git):
git commit -s -S --no-verify -m "wip: draft checkpoint"
- Allow a Push From
main:ALLOW_MAIN_PUSH=1 git push. (The worker used to pushapp.dbtomain; its state now lives in PostgreSQL and nothing pushes tomainautomatically.)
8. Continuous Integration Alignment
The hooks mirror the jobs in .github/workflows/ci.yml: gofmt, go vet, race-enabled go test, static Go builds, Pyright and the Observatory suites, Biome, tsc and the Next.js build. CI additionally checks go mod tidy, builds every image and runs the compose smoke test, so a commit that passes both hooks locally should pass CI.