mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 08:57:12 +00:00
140 lines
5.5 KiB
Bash
Executable file
140 lines
5.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
# Pre-commit hook to prevent committing restricted or sensitive data
|
|
RESTRICTED_FILES="active_subs.json charges.json customers.json subscriptions.json"
|
|
|
|
echo "Running sensitivity check..."
|
|
|
|
for file in $RESTRICTED_FILES; do
|
|
if git diff --cached --name-only | grep -q "^${file}$"; then
|
|
echo "BLOCKED: restricted file pattern matched: ${file}"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Block sensitive file types from ever being committed
|
|
SENSITIVE_EXTENSIONS="\.pem$|\.p12$|\.pfx$|\.key$|\.keystore$|\.jks$|\.enc$|id_rsa$|id_ed25519$|id_ecdsa$"
|
|
if git diff --cached --name-only | grep -qE "$SENSITIVE_EXTENSIONS"; then
|
|
echo "BLOCKED: sensitive file type staged for commit:"
|
|
git diff --cached --name-only | grep -E "$SENSITIVE_EXTENSIONS"
|
|
echo "If this is intentional (e.g. a template), use: git commit --no-verify"
|
|
exit 1
|
|
fi
|
|
|
|
# Gitleaks: comprehensive secret scanning (gracefully skips if not installed)
|
|
if command -v gitleaks >/dev/null 2>&1; then
|
|
echo "Running gitleaks secret scan..."
|
|
if ! gitleaks protect --staged --config .gitleaks.toml --no-banner 2>/dev/null; then
|
|
echo "BLOCKED: gitleaks detected secrets in staged changes."
|
|
echo "Run 'gitleaks protect --staged --verbose' for details."
|
|
exit 1
|
|
fi
|
|
echo "Gitleaks scan passed."
|
|
else
|
|
# Fallback: broader pattern check when gitleaks is not installed
|
|
# Covers Stripe, AWS, GCP, OpenAI, private keys, and generic high-entropy tokens
|
|
STAGED_DIFF=$(git diff --cached | grep -E "^\+" | grep -v ".husky/pre-commit" | grep -v "_test\.go")
|
|
|
|
if echo "$STAGED_DIFF" | grep -qE "(cus_|sub_|ch_|pi_|pm_|sk_live_|sk_test_|rk_live_|rk_test_|whsec_)"; then
|
|
echo "WARNING: Potential Stripe identifiers found in staged changes."
|
|
echo " Use 'git diff --cached' to review before proceeding."
|
|
if [ -t 0 ]; then
|
|
printf " Proceed anyway? (y/N): "
|
|
read REPLY < /dev/tty
|
|
echo
|
|
if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then
|
|
exit 1
|
|
fi
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if echo "$STAGED_DIFF" | grep -qE "(AKIA[0-9A-Z]{16}|-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----|sk-[a-zA-Z0-9]{20,}|AIza[0-9A-Za-z_-]{35})"; then
|
|
echo "BLOCKED: Likely secret detected in staged changes (AWS key, private key, or API key)."
|
|
echo " Use 'git diff --cached' to review."
|
|
echo " Install gitleaks for more precise scanning: brew install gitleaks"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo "Sensitivity check passed."
|
|
|
|
# Governance checks — only run when governance files are present (skipped on fresh clones).
|
|
# Governance files live in docs/release-control/v6/internal/ which is not tracked in the
|
|
# public repo; contributors without that directory get standard linting only.
|
|
if [ -f "docs/release-control/v6/internal/status.json" ]; then
|
|
|
|
echo "Running governance stage guard..."
|
|
python3 scripts/release_control/governance_stage_guard.py
|
|
|
|
echo "Running staged commit shape guard..."
|
|
python3 scripts/release_control/staged_commit_shape_guard.py
|
|
|
|
echo "Running control plane audit..."
|
|
python3 scripts/release_control/control_plane_audit.py --check --staged
|
|
|
|
echo "Running canonical completion guard..."
|
|
python3 scripts/release_control/canonical_completion_guard.py
|
|
|
|
echo "Running status audit..."
|
|
python3 scripts/release_control/status_audit.py --check --staged
|
|
|
|
echo "Running registry audit..."
|
|
python3 scripts/release_control/registry_audit.py --check --staged
|
|
|
|
echo "Running contract audit..."
|
|
python3 scripts/release_control/contract_audit.py --check --staged
|
|
|
|
echo "Running governance guardrail tests..."
|
|
export PULSE_READ_STAGED_GOVERNANCE=1
|
|
go test ./internal/repoctl -count=1
|
|
|
|
echo "Running readiness assertion guard..."
|
|
python3 scripts/release_control/readiness_assertion_guard.py --staged --active-target --proof-type automated
|
|
|
|
echo "Running release-control helper unit tests..."
|
|
python3 scripts/release_control/canonical_completion_guard_test.py
|
|
python3 scripts/release_control/control_plane_audit_test.py
|
|
python3 scripts/release_control/contract_audit_test.py
|
|
python3 scripts/release_control/format_staged_go_test.py
|
|
python3 scripts/release_control/governance_stage_guard_test.py
|
|
python3 scripts/release_control/release_promotion_policy_support_test.py
|
|
python3 scripts/release_control/registry_audit_test.py
|
|
python3 scripts/release_control/readiness_assertion_guard_test.py
|
|
(cd scripts/release_control && git -C ../.. show :scripts/release_control/release_promotion_policy_test.py | python3 -)
|
|
python3 scripts/release_control/repo_file_io_test.py
|
|
python3 scripts/release_control/staged_commit_shape_guard_test.py
|
|
python3 scripts/release_control/status_audit_test.py
|
|
python3 scripts/release_control/subsystem_contracts_test.py
|
|
python3 scripts/release_control/subsystem_lookup_test.py
|
|
unset PULSE_READ_STAGED_GOVERNANCE
|
|
|
|
else
|
|
echo "Governance files not present — skipping governance checks."
|
|
fi
|
|
|
|
|
|
# Run Go formatting
|
|
python3 scripts/release_control/format_staged_go.py
|
|
|
|
# Run Go linting (if golangci-lint is available)
|
|
if command -v golangci-lint >/dev/null 2>&1; then
|
|
echo "Running golangci-lint..."
|
|
golangci-lint run ./...
|
|
fi
|
|
|
|
# Run frontend linting (if package.json has lint script)
|
|
if [ -f frontend-modern/package.json ]; then
|
|
if git diff --cached --name-only | grep -q "^frontend-modern/"; then
|
|
echo "Running frontend linter..."
|
|
cd frontend-modern
|
|
npm run lint
|
|
cd ..
|
|
else
|
|
echo "Skipping frontend lint (no staged frontend changes)."
|
|
fi
|
|
fi
|
|
|
|
echo "Pre-commit checks passed!"
|