Skip to content

Commit a15e98d

Browse files
jonphippsclaude
andcommitted
feat: optimize husky hooks with nx affected detection
- Replace all 'pnpm' commands with 'nx affected' in pre-commit hook - Update pre-push hook to use nx affected throughout with smart detection - Remove obsolete shared-config references from all hooks and build scripts - Add test-site-builds-affected.js for nx-aware configuration validation - Update build scripts to support --affected flag for faster builds - Ensure serialized builds (parallel=1) to prevent static state contamination - Add uncommitted file detection when no affected projects found This significantly improves git hook performance by only testing/building affected projects instead of the entire workspace. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent a8d3eec commit a15e98d

File tree

9 files changed

+722
-216
lines changed

9 files changed

+722
-216
lines changed

.husky/pre-commit

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,27 @@
11
#!/usr/bin/env sh
2-
# Pre-commit hook for IFLA Standards project
3-
# Runs essential checks before allowing commits
2+
# NX-optimized pre-commit hook for IFLA Standards project
3+
# Runs essential checks on affected projects only
44

5-
echo "🔍 Running pre-commit checks..."
5+
echo "🔍 Running NX-optimized pre-commit checks..."
66

7-
# 1. Run TypeScript type checking (fast, catches major issues)
8-
echo "📝 Checking TypeScript..."
9-
pnpm typecheck
10-
if [ $? -ne 0 ]; then
11-
echo "❌ TypeScript errors found. Please fix before committing."
12-
exit 1
13-
fi
14-
15-
# 2. Run ESLint (code quality)
16-
echo "🔧 Running ESLint..."
17-
pnpm lint --quiet
18-
if [ $? -ne 0 ]; then
19-
echo "❌ ESLint errors found. Please fix before committing."
7+
# Run affected checks in parallel for maximum efficiency
8+
echo "⚡ Running affected typecheck, lint, and test in parallel..."
9+
{
10+
nx affected --target=typecheck --parallel=3 &
11+
nx affected --target=lint --parallel=3 &
12+
nx affected --target=test --parallel=3 &
13+
wait
14+
} || {
15+
echo "❌ Pre-commit checks failed. Please fix and try again."
2016
exit 1
21-
fi
22-
23-
# 3. Run unit tests (fast feedback on component changes)
24-
echo "🧪 Running unit tests..."
25-
pnpm test --run
26-
if [ $? -ne 0 ]; then
27-
echo "❌ Unit tests failed. Please fix before committing."
28-
exit 1
29-
fi
17+
}
3018

31-
# 4. Quick configuration validation (for config changes)
32-
echo "⚙️ Validating site configurations..."
33-
node scripts/test-site-builds.js --site all --env local --skip-build
19+
# Quick configuration validation for affected sites only
20+
echo "⚙️ Validating affected site configurations..."
21+
node scripts/test-site-builds-affected.js --env local --skip-build
3422
if [ $? -ne 0 ]; then
3523
echo "❌ Site configuration validation failed."
3624
exit 1
3725
fi
3826

39-
echo "✅ All pre-commit checks passed!"
27+
echo "✅ All NX-optimized pre-commit checks passed!"

.husky/pre-push

Lines changed: 113 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,131 @@
11
#!/usr/bin/env sh
2-
# Gentle Pre-push reminder for IFLA Standards project
3-
# Just reminds about testing, doesn't force it
2+
# Optimized Pre-push hook for IFLA Standards project
3+
# Uses Nx affected detection and smart caching for fast regression tests
44

5+
echo "🚀 Running optimized pre-push regression tests..."
6+
7+
# Get the current branch name
58
BRANCH=$(git branch --show-current)
6-
LAST_TEST_FILE=".git/.last-regression-test"
7-
CURRENT_COMMIT=$(git rev-parse HEAD)
9+
echo "📋 Testing branch: $BRANCH"
810

9-
echo "🚀 Preparing to push to branch: $BRANCH"
11+
# Get affected projects using Nx
12+
echo "🎯 Detecting affected projects..."
13+
AFFECTED_PROJECTS=$(npx nx print-affected --select=projects --type=app 2>/dev/null || echo "")
1014

11-
# Function to check if regression tests have been run recently
12-
check_recent_tests() {
13-
if [ -f "$LAST_TEST_FILE" ]; then
14-
LAST_TEST_COMMIT=$(cat "$LAST_TEST_FILE")
15-
# Check if current commit is descendant of last tested commit
16-
if git merge-base --is-ancestor "$LAST_TEST_COMMIT" "$CURRENT_COMMIT" 2>/dev/null; then
17-
return 0 # Tests are recent
18-
fi
15+
if [ -z "$AFFECTED_PROJECTS" ] || [ "$AFFECTED_PROJECTS" = "" ]; then
16+
echo "📝 No affected projects detected - running minimal validation"
17+
18+
# Since no projects are affected, check if there are uncommitted changes
19+
echo "⚡ Checking for uncommitted changes..."
20+
UNCOMMITTED_FILES=$(git diff --name-only)
21+
if [ -z "$UNCOMMITTED_FILES" ]; then
22+
echo "✅ No changes detected - proceeding with push."
23+
exit 0
24+
fi
25+
26+
# Run minimal validation on uncommitted files
27+
echo "📝 Running minimal validation..."
28+
npx nx affected --target=typecheck --parallel=3 --skip-nx-cache=false --uncommitted
29+
if [ $? -ne 0 ]; then
30+
echo "❌ TypeScript validation failed."
31+
exit 1
32+
fi
33+
34+
npx nx affected --target=lint --parallel=3 --skip-nx-cache=false --quiet --uncommitted
35+
if [ $? -ne 0 ]; then
36+
echo "❌ Linting failed."
37+
exit 1
1938
fi
20-
return 1 # Tests may be stale
21-
}
39+
40+
echo "✅ Fast validation passed! No builds needed for changes."
41+
exit 0
42+
fi
43+
44+
echo "📦 Affected projects: $AFFECTED_PROJECTS"
2245

23-
# Function to show testing recommendations
24-
show_recommendations() {
25-
echo ""
26-
echo "💡 Testing Recommendations:"
27-
echo ""
46+
# Check if we're pushing to main or dev (stricter testing)
47+
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "dev" ]; then
48+
echo "🔒 Detected push to protected branch ($BRANCH) - running comprehensive tests"
2849

29-
# Check what files changed
30-
CHANGED_FILES=$(git diff --name-only @{u}..HEAD 2>/dev/null || git diff --name-only HEAD~1..HEAD)
50+
# 1. Run affected tests in parallel
51+
echo "🧪 Running tests for affected projects..."
52+
npx nx affected --target=test --parallel=3 --skip-nx-cache=false
53+
if [ $? -ne 0 ]; then
54+
echo "❌ Tests failed for affected projects."
55+
exit 1
56+
fi
57+
58+
# 2. Build affected projects (serialized to prevent contamination)
59+
echo "🏗️ Building affected projects..."
60+
npx nx affected --target=build --parallel=1 --skip-nx-cache=false
61+
if [ $? -ne 0 ]; then
62+
echo "❌ Build failed for affected projects."
63+
exit 1
64+
fi
3165

32-
if echo "$CHANGED_FILES" | grep -qE '^(packages/|libs/)'; then
33-
echo " 📦 Package changes detected"
34-
echo " 🔧 Suggested: pnpm test:regression:optimized"
35-
elif echo "$CHANGED_FILES" | grep -qE '^(portal/|standards/)'; then
36-
echo " 📄 Site content changes detected"
37-
echo " 🔧 Suggested: pnpm test:regression:fast"
38-
elif echo "$CHANGED_FILES" | grep -qE '^(scripts/|\.github/)'; then
39-
echo " ⚙️ Infrastructure changes detected"
40-
echo " 🔧 Suggested: pnpm test:regression:affected"
66+
# 3. Run configuration validation for all sites (fast, no build)
67+
echo "⚙️ Validating all site configurations..."
68+
node scripts/test-site-builds.js --site all --env localhost --skip-build
69+
if [ $? -ne 0 ]; then
70+
echo "❌ Site configuration validation failed."
71+
exit 1
72+
fi
73+
74+
# 4. Only run E2E if portal is affected
75+
if echo "$AFFECTED_PROJECTS" | grep -q "portal"; then
76+
echo "🌐 Portal affected - running critical E2E tests..."
77+
npx nx run portal:e2e || {
78+
echo "⚠️ E2E tests failed but continuing (non-blocking for protected branches)"
79+
}
4180
else
42-
echo " 📝 General changes detected"
43-
echo " 🔧 Suggested: pnpm test:regression:fast"
81+
echo "📝 Portal not affected - skipping E2E tests"
4482
fi
4583

46-
echo ""
47-
echo " ⚡ All options are fast thanks to Nx caching!"
48-
echo " 📊 Performance comparison: node scripts/regression-performance-comparison.js"
49-
echo ""
50-
}
51-
52-
# Check test status
53-
if check_recent_tests; then
54-
echo "✅ Recent regression tests found - you're good to go!"
5584
else
56-
echo "ℹ️ No recent regression tests found"
85+
echo "📝 Feature branch detected - running smart abbreviated tests"
86+
87+
# 1. Fast validation first
88+
echo "⚡ Running fast validation..."
89+
npx nx affected --target=typecheck --parallel=3 --skip-nx-cache=false
90+
if [ $? -ne 0 ]; then
91+
echo "❌ TypeScript validation failed."
92+
exit 1
93+
fi
94+
95+
npx nx affected --target=lint --parallel=3 --skip-nx-cache=false --quiet
96+
if [ $? -ne 0 ]; then
97+
echo "❌ Linting failed."
98+
exit 1
99+
fi
100+
101+
# 2. Test affected projects
102+
echo "🧪 Testing affected projects..."
103+
npx nx affected --target=test --parallel=3 --skip-nx-cache=false
104+
if [ $? -ne 0 ]; then
105+
echo "❌ Tests failed for affected projects."
106+
exit 1
107+
fi
57108

58-
# Only show recommendations for protected branches or if user wants them
59-
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "dev" ]; then
60-
echo "🔒 Protected branch - consider running tests before pushing"
61-
show_recommendations
109+
# 3. Configuration validation for affected sites (fast, no builds)
110+
echo "⚙️ Quick configuration validation..."
111+
node scripts/test-site-builds-affected.js --env localhost --skip-build
112+
if [ $? -ne 0 ]; then
113+
echo "❌ Configuration validation failed."
114+
exit 1
115+
fi
116+
117+
# 4. Build only one representative site if portal affected
118+
if echo "$AFFECTED_PROJECTS" | grep -q "portal"; then
119+
echo "🏗️ Testing representative build..."
120+
npx nx run portal:build --parallel=1 --skip-nx-cache=false
121+
if [ $? -ne 0 ]; then
122+
echo "❌ Representative build test failed."
123+
exit 1
124+
fi
62125
else
63-
echo "📝 Feature branch - tests are optional but recommended"
64-
echo "💡 Run 'pnpm test:regression:fast' for quick validation"
126+
echo "📝 Core infrastructure not affected - skipping build test"
65127
fi
66128
fi
67129

68-
echo "🚀 Proceeding with push..."
69-
exit 0
130+
echo "✅ All optimized pre-push tests passed! Safe to push to $BRANCH."
131+
echo "📊 Time saved by using Nx affected detection and caching!"

.husky/pre-push-optimized

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "dev" ]; then
6363
exit 1
6464
fi
6565

66-
# 4. Only run E2E if portal or shared-config.old is affected
67-
if echo "$AFFECTED_PROJECTS" | grep -q -E "(portal|shared-config)"; then
66+
# 4. Only run E2E if portal is affected
67+
if echo "$AFFECTED_PROJECTS" | grep -q "portal"; then
6868
echo "🌐 Portal affected - running critical E2E tests..."
6969
npx nx run portal:e2e || {
7070
echo "⚠️ E2E tests failed but continuing (non-blocking for protected branches)"
@@ -106,8 +106,8 @@ else
106106
exit 1
107107
fi
108108

109-
# 4. Build only one representative site if portal/shared-config.old affected
110-
if echo "$AFFECTED_PROJECTS" | grep -q -E "(portal|shared-config)"; then
109+
# 4. Build only one representative site if portal affected
110+
if echo "$AFFECTED_PROJECTS" | grep -q "portal"; then
111111
echo "🏗️ Testing representative build..."
112112
npx nx run portal:build --skip-nx-cache=false
113113
if [ $? -ne 0 ]; then

nx.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
"{projectRoot}/sidebars.ts",
2727
"{projectRoot}/src/**/*",
2828
"{projectRoot}/static/**/*",
29-
"{workspaceRoot}/packages/theme/**/*",
30-
"{workspaceRoot}/libs/shared-config/**/*"
29+
"{workspaceRoot}/packages/theme/**/*"
3130
],
3231
"docusaurus-no-theme": [
3332
"{projectRoot}/**/*.{md,mdx}",
@@ -36,8 +35,7 @@
3635
"{projectRoot}/sidebars.js",
3736
"{projectRoot}/sidebars.ts",
3837
"{projectRoot}/src/**/*",
39-
"{projectRoot}/static/**/*",
40-
"{workspaceRoot}/libs/shared-config/**/*"
38+
"{projectRoot}/static/**/*"
4139
],
4240
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
4341
},

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"build": "echo 'Please specify a site to build using: pnpm build:{site}' && exit 1",
1111
"build-env": "node scripts/build-with-env.js",
1212
"build:all": "node scripts/nx-build-all.js",
13+
"build:all:affected": "node scripts/nx-build-all.js --affected",
1314
"build:all:nx": "nx run standards-dev:build-all",
1415
"build:affected": "nx run standards-dev:build-affected",
1516
"build:all:safe": "pnpm clear:all && pnpm build:all",
@@ -237,6 +238,7 @@
237238
"devDependencies": {
238239
"@docusaurus/core": "^3.8.1",
239240
"@docusaurus/eslint-plugin": "^3.8.1",
241+
"@docusaurus/faster": "^3.8.1",
240242
"@docusaurus/module-type-aliases": "3.8.1",
241243
"@docusaurus/plugin-client-redirects": "^3.8.1",
242244
"@docusaurus/plugin-content-docs": "^3.8.1",

0 commit comments

Comments
 (0)