⚙️ Automation
Git Hooks Configuration
Set up Git hooks for automated code quality checks and workflow enforcement
★★★ Advanced 25 min January 13, 2025
Use Case
Git hooks automate quality checks before commits and pushes. Cowork can generate customized hooks for linting, testing, commit message validation, and more.
Example Prompt
I want to set up Git hooks for my JavaScript project at ~/Projects/myapp/. Please create:
1. pre-commit hook:
- Run ESLint on staged files
- Run Prettier formatting check
- Prevent commits with console.log
2. commit-msg hook:
- Enforce conventional commit format
- Require ticket reference (PROJ-XXX)
3. pre-push hook:
- Run full test suite
- Check for TODO/FIXME comments
- Prevent push to main without PR
Save hooks to .git/hooks/ and make them executable
What Cowork Does
- Hook Generation: Creates shell scripts for each hook type
- Tool Integration: Integrates with ESLint, Prettier, Jest
- Pattern Matching: Sets up regex for commit validation
- Permission Setup: Makes hooks executable
- Documentation: Adds usage instructions
Sample Output
#!/bin/sh
# .git/hooks/pre-commit
echo "🔍 Running pre-commit checks..."
# Get staged files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|jsx|tsx)$')
if [ -z "$STAGED_FILES" ]; then
echo "No JS/TS files to check"
exit 0
fi
# Check for console.log
echo "Checking for console.log statements..."
if grep -n "console\.log" $STAGED_FILES; then
echo "❌ Error: console.log found in staged files"
echo "Remove or replace with proper logging"
exit 1
fi
# Run ESLint
echo "Running ESLint..."
npx eslint $STAGED_FILES
if [ $? -ne 0 ]; then
echo "❌ ESLint failed"
exit 1
fi
# Run Prettier check
echo "Checking formatting..."
npx prettier --check $STAGED_FILES
if [ $? -ne 0 ]; then
echo "❌ Formatting issues found"
echo "Run: npx prettier --write <files>"
exit 1
fi
echo "✅ Pre-commit checks passed!"
exit 0
#!/bin/sh
# .git/hooks/commit-msg
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# Conventional commit pattern
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\([a-z-]+\))?: .+"
# Ticket reference pattern
TICKET_PATTERN="PROJ-[0-9]+"
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "❌ Invalid commit message format"
echo ""
echo "Expected format: type(scope): description"
echo "Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert"
echo ""
echo "Example: feat(auth): add OAuth2 support PROJ-123"
exit 1
fi
if ! echo "$COMMIT_MSG" | grep -qE "$TICKET_PATTERN"; then
echo "❌ Missing ticket reference (PROJ-XXX)"
exit 1
fi
echo "✅ Commit message validated"
exit 0
#!/bin/sh
# .git/hooks/pre-push
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Prevent direct push to main
if [ "$BRANCH" = "main" ]; then
echo "❌ Cannot push directly to main"
echo "Create a PR instead"
exit 1
fi
# Run tests
echo "🧪 Running tests..."
npm test
if [ $? -ne 0 ]; then
echo "❌ Tests failed"
exit 1
fi
# Check for TODO/FIXME
echo "Checking for TODO/FIXME..."
if git diff origin/main...HEAD | grep -E "TODO|FIXME"; then
echo "⚠️ Warning: TODO/FIXME comments found"
read -p "Continue anyway? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
echo "✅ Pre-push checks passed!"
exit 0
Tips
- Use husky or lefthook for easier hook management
- Include bypass instructions for emergencies
- Keep hooks fast to avoid frustration
- Consider team-wide hook sharing via npm