DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Git Hooks with Claude Code: Build Quality Gates with Husky and Pre-commit

Every Claude Code session generates code that needs to pass quality checks before it reaches production. Combining Claude Code with git hooks creates automatic quality gates that run on every commit.


CLAUDE.md for Git Hook Standards

## Git Hooks Policy

### pre-commit (required checks)
- Lint errors → commit fails
- TypeScript build errors → commit fails
- console.log in production code → warning

### commit-msg (message convention)
- Conventional Commits format required: type(scope): description
- Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci
- Scope required

### pre-push
- Run full test suite
- Coverage below 70% → push fails

### Management: husky (.husky/ directory)
- Run `npm run prepare` to install hooks
Enter fullscreen mode Exit fullscreen mode

Generating the Husky Setup

Generate a git hooks setup using husky and lint-staged.

Requirements:
- pre-commit: ESLint (changed files only) + TypeScript type check
- commit-msg: Conventional Commits format validation
- pre-push: Run test suite (npm test)
- Node.js 20 + TypeScript 5 + ESLint 8

Files to generate:
- package.json scripts/devDependencies additions
- .husky/pre-commit
- .husky/commit-msg
- .husky/pre-push
- .lintstagedrc.json
Enter fullscreen mode Exit fullscreen mode

Generated pre-commit Hook

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "Running lint-staged..."
npx lint-staged

echo "TypeScript type check..."
npx tsc --noEmit --skipLibCheck

echo "pre-commit complete"
Enter fullscreen mode Exit fullscreen mode
// .lintstagedrc.json
{
  "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
  "*.{json,md,yml}": ["prettier --write"]
}
Enter fullscreen mode Exit fullscreen mode

Conventional Commits Enforcement

Generate a commit-msg hook that enforces Conventional Commits.

Requirements:
- Format: type(scope): description
- Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci
- Scope: lowercase alphanumeric only
- Description: max 50 characters
- BREAKING CHANGE support
- Clear error messages

Save to: .husky/commit-msg
Enter fullscreen mode Exit fullscreen mode

Generated hook:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf|ci)(\([a-z0-9-]+\))!?: .{1,50}$"

if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
  echo "❌ Commit message does not follow Conventional Commits."
  echo ""
  echo "Format: type(scope): description"
  echo "Example: feat(auth): add JWT refresh token"
  echo ""
  echo "Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci"
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Claude Code Hooks for Security Scanning

Claude Code's own hook system can scan files as they're written:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{"type": "command", "command": "python .claude/hooks/security_check.py"}]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode
# .claude/hooks/security_check.py
import json, re, sys

data = json.load(sys.stdin)
content = data.get("tool_input", {}).get("content", "") or ""
fp = data.get("tool_input", {}).get("file_path", "")

if not fp or not fp.endswith((".ts", ".js", ".py")):
    sys.exit(0)

PATTERNS = [
    (r'(?i)(password|passwd)\s*=\s*["'][^"']{8,}["']', "Hardcoded password"),
    (r'(?i)api[_-]?key\s*=\s*["'][a-zA-Z0-9]{20,}["']', "Hardcoded API key"),
    (r'(?i)secret\s*=\s*["'][^"']{10,}["']', "Hardcoded secret"),
]

for pattern, message in PATTERNS:
    if re.search(pattern, content):
        print(f"[SECURITY] {message} detected. Move to environment variables.", file=sys.stderr)
        sys.exit(2)

sys.exit(0)
Enter fullscreen mode Exit fullscreen mode

This runs before every file write — Claude Code is blocked from committing secrets automatically.


Coverage Gate on pre-push

Generate a pre-push hook that blocks pushes when test coverage is below 70%.

Requirements:
- Use vitest coverage reports
- Parse JSON format report
- Check statement coverage
- On failure, show coverage summary

Save to: .husky/pre-push
Enter fullscreen mode Exit fullscreen mode

Summary

Build quality gates with Claude Code and git hooks:

  1. CLAUDE.md — Define hook standards (managed by husky)
  2. pre-commit — Auto-run lint + type check on changed files
  3. commit-msg — Enforce Conventional Commits format
  4. pre-push — Coverage gate before remote pushes
  5. Claude Code Hooks — Security scan every file write

Security Pack (¥1,480) includes /security-check and git hook templates for automated quality enforcement.

👉 prompt-works.jp

Myouga (@myougatheaxo) — Security-focused Claude Code engineer.

Top comments (0)