diff --git a/.husky/pre-push b/.husky/pre-push index 5595d082..394f72e2 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1 +1,7 @@ -pnpm run prepush 2>&1 +# Run lint, typecheck and the frontend build, then the tests related to what the push changes. The full suite is CI's job: it runs there on every pull request, so repeating it here only repeats the same work for each push attempt, and again for each attempt that fails. +# The related tests are those vitest finds from the module graph for the files changed since the push diverged from origin/main, and a push that changes no source file has none to run, which is a pass. A change to the vitest config, package.json or the lockfile still reruns everything, as vitest treats those as triggers. +# Workers are the cores the machine's run queue leaves free, and at least one: vitest starts a pool the size of the core count by default, so several pushes at once on a shared machine each oversubscribe it, and every test slows until the guards against a hang fire on tests that did nothing wrong. +base=$(git merge-base origin/main HEAD) && +workers=$(node -p "Math.max(1, os.availableParallelism() - Math.ceil(os.loadavg()[0]))") && +pnpm run prepush 2>&1 && +pnpm exec vitest run --changed "$base" --passWithNoTests --maxWorkers="$workers" 2>&1 diff --git a/turbo.json b/turbo.json index 15da1c9c..f18faa41 100644 --- a/turbo.json +++ b/turbo.json @@ -17,11 +17,14 @@ "inputs": ["$TURBO_DEFAULT$", "eslint.config.ts"] }, "_prepush": { - "dependsOn": ["_lint", "_typecheck", "_test"] + // The checks the pre-push hook runs before its related-tests run. The build is here because the web-bridge + // integration tests the hook may select need it (see _test), and turbo caches it, so it costs nothing when + // the frontend sources are unchanged. + "dependsOn": ["_lint", "_typecheck", "_build:frontend"] }, "_test": { - // The web-bridge integration tests request the frontend routes, which serve src/bridges/user/web/dist - // -- without this dependency, a fresh checkout with no prior build (a new worktree's pre-push hook, in + // The web-bridge integration tests request the frontend routes, which serve src/bridges/user/web/dist. + // Without this dependency, a fresh checkout with no prior build (a new worktree running the tests, in // particular) gets 503 from those routes and fails those suites rather than actually exercising them. "dependsOn": ["_build:frontend"] },