diff --git a/.husky/pre-commit b/.husky/pre-commit index c83fdfc4..3c103710 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,6 @@ # Run quick checks before commit (typecheck + lint + format only). -# Full CI parity is enforced by .husky/pre-push via validate:ci-parity. +# Protected branches still enforce full CI parity in .husky/pre-push. +# Feature branches use a faster pre-push gate plus GitHub CI. bun run typecheck && bun run lint:fix && bun run format:check # Validate UI if changes detected (typecheck + lint only) diff --git a/.husky/pre-push b/.husky/pre-push index 012f1386..1a54c477 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,3 +1,61 @@ -# Enforce CI parity before pushing to remote. +#!/usr/bin/env bash +set -euo pipefail + +# Protected branches keep the full CI parity gate. +# Feature branches use a faster gate and let GitHub CI run the full suite. # Override in emergencies only: CCS_SKIP_PREPUSH_GATE=1 git push --no-verify -bun run validate:ci-parity + +CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" +BASE_BRANCH="${CCS_PR_BASE:-}" + +if [[ -z "$BASE_BRANCH" ]]; then + if [[ "$CURRENT_BRANCH" == "main" || "$CURRENT_BRANCH" =~ ^hotfix/ || "$CURRENT_BRANCH" =~ ^kai/hotfix- ]]; then + BASE_BRANCH="main" + else + BASE_BRANCH="dev" + fi +fi + +if [[ "$CURRENT_BRANCH" == "main" || "$CURRENT_BRANCH" == "dev" || "$CURRENT_BRANCH" =~ ^hotfix/ || "$CURRENT_BRANCH" =~ ^kai/hotfix- ]]; then + echo "[i] Protected branch detected, running full CI parity gate..." + bun run validate:ci-parity + exit 0 +fi + +echo "[i] Feature branch detected, running fast pre-push gate..." +echo " branch: $CURRENT_BRANCH" +echo " base: $BASE_BRANCH" + +bun run typecheck +bun run lint:fix +bun run format:check + +git fetch origin "$BASE_BRANCH" --quiet || true +DIFF_RANGE="HEAD" +if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH"; then + DIFF_RANGE="origin/$BASE_BRANCH...HEAD" +fi + +CHANGED_FILES="$(git diff --name-only "$DIFF_RANGE" || true)" + +if printf '%s\n' "$CHANGED_FILES" | grep -q '^ui/'; then + echo "[i] UI changes detected, running ui:validate..." + bun run ui:validate +fi + +if printf '%s\n' "$CHANGED_FILES" | grep -qE '^(\.github/workflows/|scripts/github/|tests/unit/scripts/github/)'; then + echo "[i] GitHub workflow changes detected, running workflow tests..." + bun test tests/unit/scripts/github +fi + +if printf '%s\n' "$CHANGED_FILES" | grep -qE '^(src/commands/update-command.ts|tests/unit/commands/update-command-current-install.test.ts|tests/integration/update-command-install-origin.test.ts)'; then + echo "[i] Update command changes detected, running targeted update tests..." + bun test tests/unit/commands/update-command-current-install.test.ts tests/integration/update-command-install-origin.test.ts +fi + +if printf '%s\n' "$CHANGED_FILES" | grep -qE '^(src/cursor/cursor-models.ts|tests/unit/cursor/cursor-models.test.ts)'; then + echo "[i] Cursor model changes detected, running targeted cursor model tests..." + bun test tests/unit/cursor/cursor-models.test.ts +fi + +echo "[OK] Fast pre-push gate passed." diff --git a/CLAUDE.md b/CLAUDE.md index 4755d598..3c182ac2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -183,7 +183,7 @@ Quality gates MUST pass before pushing. **Both projects have identical workflow. bun run format # Step 1: Fix formatting bun run lint:fix # Step 2: Fix lint issues bun run validate # Step 3: Full gate (typecheck + lint + format + maintainability + tests) -bun run validate:ci-parity # Step 4: CI parity gate (build + validate + base branch check) +bun run validate:ci-parity # Step 4: full CI parity gate (build + validate + base branch check) # UI project (if UI changed) cd ui @@ -230,7 +230,8 @@ bun run validate # Step 3: Final check (must pass) - `prepublishOnly` / `prepack` runs `build:all` + `validate` + `sync-version.js` - CI/CD runs `bun run validate` on every PR (maintainability is warning mode on PR events) - husky `pre-commit` runs quick lint/type/format checks -- husky `pre-push` runs `bun run validate:ci-parity` to block CI drift before push +- husky `pre-push` runs the full `bun run validate:ci-parity` gate on `main`/`dev`/hotfix branches +- husky `pre-push` runs a faster feature-branch gate (`typecheck` + `lint:fix` + `format:check` + targeted checks based on changed files) before GitHub CI handles the full matrix ### Maintainability Baseline Gate @@ -503,7 +504,7 @@ rm -rf ~/.ccs # Clean environment **Quality (BLOCKERS):** - [ ] `bun run format` — formatting fixed - [ ] `bun run validate` — all checks pass -- [ ] `bun run validate:ci-parity` — CI parity passed (also enforced by pre-push hook) +- [ ] `bun run validate:ci-parity` — CI parity passed (required before protected-branch pushes; recommended before PRs) - [ ] `cd ui && bun run format && bun run validate` — if UI changed - [ ] If touching debt-sensitive code, run `bun run maintainability:check:strict` before opening/merging PR - [ ] If strict mode fails and increase is intentional: `bun run maintainability:baseline` and commit `docs/metrics/maintainability-baseline.json`