# NOTE: golangci-lint-fast now includes test files (_test.go) to catch security # issues earlier. The fast config uses gosec with critical-only checks (G101, # G110, G305, G401, G501, G502, G503) for acceptable performance. # Last updated: 2026-02-02 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - id: end-of-file-fixer exclude: '^(frontend/(coverage|dist|node_modules|\.vite)/|.*\.tsbuildinfo$)' - id: trailing-whitespace exclude: '^(frontend/(coverage|dist|node_modules|\.vite)/|.*\.tsbuildinfo$)' - id: check-yaml - id: check-added-large-files args: ['--maxkb=2500'] - repo: https://github.com/shellcheck-py/shellcheck-py rev: v0.10.0.1 hooks: - id: shellcheck name: shellcheck exclude: '^(frontend/(coverage|dist|node_modules|\.vite)/|test-results|codeql-agent-results)/' args: ['--severity=error'] - repo: https://github.com/rhysd/actionlint rev: v1.7.10 hooks: - id: actionlint name: actionlint (GitHub Actions) files: '^\.github/workflows/.*\.ya?ml$' - repo: local hooks: - id: dockerfile-check name: dockerfile validation entry: tools/dockerfile_check.sh language: script files: "Dockerfile.*" pass_filenames: true - id: go-test-coverage name: Go Test Coverage (Manual) entry: scripts/go-test-coverage.sh language: script files: '\.go$' pass_filenames: false verbose: true stages: [manual] # Only runs when explicitly called - id: go-vet name: Go Vet entry: bash -c 'cd backend && go vet ./...' language: system files: '\.go$' pass_filenames: false - id: golangci-lint-fast name: golangci-lint (Fast Linters - BLOCKING) entry: scripts/pre-commit-hooks/golangci-lint-fast.sh language: script files: '\.go$' # Test files are now included to catch security issues (gosec critical checks) pass_filenames: false description: "Runs fast, essential linters (staticcheck, govet, errcheck, ineffassign, unused, gosec critical) - BLOCKS commits on failure" - id: check-version-match name: Check .version matches latest Git tag entry: bash -c 'scripts/check-version-match-tag.sh' language: system files: '\.version$' pass_filenames: false - id: check-lfs-large-files name: Prevent large files that are not tracked by LFS entry: bash scripts/pre-commit-hooks/check-lfs-for-large-files.sh language: system pass_filenames: false verbose: true always_run: true - id: block-codeql-db-commits name: Prevent committing CodeQL DB artifacts entry: bash scripts/pre-commit-hooks/block-codeql-db-commits.sh language: system pass_filenames: false verbose: true always_run: true - id: block-data-backups-commit name: Prevent committing data/backups files entry: bash scripts/pre-commit-hooks/block-data-backups-commit.sh language: system pass_filenames: false verbose: true always_run: true # === MANUAL/CI-ONLY HOOKS === # These are slow and should only run on-demand or in CI # Run manually with: pre-commit run golangci-lint-full --all-files - id: go-test-race name: Go Test Race (Manual) entry: bash -c 'cd backend && go test -race ./...' language: system files: '\.go$' pass_filenames: false stages: [manual] # Only runs when explicitly called - id: golangci-lint-full name: golangci-lint (Full - Manual) entry: scripts/pre-commit-hooks/golangci-lint-full.sh language: script files: '\.go$' pass_filenames: false stages: [manual] # Only runs when explicitly called - id: hadolint name: Hadolint Dockerfile Check (Manual) entry: bash -c 'docker run --rm -i hadolint/hadolint < Dockerfile' language: system files: 'Dockerfile' pass_filenames: false stages: [manual] # Only runs when explicitly called - id: frontend-type-check name: Frontend TypeScript Check entry: bash -c 'cd frontend && npm run type-check' language: system files: '^frontend/.*\.(ts|tsx)$' pass_filenames: false - id: frontend-lint name: Frontend Lint (Fix) entry: bash -c 'cd frontend && npm run lint -- --fix' language: system files: '^frontend/.*\.(ts|tsx|js|jsx)$' pass_filenames: false - id: frontend-test-coverage name: Frontend Test Coverage (Manual) entry: scripts/frontend-test-coverage.sh language: script files: '^frontend/.*\\.(ts|tsx|js|jsx)$' pass_filenames: false verbose: true stages: [manual] - id: security-scan name: Security Vulnerability Scan (Manual) entry: scripts/security-scan.sh language: script files: '(\.go$|go\.mod$|go\.sum$)' pass_filenames: false verbose: true stages: [manual] # Only runs when explicitly called - id: codeql-go-scan name: CodeQL Go Security Scan (Manual - Slow) entry: scripts/pre-commit-hooks/codeql-go-scan.sh language: script files: '\.go$' pass_filenames: false verbose: true stages: [manual] # Performance: 30-60s, only run on-demand - id: codeql-js-scan name: CodeQL JavaScript/TypeScript Security Scan (Manual - Slow) entry: scripts/pre-commit-hooks/codeql-js-scan.sh language: script files: '^frontend/.*\.(ts|tsx|js|jsx)$' pass_filenames: false verbose: true stages: [manual] # Performance: 30-60s, only run on-demand - id: codeql-check-findings name: Block HIGH/CRITICAL CodeQL Findings entry: scripts/pre-commit-hooks/codeql-check-findings.sh language: script pass_filenames: false verbose: true stages: [manual] # Only runs after CodeQL scans - id: gorm-security-scan name: GORM Security Scanner (Manual) entry: scripts/pre-commit-hooks/gorm-security-check.sh language: script files: '\.go$' pass_filenames: false stages: [manual] # Manual stage initially (soft launch) verbose: true description: "Detects GORM ID leaks and common GORM security mistakes" - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.47.0 hooks: - id: markdownlint args: ["--fix"] exclude: '^(node_modules|\.venv|test-results|codeql-db|codeql-agent-results)/' stages: [manual]