Skip to main content

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-commit runs fast checks only: secret scan, formatting and lint, static analysis, and the unit tests of the areas that changed.
  • .githooks/pre-push re-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:

  1. 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.
  2. AI Observatory Service: FastAPI + LangChain Tool-Calling RAG application managed with uv under src/services/github-backup-observatory/.
  3. 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, mapfile or ${var,,}), as well as Linux, Windows Git Bash and WSL. tests/githooks_test.sh exercises 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)​

SubsystemStageValidation CommandRemediation Command
AllSecret scanStaged .env, key files and token patternsgit restore --staged <file>
GoFormattinggofmt -l <staged_files>make format or gofmt -w <file>
GoStatic Analysisgo vet <changed service packages>Fix the reported issues
GoUnit Testsgo test <changed service packages>make test-go
PythonStatic Typecheckcd src/services/github-backup-observatory && uv run --with pyright pyrightmake typecheck
PythonTest Suitescd src/services/github-backup-observatory && uv run pytestmake test-py / make test-agents
FrontendLint & Formatcd src/apps/github-backup-dashboard && pnpm run lint (biome check)make format / pnpm run format
FrontendType Checkcd src/apps/github-backup-dashboard && pnpm exec tsc --noEmitFix the reported type errors
FrontendUnit Testscd 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)​

TriggerBuild Command
Go code, go.mod or go.sum changedCGO_ENABLED=0 go build ./...
Dashboard files changedcd src/apps/github-backup-dashboard && pnpm run build
A service Dockerfile changeddocker buildx build --output type=cacheonly -f <Dockerfile> . for that image
.dockerignore or docker-compose.yml changedThe same, for every image
Hooks, scripts or Makefile changedGo 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​

  1. 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.
  2. Documentation Fast Path:
    • Staging only documentation files (*.md, *.txt, *.png, .gitignore, *.env.example) or only *.db snapshots skips every check.
  3. Full Monorepo Validation:
    • Modifying global configuration (Makefile, .github/, scripts/, .githooks/) or running make pre-commit triggers every fast check.
  4. 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 from main. Without push information (for example make pre-push) it checks and builds everything.

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=1
    PREPUSH_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 push app.db to main; its state now lives in PostgreSQL and nothing pushes to main automatically.)

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.