From f092a8d53858707c4b23f1fc2cd2c9b7f8137915 Mon Sep 17 00:00:00 2001 From: maebeale Date: Sun, 22 Mar 2026 11:09:57 -0400 Subject: [PATCH 1/3] Add pre-commit hook for rubocop, brakeman, and safety checks Runs on every commit: - rubocop on staged .rb files only - brakeman security scan - checks for debug statements (binding.pry, byebug, etc.) - checks for merge conflict markers - blocks committing .env/secrets files Hook is auto-installed via bin/setup. Co-Authored-By: Claude Opus 4.6 --- bin/pre-commit | 38 ++++++++++++++++++++++++++++++++++++++ bin/setup | 3 +++ 2 files changed, 41 insertions(+) create mode 100755 bin/pre-commit diff --git a/bin/pre-commit b/bin/pre-commit new file mode 100755 index 000000000..25793c73a --- /dev/null +++ b/bin/pre-commit @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +staged_files=$(git diff --cached --name-only --diff-filter=d) +staged_rb_files=$(echo "$staged_files" | grep '\.rb$' || true) + +# Run rubocop on staged .rb files only +if [ -n "$staged_rb_files" ]; then + echo "Running rubocop on staged Ruby files..." + bundle exec rubocop --force-exclusion $staged_rb_files || exit 1 +fi + +# Run brakeman security scan +echo "Running brakeman security scan..." +bundle exec brakeman --no-pager -q || exit 1 + +# Check for debug statements +if [ -n "$staged_rb_files" ]; then + if echo "$staged_rb_files" | xargs grep -n 'binding\.pry\|binding\.irb\|byebug\|debugger' 2>/dev/null; then + echo "ERROR: Debug statements found in staged files. Remove them before committing." + exit 1 + fi +fi + +# Check for merge conflict markers +if [ -n "$staged_files" ]; then + if echo "$staged_files" | xargs grep -n '<<<<<<<\|>>>>>>>\|=======' 2>/dev/null; then + echo "ERROR: Merge conflict markers found in staged files. Resolve them before committing." + exit 1 + fi +fi + +# Check for secrets/env files +if echo "$staged_files" | grep -q '\.env$\|\.env\.\|credentials\.yml\.enc\|master\.key'; then + echo "ERROR: Potentially sensitive files staged for commit:" + echo "$staged_files" | grep '\.env$\|\.env\.\|credentials\.yml\.enc\|master\.key' + echo "Remove them from staging before committing." + exit 1 +fi diff --git a/bin/setup b/bin/setup index 5773cd675..c9ed0b2f9 100755 --- a/bin/setup +++ b/bin/setup @@ -70,6 +70,9 @@ FileUtils.chdir APP_ROOT do puts "\n== Building Vite test assets ==" system! "RAILS_ENV=test npx vite build --mode test" + puts "\n== Installing git hooks ==" + system! 'cp bin/pre-commit .git/hooks/pre-commit' + system! 'chmod +x .git/hooks/pre-commit' puts "\n== Cleaning logs and tempfiles ==" system! "bin/rails log:clear tmp:clear" From d231696c35f48dbd6e207249b929dc2fb7bdfad6 Mon Sep 17 00:00:00 2001 From: maebeale Date: Sat, 28 Mar 2026 08:42:12 -0400 Subject: [PATCH 2/3] Move rubocop and brakeman to pre-push hook for faster commits Pre-commit now only runs lightweight safety checks (debug statements, conflict markers, secrets). Heavier tools run before push instead. Also removes credentials.yml.enc from secrets blocklist since it's meant to be committed (it's encrypted). Co-Authored-By: Claude Opus 4.6 --- bin/pre-commit | 14 ++------------ bin/pre-push | 11 +++++++++++ bin/setup | 2 ++ 3 files changed, 15 insertions(+), 12 deletions(-) create mode 100755 bin/pre-push diff --git a/bin/pre-commit b/bin/pre-commit index 25793c73a..9d8662b9b 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -3,16 +3,6 @@ staged_files=$(git diff --cached --name-only --diff-filter=d) staged_rb_files=$(echo "$staged_files" | grep '\.rb$' || true) -# Run rubocop on staged .rb files only -if [ -n "$staged_rb_files" ]; then - echo "Running rubocop on staged Ruby files..." - bundle exec rubocop --force-exclusion $staged_rb_files || exit 1 -fi - -# Run brakeman security scan -echo "Running brakeman security scan..." -bundle exec brakeman --no-pager -q || exit 1 - # Check for debug statements if [ -n "$staged_rb_files" ]; then if echo "$staged_rb_files" | xargs grep -n 'binding\.pry\|binding\.irb\|byebug\|debugger' 2>/dev/null; then @@ -30,9 +20,9 @@ if [ -n "$staged_files" ]; then fi # Check for secrets/env files -if echo "$staged_files" | grep -q '\.env$\|\.env\.\|credentials\.yml\.enc\|master\.key'; then +if echo "$staged_files" | grep -q '\.env$\|\.env\.\|master\.key'; then echo "ERROR: Potentially sensitive files staged for commit:" - echo "$staged_files" | grep '\.env$\|\.env\.\|credentials\.yml\.enc\|master\.key' + echo "$staged_files" | grep '\.env$\|\.env\.\|master\.key' echo "Remove them from staging before committing." exit 1 fi diff --git a/bin/pre-push b/bin/pre-push new file mode 100755 index 000000000..efed4868d --- /dev/null +++ b/bin/pre-push @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +eval "$(command /opt/homebrew/bin/mise activate zsh)" + +# Run rubocop on all Ruby files +echo "Running rubocop..." +bundle exec rubocop || exit 1 + +# Run brakeman security scan +echo "Running brakeman security scan..." +bundle exec brakeman --no-pager -q || exit 1 diff --git a/bin/setup b/bin/setup index c9ed0b2f9..5cf27e56c 100755 --- a/bin/setup +++ b/bin/setup @@ -73,6 +73,8 @@ FileUtils.chdir APP_ROOT do puts "\n== Installing git hooks ==" system! 'cp bin/pre-commit .git/hooks/pre-commit' system! 'chmod +x .git/hooks/pre-commit' + system! 'cp bin/pre-push .git/hooks/pre-push' + system! 'chmod +x .git/hooks/pre-push' puts "\n== Cleaning logs and tempfiles ==" system! "bin/rails log:clear tmp:clear" From 737223babed58dc9ec370378a2594f121263b54e Mon Sep 17 00:00:00 2001 From: maebeale Date: Sat, 28 Mar 2026 08:42:57 -0400 Subject: [PATCH 3/3] Allow .env.example through pre-commit secrets check Co-Authored-By: Claude Opus 4.6 --- bin/pre-commit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/pre-commit b/bin/pre-commit index 9d8662b9b..d25aaa059 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -19,10 +19,10 @@ if [ -n "$staged_files" ]; then fi fi -# Check for secrets/env files -if echo "$staged_files" | grep -q '\.env$\|\.env\.\|master\.key'; then +# Check for secrets/env files (allow .env.example) +if echo "$staged_files" | grep '\.env$\|\.env\.\|master\.key' | grep -qv '\.env\.example$'; then echo "ERROR: Potentially sensitive files staged for commit:" - echo "$staged_files" | grep '\.env$\|\.env\.\|master\.key' + echo "$staged_files" | grep '\.env$\|\.env\.\|master\.key' | grep -v '\.env\.example$' echo "Remove them from staging before committing." exit 1 fi