From 7b80c257337f6dccc3fd479cd342cd12e660ce51 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 20:21:12 +0000 Subject: [PATCH 1/2] ci(turbo): derive the lint and build inputs guards from each package's real program (#4184, #4185) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `lint` and `build` both declared no `inputs` at all, so both ran on turbo's default — which covers only files inside the package directory. The repo-root `eslint.config.js` that IS the lint program, and the root tsconfigs plus `scripts/vite-*.ts` that the build programs read, were unhashed: turbo replayed the previous verdict instead of re-running. Adds the third and fourth walkers on the #4176 / #4188 architecture — an ESLint flat-config program and a build program (a union over tsc / vite / tsup / next / node / pnpm segments) — plus the family's completeness gate, which asserts every CACHEABLE turbo task has a guard so a fifth instance cannot arrive quietly. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3 --- scripts/__tests__/helpers/build-program.ts | 356 ++++++++++++++++++ scripts/__tests__/helpers/config-program.ts | 217 +++++++++++ .../helpers/eslint-config-program.ts | 224 +++++++++++ scripts/__tests__/helpers/tsc-program.ts | 148 ++++++++ scripts/__tests__/helpers/turbo-inputs.ts | 22 +- .../helpers/vitest-config-program.ts | 172 ++------- scripts/__tests__/turbo-build-inputs.test.ts | 233 ++++++++++++ scripts/__tests__/turbo-lint-inputs.test.ts | 245 ++++++++++++ .../turbo-task-guard-coverage.test.ts | 97 +++++ .../__tests__/turbo-type-check-inputs.test.ts | 126 +------ turbo.json | 15 +- 11 files changed, 1584 insertions(+), 271 deletions(-) create mode 100644 scripts/__tests__/helpers/build-program.ts create mode 100644 scripts/__tests__/helpers/config-program.ts create mode 100644 scripts/__tests__/helpers/eslint-config-program.ts create mode 100644 scripts/__tests__/helpers/tsc-program.ts create mode 100644 scripts/__tests__/turbo-build-inputs.test.ts create mode 100644 scripts/__tests__/turbo-lint-inputs.test.ts create mode 100644 scripts/__tests__/turbo-task-guard-coverage.test.ts diff --git a/scripts/__tests__/helpers/build-program.ts b/scripts/__tests__/helpers/build-program.ts new file mode 100644 index 000000000..52f904798 --- /dev/null +++ b/scripts/__tests__/helpers/build-program.ts @@ -0,0 +1,356 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { outOfPackageProgramFiles } from './config-program'; +import { + invocationForCommand, + outOfPackageFilesFor, + type TscInvocation, +} from './tsc-program'; +import { rel, repoRoot, type WorkspacePackage } from './turbo-inputs'; + +/** + * Derives a workspace package's **build program** — the set of files the tools + * its `build` script drives read in order to know what to produce. + * + * The fourth instance of the objectui#3514 class (objectui#4185), and the one + * with the widest blast radius: `build` declared no `inputs` at all, and `build` + * is the task whose `dist/` every other task consumes through + * `dependsOn: ["^build"]`. A build replayed from a cache key that ignored a + * `strict` flip in the root `tsconfig.json` hands stale `dist/` to everything + * downstream. + * + * ## Why this derivation is a union rather than one walk + * + * `type-check` scripts are all tsc and `test` scripts are all Vitest, so each of + * those guards derives one kind of program. `build` scripts are not uniform — + * they are `&&` chains over five tools: + * + * tsc 14 packages the tsc program (./tsc-program.ts) + * vite build 22 packages the Vite config program + * tsup 4 packages the tsup config program + its tsconfig + * next build 1 app the Next config program + its tsconfig + * node