Git Hooks & Code Quality
Complete guide to git hooks, code quality enforcement, and pre-commit checks in the MyNATCA platform.
Overview
The MyNATCA platform uses git hooks to:
- Enforce branch protection - Prevent direct commits to main/staging
- Maintain code quality - Run basic checks on every commit
- Synchronize migrations - Update symlinks automatically
- Ensure consistency - Trim whitespace, validate syntax
Git Hooks Installation
One-Time Setup
Install git hooks in each repository you work on:
# Platform repository (required)
cd ~/dev/mynatca/platform
./scripts/setup-git-hooks.sh
# Pay repository (if working on PayChecker)
cd ~/dev/mynatca/pay
./scripts/setup-git-hooks.sh
# Discord repository (if working on Discord bot)
cd ~/dev/mynatca/discord
./scripts/setup-git-hooks.shWhat Gets Installed
Platform repository:
pre-commit- Branch protection + quality checkspost-checkout- Update migration symlinkspost-merge- Update migration symlinks after pulls
Subproject repositories (Pay, Discord):
pre-commit- Branch protection + quality checkspost-checkout- Trigger platform symlink updatepost-merge- Trigger platform symlink update
Verification
# Check hooks are installed
ls -la .git/hooks/
# Should see:
# pre-commit (executable)
# post-checkout (executable)
# post-merge (executable)
# Test pre-commit hook
git checkout main
git commit --allow-empty -m "test"
# Should be blocked with error messagePre-Commit Hooks
Branch Protection
Prevents direct commits to protected branches:
main- Production branchstaging- Pre-production branch
Error message:
❌ Direct commits to main/staging are not allowed!
Please use the Pull Request workflow:
1. Create a feature branch:
git checkout -b feature/my-feature
2. Make your changes and commit:
git add .
git commit -m "Your changes"
3. Push and create a Pull Request:
git push origin feature/my-feature
To bypass this check (not recommended):
git commit --no-verifyOverride (emergency only):
git commit --no-verify -m "Emergency hotfix"Quality Checks
Automatically run on every commit:
- Trailing whitespace - Remove trailing spaces
- End of file - Ensure files end with newline
- YAML validation - Check YAML syntax
- JSON validation - Check JSON syntax
- Merge conflict markers - Detect unresolved conflicts
Implementation:
Uses pre-commit framework (opens in a new tab) with configuration in .pre-commit-config.yaml.
Configuration
.pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: branch-protection
name: Branch Protection
entry: scripts/hooks/check-branch.sh
language: script
stages: [commit]
always_run: true
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
name: Trim trailing whitespace
- id: end-of-file-fixer
name: Fix end of files
- id: check-yaml
name: Validate YAML
- id: check-json
name: Validate JSON
- id: check-merge-conflict
name: Check for merge conflictsPost-Checkout Hooks
Purpose
Automatically update migration symlinks when switching branches.
Behavior
When you run:
git checkout feature/my-branchHook automatically runs:
./scripts/link-migrations.shResult:
- Symlinks in
platform/supabase/migrations/updated - Point to correct branch versions of pay/discord migrations
- No manual intervention needed
Example
# Start on main branch
git checkout main
# Hook runs: symlinks point to pay main, discord main
# Switch to feature branch
git checkout feature/new-feature
# Hook runs: symlinks point to pay feature, discord main (whatever branches they're on)
# Symlinks always reflect current branch statePost-Merge Hooks
Purpose
Automatically update migration symlinks after pulling changes.
Behavior
When you run:
git pull origin mainHook automatically runs:
./scripts/link-migrations.shResult:
- Symlinks updated to reflect merged changes
- New migrations from pay/discord are automatically linked
- Database stays synchronized
Code Quality Tools
Prettier (Code Formatter)
Purpose: Enforce consistent code formatting
Configuration: .prettierrc.json
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"endOfLine": "lf"
}Ignored files: .prettierignore
node_modules/
.next/
dist/
build/
coverage/
supabase/functionsManual usage:
# Check formatting
npx prettier --check "**/*.{js,mjs,json,md,yaml,yml}"
# Fix formatting
npx prettier --write "**/*.{js,mjs,json,md,yaml,yml}"Automatic usage:
Runs automatically when you use npm run bump:* commands.
ESLint (Code Linter)
Purpose: Enforce code quality and catch errors
Configuration: .eslintrc.json
{
"extends": ["eslint:recommended", "next"],
"env": {
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"rules": {
"no-console": "warn",
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"prefer-const": "error"
}
}Manual usage:
# Check for issues
npx eslint "**/*.{js,mjs}"
# Fix auto-fixable issues
npx eslint --fix "**/*.{js,mjs}"Automatic usage:
Runs automatically when you use npm run bump:* commands.
TypeScript Check
Purpose: Validate TypeScript types (if using TypeScript)
Configuration: tsconfig.json
Manual usage:
# Check types
npm run type-check
# Or directly
npx tsc --noEmitAutomatic usage:
Runs automatically when you use npm run bump:* commands (if tsconfig.json exists).
Deployment Preparation Workflow
Full Quality Check + Version Bump
# Run all quality checks + bump version
npm run bump:patch # or minor/majorWhat runs:
Step 1: Prettier ✓
- Auto-formats all code
- Fixes formatting issues
- Updates .js, .mjs, .json, .md, .yaml, .yml files
Step 2: ESLint ✓
- Lints code
- Auto-fixes fixable issues
- Reports unfixable issues (fails if any)
Step 3: TypeScript ✓
- Checks types (if TypeScript project)
- Reports type errors (fails if any)
Step 4: Version Bump ✓
- Updates VERSION file
- Updates package.json
- Shows next steps
If any step fails: Process stops, version is not bumped
Why Quality Checks Don't Run on Every Commit
Design decision:
- Pre-commit hooks run basic checks (whitespace, syntax)
- Full quality checks (Prettier, ESLint, TypeScript) run during deployment prep
- Faster commits during development
- Comprehensive checks before PR/deployment
Rationale:
- Developers iterate quickly during feature development
- Full quality checks can be slow
- Quality enforced at deployment time (when it matters)
- Can always run manually:
npx prettier --write .
Bypassing Hooks
When to Bypass
Legitimate use cases:
- Emergency hotfixes to production
- Automated commits (CI/CD)
- Revert commits
- Temporary WIP commits (that will be squashed)
NOT legitimate:
- Avoiding fixing quality issues
- Skipping branch protection for convenience
- Committing to main/staging to "save time"
How to Bypass
# Skip all git hooks
git commit --no-verify -m "Emergency fix"
# Or set environment variable
SKIP=1 git commit -m "Emergency fix"
# Only for pre-commit framework checks
SKIP=trailing-whitespace,check-yaml git commit -m "WIP"Warning: Use sparingly and only when necessary.
Hook Maintenance
Updating Hooks
# Re-run setup script
cd ~/dev/mynatca/platform
./scripts/setup-git-hooks.sh
# Updates all hooks to latest versionDisabling Hooks
Temporarily:
# Bypass for single commit
git commit --no-verify
# Disable pre-commit framework
rm .git/hooks/pre-commit
# Re-enable
./scripts/setup-git-hooks.shPermanently (not recommended):
# Remove all hooks
rm .git/hooks/*Custom Hooks
Add custom hook:
- Edit
.pre-commit-config.yaml - Add new hook configuration
- Update hooks:
pre-commit install
Example: Add custom script
- repo: local
hooks:
- id: my-custom-check
name: My Custom Check
entry: scripts/hooks/my-check.sh
language: script
stages: [commit]Troubleshooting
Hooks Not Running
Issue: Git hooks don't execute
Solution:
# Reinstall hooks
./scripts/setup-git-hooks.sh
# Check hooks are executable
ls -la .git/hooks/
# If not executable
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/post-checkout
chmod +x .git/hooks/post-mergePre-Commit Framework Not Found
Issue: pre-commit: command not found
Solution:
# Install pre-commit framework
pip install pre-commit
# Or via Homebrew
brew install pre-commit
# Install hooks
pre-commit installHook Fails with Error
Issue: Hook script has syntax error or fails
Solution:
# Check hook script
cat .git/hooks/pre-commit
# Test hook manually
.git/hooks/pre-commit
# See detailed error
bash -x .git/hooks/pre-commitCan't Commit on Main/Staging
Issue: Legitimate need to commit to main/staging
Solution:
# Option 1: Use feature branch (recommended)
git checkout -b feature/my-fix
git commit -m "My fix"
# Then create PR
# Option 2: Bypass hook (emergency only)
git commit --no-verify -m "Emergency hotfix"Symlinks Not Updating
Issue: Migration symlinks don't update after checkout
Solution:
# Manually run link script
./scripts/link-migrations.sh
# Verify post-checkout hook exists
ls -la .git/hooks/post-checkout
# Reinstall hooks
./scripts/setup-git-hooks.shQuality Checks Fail
Issue: npm run bump fails with lint errors
Solution:
# Fix Prettier issues
npx prettier --write "**/*.{js,mjs,json,md,yaml,yml}"
# Fix ESLint issues
npx eslint --fix "**/*.{js,mjs}"
# Fix remaining ESLint issues manually
npx eslint "**/*.{js,mjs}"
# Edit files to fix reported issues
# Fix TypeScript issues
npm run type-check
# Edit files to fix type errors
# Try bump again
npm run bump:patchBest Practices
DO ✅
- Install git hooks in all repos you work on
- Run
npm run bump:*before creating PRs - Fix quality issues promptly
- Use feature branches for all work
- Test hooks after installation
- Update hooks when scripts change
- Follow branch protection rules
- Keep hooks executable
DON'T ❌
- Skip hook installation
- Regularly bypass hooks with
--no-verify - Commit directly to main/staging
- Ignore quality check failures
- Modify
.git/hooks/files directly (use setup script) - Disable hooks permanently
- Commit without testing
- Force push to protected branches
Quick Reference
Commands
# Installation
./scripts/setup-git-hooks.sh # Install all hooks
# Quality checks (manual)
npx prettier --write "**/*.{js,mjs,json,md,yaml,yml}"
npx eslint --fix "**/*.{js,mjs}"
npm run type-check
# Quality checks (automatic)
npm run bump:patch # All checks + version bump
npm run bump:minor
npm run bump:major
# Bypass hooks
git commit --no-verify # Skip all hooks
SKIP=1 git commit -m "message" # Skip pre-commit framework
# Hook management
ls -la .git/hooks/ # List installed hooks
chmod +x .git/hooks/* # Make hooks executable
rm .git/hooks/hook-name # Remove specific hookFiles
Configuration:
.pre-commit-config.yaml- Pre-commit framework configuration.prettierrc.json- Prettier configuration.prettierignore- Prettier ignore patterns.eslintrc.json- ESLint configurationtsconfig.json- TypeScript configuration
Scripts:
scripts/setup-git-hooks.sh- Hook installation scriptscripts/hooks/check-branch.sh- Branch protection scriptscripts/link-migrations.sh- Migration symlink scriptscripts/prepare-deployment.sh- Full deployment prepscripts/bump-version.js- Version bump script
Hooks:
.git/hooks/pre-commit- Before commit.git/hooks/post-checkout- After checkout.git/hooks/post-merge- After merge/pull
Related Documentation
- Code Promotion Workflow - Deployment process
- Version Management - Version control
- Contributing Guidelines - Code standards
- Local Development Setup - Environment setup
- Platform Scripts Reference (opens in a new tab) - Hook details