-
-
Notifications
You must be signed in to change notification settings - Fork 637
Add smart pre-commit hooks to prevent CI failures #1792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# .lefthook.yml | ||
# Fast pre-commit hooks that check all changed files (staged + unstaged + untracked) | ||
# Install with: bundle exec lefthook install | ||
|
||
pre-commit: | ||
parallel: true | ||
commands: | ||
autofix: | ||
run: bin/lefthook/ruby-autofix all-changed | ||
|
||
rubocop: | ||
run: bin/lefthook/ruby-lint all-changed | ||
|
||
prettier: | ||
run: bin/lefthook/prettier-format all-changed | ||
|
||
trailing-newlines: | ||
run: bin/lefthook/check-trailing-newlines all-changed | ||
|
||
pre-push: | ||
commands: | ||
branch-lint: | ||
run: bin/lefthook/ruby-lint branch |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,6 +7,10 @@ | |||||||||||||||||||||||||||||||||||||||||
## Prerequisites | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
- [Yalc](https://github.com/whitecolor/yalc) must be installed globally for most local development. | ||||||||||||||||||||||||||||||||||||||||||
- **Git hooks setup** (automatic during normal setup): | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Git hooks are installed automatically when you run the standard setup commands. They will run automatic linting on **all changed files (staged + unstaged + untracked)** - making commits fast while preventing CI failures. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
- After updating code via Git, to prepare all examples: | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
```sh | ||||||||||||||||||||||||||||||||||||||||||
|
@@ -457,7 +461,9 @@ This approach: | |||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
## Pre-Commit Requirements | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**CRITICAL**: Before committing any changes, always run the following commands to ensure code quality: | ||||||||||||||||||||||||||||||||||||||||||
**AUTOMATED**: If you've set up Lefthook (see Prerequisites), linting runs automatically on changed files before each commit. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**MANUAL OPTION**: If you need to run linting manually: | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
```bash | ||||||||||||||||||||||||||||||||||||||||||
# Navigate to the main react_on_rails directory | ||||||||||||||||||||||||||||||||||||||||||
|
@@ -476,14 +482,14 @@ rake lint:rubocop | |||||||||||||||||||||||||||||||||||||||||
rake lint | ||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**Automated checks:** | ||||||||||||||||||||||||||||||||||||||||||
**Git hooks automatically run:** | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
- Format all JavaScript/TypeScript files with Prettier | ||||||||||||||||||||||||||||||||||||||||||
- Format JavaScript/TypeScript files with Prettier (on changed files only) | ||||||||||||||||||||||||||||||||||||||||||
- Check and fix linting issues with ESLint | ||||||||||||||||||||||||||||||||||||||||||
- Check and fix Ruby style issues with RuboCop | ||||||||||||||||||||||||||||||||||||||||||
- Ensure all tests pass before pushing | ||||||||||||||||||||||||||||||||||||||||||
- Check and fix Ruby style issues with RuboCop (on all changed files) | ||||||||||||||||||||||||||||||||||||||||||
- Ensure trailing newlines on all files | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**Tip**: Set up your IDE to run these automatically on save to catch issues early. | ||||||||||||||||||||||||||||||||||||||||||
**Setup**: Automatic during normal development setup | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+485
to
493
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Docs/impl mismatch: ESLint is not part of the configured hooks. Either add an ESLint hook or update docs to remove ESLint from “automatically run”. -**Git hooks automatically run:**
-
-- Format JavaScript/TypeScript files with Prettier (on changed files only)
-- Check and fix linting issues with ESLint
-- Check and fix Ruby style issues with RuboCop (on all changed files)
-- Ensure trailing newlines on all files
+**Git hooks automatically run:**
+
+- Format JavaScript/TypeScript files with Prettier (on changed files only)
+- Check Ruby style with RuboCop (on changed files)
+- Ensure trailing newlines on all files If you do want ESLint here, I can add an 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||
## 🤖 Best Practices for AI Coding Agents | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#!/usr/bin/env bash | ||
# Check for trailing newlines on all changed files | ||
set -euo pipefail | ||
|
||
CONTEXT="${1:-staged}" | ||
files="$(bin/lefthook/get-changed-files "$CONTEXT" '.*')" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid false positives on binaries; fix quoting and user hint. Current loop may flag images/binaries and breaks on spaces. Filter to text when possible, use arrays, and correct the quick-fix message. -CONTEXT="${1:-staged}"
-files="$(bin/lefthook/get-changed-files "$CONTEXT" '.*')"
+CONTEXT="${1:-staged}"
+mapfile -t files < <(bin/lefthook/get-changed-files "$CONTEXT" '.*')
@@
-if [ -z "$files" ]; then
+if [ "${#files[@]}" -eq 0 ]; then
echo "✅ No files to check for trailing newlines"
exit 0
fi
@@
-failed_files=""
-for file in $files; do
+failed_files=()
+for file in "${files[@]}"; do
if [ -f "$file" ] && [ -s "$file" ]; then
+ # Skip non-text files if `file` is available
+ if command -v file >/dev/null 2>&1; then
+ if ! file -bi "$file" | grep -qi '^text/'; then
+ continue
+ fi
+ fi
if ! tail -c 1 "$file" | grep -q '^$'; then
echo "❌ Missing trailing newline: $file"
- failed_files="$failed_files $file"
+ failed_files+=("$file")
fi
fi
done
@@
-if [ -n "$failed_files" ]; then
+if [ "${#failed_files[@]}" -gt 0 ]; then
echo ""
echo "❌ Trailing newline check failed!"
- echo "💡 Add trailing newlines to:$failed_files"
- echo "🔧 Quick fix: for file in$failed_files; do echo >> \"\$file\"; done"
+ echo "💡 Add trailing newlines to: ${failed_files[*]}"
+ echo "🔧 Quick fix: for file in ${failed_files[*]}; do printf '\n' >> \"\$file\"; done"
echo "🚫 Skip hook: git commit --no-verify"
exit 1
fi Also applies to: 19-27, 29-36 🤖 Prompt for AI Agents
|
||
|
||
if [ -z "$files" ]; then | ||
echo "✅ No files to check for trailing newlines" | ||
exit 0 | ||
fi | ||
|
||
if [ "$CONTEXT" = "all-changed" ]; then | ||
echo "🔍 Checking trailing newlines on all changed files..." | ||
else | ||
echo "🔍 Checking trailing newlines on $CONTEXT files..." | ||
fi | ||
|
||
failed_files="" | ||
for file in $files; do | ||
if [ -f "$file" ] && [ -s "$file" ]; then | ||
if ! tail -c 1 "$file" | grep -q '^$'; then | ||
echo "❌ Missing trailing newline: $file" | ||
failed_files="$failed_files $file" | ||
fi | ||
fi | ||
done | ||
|
||
if [ -n "$failed_files" ]; then | ||
echo "" | ||
echo "❌ Trailing newline check failed!" | ||
echo "💡 Add trailing newlines to:$failed_files" | ||
echo "🔧 Quick fix: for file in$failed_files; do echo >> \"\$file\"; done" | ||
echo "🚫 Skip hook: git commit --no-verify" | ||
exit 1 | ||
fi | ||
|
||
echo "✅ All files have proper trailing newlines" |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,26 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
#!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||
# Get changed files based on context (staged, branch, or all) | ||||||||||||||||||||||||||||||||||||||||||||||
set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
CONTEXT="${1:-staged}" | ||||||||||||||||||||||||||||||||||||||||||||||
PATTERN="${2:-.*}" | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
case "$CONTEXT" in | ||||||||||||||||||||||||||||||||||||||||||||||
staged) | ||||||||||||||||||||||||||||||||||||||||||||||
git diff --cached --name-only --diff-filter=ACM | grep -E "$PATTERN" || true | ||||||||||||||||||||||||||||||||||||||||||||||
;; | ||||||||||||||||||||||||||||||||||||||||||||||
all-changed) | ||||||||||||||||||||||||||||||||||||||||||||||
# Get all changed files (staged + unstaged + untracked) vs working directory | ||||||||||||||||||||||||||||||||||||||||||||||
(git diff --cached --name-only --diff-filter=ACM; git diff --name-only --diff-filter=ACM; git ls-files --others --exclude-standard) | sort -u | grep -E "$PATTERN" || true | ||||||||||||||||||||||||||||||||||||||||||||||
;; | ||||||||||||||||||||||||||||||||||||||||||||||
branch) | ||||||||||||||||||||||||||||||||||||||||||||||
# Find base branch (prefer main over master) | ||||||||||||||||||||||||||||||||||||||||||||||
base="origin/main" | ||||||||||||||||||||||||||||||||||||||||||||||
git rev-parse --verify --quiet "$base" >/dev/null || base="origin/master" | ||||||||||||||||||||||||||||||||||||||||||||||
git diff --name-only --diff-filter=ACM "$base"...HEAD | grep -E "$PATTERN" || true | ||||||||||||||||||||||||||||||||||||||||||||||
;; | ||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+17
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Harden base branch resolution for branch diffs. Handles repos without origin/main or origin/master; prefers origin’s default HEAD, then sensible fallbacks. - # Find base branch (prefer main over master)
- base="origin/main"
- git rev-parse --verify --quiet "$base" >/dev/null || base="origin/master"
- git diff --name-only --diff-filter=ACM "$base"...HEAD | grep -E "$PATTERN" || true
+ # Resolve base branch (prefer remote default, then origin/main, origin/master, main, master)
+ base=""
+ if git rev-parse --verify --quiet refs/remotes/origin/HEAD >/dev/null; then
+ base="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD)"
+ fi
+ for candidate in "$base" origin/main origin/master main master; do
+ if [ -n "$candidate" ] && git rev-parse --verify --quiet "$candidate" >/dev/null; then
+ base="$candidate"
+ break
+ fi
+ done
+ if [ -z "$base" ]; then
+ echo "⚠️ Could not resolve base branch; defaulting to HEAD~1" >&2
+ base="HEAD~1"
+ fi
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD | grep -E "$PATTERN" || true 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||
*) | ||||||||||||||||||||||||||||||||||||||||||||||
echo "Usage: $0 {staged|all-changed|branch} [pattern]" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||
;; | ||||||||||||||||||||||||||||||||||||||||||||||
esac |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env bash | ||
# Format JS/TS/JSON/MD files with Prettier | ||
set -euo pipefail | ||
|
||
CONTEXT="${1:-staged}" | ||
files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(js|jsx|ts|tsx|json|md|yml|yaml)$')" | ||
Comment on lines
+5
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quote-safe file handling: avoid word-splitting; use arrays and pass args safely. Files with spaces/newlines will break current usage. Also restaging via echo|xargs is fragile. Refactor to arrays and quote expansions. -# Format JS/TS/JSON/MD files with Prettier
+# Format JS/TS/JSON/MD/YAML files with Prettier
@@
-CONTEXT="${1:-staged}"
-files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(js|jsx|ts|tsx|json|md|yml|yaml)$')"
+CONTEXT="${1:-staged}"
+mapfile -t files < <(bin/lefthook/get-changed-files "$CONTEXT" '\.(js|jsx|ts|tsx|json|md|yml|yaml)$')
@@
-if [ -z "$files" ]; then
+if [ "${#files[@]}" -eq 0 ]; then
echo "✅ No files to format with Prettier"
exit 0
fi
@@
-printf " %s\n" $files
+printf " %s\n" "${files[@]}"
@@
-yarn run prettier --write $files
+yarn run prettier --write -- "${files[@]}"
@@
-# Re-stage files if running on staged or all-changed context
-if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then
- echo $files | xargs -r git add
- echo "✅ Re-staged formatted files"
-fi
+# Re-stage files if running on staged or all-changed context
+if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then
+ git add -- "${files[@]}"
+ echo "✅ Re-staged formatted files"
+fi Also applies to: 8-11, 18-18, 20-20, 23-26 🤖 Prompt for AI Agents
|
||
|
||
if [ -z "$files" ]; then | ||
echo "✅ No files to format with Prettier" | ||
exit 0 | ||
fi | ||
|
||
if [ "$CONTEXT" = "all-changed" ]; then | ||
echo "💅 Prettier on all changed files:" | ||
else | ||
echo "💅 Prettier on $CONTEXT files:" | ||
fi | ||
printf " %s\n" $files | ||
|
||
yarn run prettier --write $files | ||
|
||
# Re-stage files if running on staged or all-changed context | ||
if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then | ||
echo $files | xargs -r git add | ||
echo "✅ Re-staged formatted files" | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env bash | ||
# Auto-fix Ruby files using rake autofix | ||
set -euo pipefail | ||
|
||
CONTEXT="${1:-staged}" | ||
files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(rb|rake|ru)$')" | ||
|
||
if [ -z "$files" ]; then | ||
echo "✅ No Ruby files to autofix" | ||
exit 0 | ||
fi | ||
|
||
if [ "$CONTEXT" = "all-changed" ]; then | ||
echo "🎨 Autofix on all changed Ruby files:" | ||
else | ||
echo "🎨 Autofix on $CONTEXT Ruby files:" | ||
fi | ||
printf " %s\n" $files | ||
|
||
bundle exec rake autofix | ||
|
||
# Re-stage files if running on staged or all-changed context | ||
if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then | ||
echo $files | xargs -r git add | ||
echo "✅ Re-staged formatted files" | ||
fi | ||
Comment on lines
+13
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Limit autofix scope to changed files and restage safely. Running -if [ "$CONTEXT" = "all-changed" ]; then
- echo "🎨 Autofix on all changed Ruby files:"
-else
- echo "🎨 Autofix on $CONTEXT Ruby files:"
-fi
-printf " %s\n" $files
-
-bundle exec rake autofix
-
-# Re-stage files if running on staged or all-changed context
-if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then
- echo $files | xargs -r git add
- echo "✅ Re-staged formatted files"
-fi
+mapfile -t arr < <(printf "%s\n" "$files")
+if [ "$CONTEXT" = "all-changed" ]; then
+ echo "🎨 Autofix on all changed Ruby files:"
+else
+ echo "🎨 Autofix on $CONTEXT Ruby files:"
+fi
+printf " %s\n" "${arr[@]}"
+
+# RuboCop autocorrect only on the targeted files
+bundle exec rubocop -A --force-exclusion -- "${arr[@]}"
+
+# Re-stage only the targeted files when applicable
+if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then
+ git add -- "${arr[@]}"
+ echo "✅ Re-staged formatted files"
+fi
🤖 Prompt for AI Agents
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,27 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
#!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||||||
# Lint Ruby files with RuboCop | ||||||||||||||||||||||||||||||||||||||||||||||||||
set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CONTEXT="${1:-staged}" | ||||||||||||||||||||||||||||||||||||||||||||||||||
files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(rb|rake|ru)$')" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if [ -z "$files" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "✅ No Ruby files to lint" | ||||||||||||||||||||||||||||||||||||||||||||||||||
exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
fi | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if [ "$CONTEXT" = "all-changed" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "🔍 RuboCop on all changed Ruby files:" | ||||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "🔍 RuboCop on $CONTEXT Ruby files:" | ||||||||||||||||||||||||||||||||||||||||||||||||||
fi | ||||||||||||||||||||||||||||||||||||||||||||||||||
printf " %s\n" $files | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if ! bundle exec rubocop --force-exclusion --display-cop-names -- $files; then | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "" | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+13
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle filenames safely and pass args without word-splitting. Use arrays and quote when invoking RuboCop. -if [ "$CONTEXT" = "all-changed" ]; then
- echo "🔍 RuboCop on all changed Ruby files:"
-else
- echo "🔍 RuboCop on $CONTEXT Ruby files:"
-fi
-printf " %s\n" $files
-
-if ! bundle exec rubocop --force-exclusion --display-cop-names -- $files; then
+mapfile -t arr < <(printf "%s\n" "$files")
+if [ "$CONTEXT" = "all-changed" ]; then
+ echo "🔍 RuboCop on all changed Ruby files:"
+else
+ echo "🔍 RuboCop on $CONTEXT Ruby files:"
+fi
+printf " %s\n" "${arr[@]}"
+
+if ! bundle exec rubocop --force-exclusion --display-cop-names -- "${arr[@]}"; then
echo ""
echo "❌ RuboCop check failed!"
- echo "💡 Auto-fix: bundle exec rubocop --auto-correct --force-exclusion -- $files"
+ echo "💡 Auto-fix: bundle exec rubocop --auto-correct --force-exclusion -- ${arr[*]}"
echo "🚫 Skip hook: git commit --no-verify"
exit 1
fi 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||
echo "❌ RuboCop check failed!" | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "💡 Auto-fix: bundle exec rubocop --auto-correct --force-exclusion -- $files" | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "🚫 Skip hook: git commit --no-verify" | ||||||||||||||||||||||||||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||
fi | ||||||||||||||||||||||||||||||||||||||||||||||||||
echo "✅ RuboCop checks passed for Ruby files" |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -102,7 +102,8 @@ | |||||||||||||
"type-check": "yarn run tsc --noEmit --noErrorTruncation", | ||||||||||||||
"release:patch": "node_package/scripts/release patch", | ||||||||||||||
"release:minor": "node_package/scripts/release minor", | ||||||||||||||
"release:major": "node_package/scripts/release major" | ||||||||||||||
"release:major": "node_package/scripts/release major", | ||||||||||||||
"postinstall": "test -f .lefthook.yml && test -d .git && command -v bundle >/dev/null 2>&1 && bundle exec lefthook install || true" | ||||||||||||||
}, | ||||||||||||||
Comment on lines
+105
to
107
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Harden postinstall repo detection; don’t assume .git is a directory. Use Git to detect a repo; also guard on git availability. - "postinstall": "test -f .lefthook.yml && test -d .git && command -v bundle >/dev/null 2>&1 && bundle exec lefthook install || true"
+ "postinstall": "test -f .lefthook.yml && command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1 && command -v bundle >/dev/null 2>&1 && bundle exec lefthook install || true" 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||
"repository": { | ||||||||||||||
"type": "git", | ||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -30,4 +30,10 @@ if [ -f "Gemfile" ]; then | |||||||||||||||||||||
bundle check --path vendor/gems 2>&1 >/dev/null || { | ||||||||||||||||||||||
bundle install --path vendor/gems --quiet --without production | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
# Install Git hooks for code quality (development only) | ||||||||||||||||||||||
if [ -f ".lefthook.yml" ] && [ -d ".git" ]; then | ||||||||||||||||||||||
echo "==> Installing Git hooks for code quality…" | ||||||||||||||||||||||
bundle exec lefthook install | ||||||||||||||||||||||
fi | ||||||||||||||||||||||
Comment on lines
+34
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make Git repo detection work with worktrees/submodules (don’t rely on .git dir).
- if [ -f ".lefthook.yml" ] && [ -d ".git" ]; then
+ if [ -f ".lefthook.yml" ] && git rev-parse --git-dir >/dev/null 2>&1; then
echo "==> Installing Git hooks for code quality…"
bundle exec lefthook install
fi 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid running fixers and linters in parallel; enforce deterministic sequence.
parallel: true
can raceautofix
/prettier
withrubocop
, causing flaky failures and missed restaging.📝 Committable suggestion
🤖 Prompt for AI Agents