1
+# Local DevSecOps guardrail enforcement (pre-commit / pre-push).
2
+#
3
+# DevSecOps Guardrails epic (jmservera/SquadScope-Coordinator#33), issue #544.
4
+# Mirrors the CI gates so violations are caught before they reach a PR:
5
+# - ruff (lint + format) -> matches the Lint workflow
6
+# - checkov (IaC/Actions) -> matches the Checkov workflow
7
+# - pytest (unit tests) -> matches the CI test job
8
+# - docker build -> verifies a Containerfile/Dockerfile if present
9
+#
10
+# Fast checks (ruff) run on every commit. Slower checks (checkov, pytest,
11
+# docker build) run on push to keep the commit loop quick.
12
+#
13
+# Install (one-time):
14
+# pip install pre-commit
15
+# pre-commit install --hook-type pre-commit --hook-type pre-push
16
+#
17
+# Run on demand:
18
+# pre-commit run --all-files
19
+#
20
+# Tool versions are pinned to match CI (ruff 0.15.7, checkov 3.2.533). When you
21
+# bump a version in CI, bump the matching `rev`/dependency here too.
22
+#
23
+# Emergency bypass (hotfixes only):
24
+# git commit --no-verify
25
+# git push --no-verify
26
+# Bypassing skips LOCAL hooks only — the CI gates still run. Follow up by fixing
27
+# any skipped findings; never weaken a CI gate to land a change.
28
+
29
+default_install_hook_types: [pre-commit, pre-push]
30
+default_stages: [pre-commit]
31
+
32
+repos:
33
+ # ── Ruff: Python lint + format (matches CI `ruff check` / `ruff format --check`)
34
+ - repo: https://github.com/astral-sh/ruff-pre-commit
35
+ rev: v0.15.7
36
+ hooks:
37
+ - id: ruff
38
+ name: ruff (lint, autofix)
39
+ args: [--fix]
40
+ - id: ruff-format
41
+ name: ruff (format)
42
+
43
+ # ── Checkov: IaC / container / GitHub Actions misconfiguration scan (pre-push)
44
+ - repo: https://github.com/bridgecrewio/checkov
45
+ rev: "3.2.533"
46
+ hooks:
47
+ - id: checkov
48
+ name: checkov (IaC / Actions scan)
49
+ stages: [pre-push]
50
+ # Trigger on workflow / container changes; the hook always scans the
51
+ # whole repo (`checkov -d .`) to mirror CI rather than per-file.
52
+ files: ^(\.github/workflows/.*\.ya?ml|.*Dockerfile.*|.*Containerfile.*)$
53
+ pass_filenames: false
54
+ args:
55
+ - --framework
56
+ - github_actions
57
+ - dockerfile
58
+ - secrets
59
+ - --skip-path
60
+ - node_modules
61
+ - --skip-path
62
+ - .venv
63
+ - --skip-path
64
+ - public
65
+ - --skip-path
66
+ - resources
67
+ - --skip-path
68
+ - themes
69
+ - --compact
70
+ - --quiet
71
+
72
+ # ── Local hooks (use repo-installed tooling)
73
+ - repo: local
74
+ hooks:
75
+ # pytest: run the unit suite before pushing (matches the CI test job).
76
+ - id: pytest
77
+ name: pytest (unit tests)
78
+ entry: python3 -m pytest tests/ -q
79
+ language: system
80
+ stages: [pre-push]
81
+ pass_filenames: false
82
+ always_run: true
83
+
84
+ # docker build: verify a Containerfile/Dockerfile builds, when one exists.
85
+ # No-op today (the repo ships no container file); activates automatically
86
+ # once a Containerfile/Dockerfile is added.
87
+ - id: docker-build
88
+ name: docker build (Containerfile, if present)
89
+ entry: scripts/hooks/docker_build_check.sh
90
+ language: script
91
+ stages: [pre-push]
92
+ pass_filenames: false
93
+ always_run: true