diff --git a/.husky/pre-push b/.husky/pre-push index db5d79b2f3..f60c0bb345 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -139,34 +139,35 @@ fi # name, and one merge went red on `main` with the error printed here as a note # nobody read, on a day CI's queue could not report it either. # -# "Affects" is the packages the diff changes, derived by gate-scope like the -# test scope, AND every package that depends on them (`--filter=...`), -# since a shared package can stay type-correct itself and break a consumer. -# `--only` keeps the verdict to those packages: without it the task graph also -# pulls in their unchanged DEPENDENCIES through `^check-types`, and a red there -# is somebody else's, the case the note below exists for. The builds those -# dependencies would have supplied already ran above. -# -# Not turbo's `--affected`: it reads any root-level change as touching every -# package, so a push that edits only `scripts/` would be refused over a red in -# a package it never reached. gate-scope already knows which root files -# redefine the graph (workspace list, task graph, root manifest, lockfile); -# for those no package can be blamed and the repo-wide verdict is the one -# that holds. +# "Affects" is turbo's own answer, not a second model kept here. `--affected` +# selects the packages whose files changed against `origin/main` (merge-base, +# so a `main` that moved on is not read as this branch's change), every +# package that depends on them, and every package when a GLOBAL input changed: +# `turbo.jsonc` declares `scripts/**`, the root manifest and the lockfile as +# reaching every task, because a root script is compiled by a workspace's +# typecheck and a lockfile bump changes what every package compiles against. +# CI's typecheck follows the same hashes, so a push this refuses is one CI +# would refuse at merge. `--only` keeps the verdict to the selected packages: +# without it the task graph also pulls in their unchanged DEPENDENCIES through +# `^check-types`, and a red there is somebody else's, the case the note below +# exists for. The builds those dependencies would have supplied already ran +# above. +# +# A diff that redefines the workspace or task graph (gate-scope status 2) +# cannot be narrowed by any tool, so the repo-wide verdict is the one that +# holds for it. if [ "$TYPES_STATUS" -ne 0 ]; then if [ "$GATE_STATUS" -eq 2 ]; then echo "pre-push: the diff redefines the workspace, task or dependency graph and the typecheck is red; refusing." >&2 exit 1 - elif [ -n "$GATE_FILTERS" ]; then - AFFECTED_FILTERS=$(printf '%s\n' "$GATE_FILTERS" | sed 's/^--filter=/--filter=.../') - # shellcheck disable=SC2086 -- one flag per line, intentionally word-split - if ! pnpm turbo check-types --continue --only $AFFECTED_FILTERS; then - echo "" >&2 - echo "pre-push: the typecheck is red in a package this push changes or one that depends on it; refusing." >&2 - echo " Fix it here, or if it came in with a merge from main, fix it here anyway:" >&2 - echo " the push carries it." >&2 - exit 1 - fi + fi + if ! TURBO_SCM_BASE=origin/main pnpm turbo check-types --continue --affected --only; then + echo "" >&2 + echo "pre-push: the typecheck is red in a package this push affects; refusing." >&2 + echo " A package this push changes, one that depends on it, or every package when a" >&2 + echo " root input (scripts/, the root manifest, the lockfile) changed. Fix it here," >&2 + echo " or if it came in with a merge from main, fix it here anyway: the push carries it." >&2 + exit 1 fi echo "" echo "pre-push: NOTE — the repo-wide typecheck failed outside the packages this"