Skip to content

Commit 20d92e3

Browse files
hotlongclaude
andauthored
ci(test-alias): gate that a unit test judges source, not a sibling's dist (#7966)
Every publishable package resolves through `exports` to `dist/`, so a package whose tests import a workspace dependency with no vitest source alias is reporting on build state rather than on the source in the checkout. #7668 is the loud version of that: 17 cases erroring on a symbol its prebuilt core predated. The version this gate is aimed at is silent — a dist merely BEHIND the source runs GREEN against old behaviour, with nothing in the output saying so. Demonstrated on this repo before writing the gate: with `@objectstack/spec` unaliased, `packages/qa/downstream-contract` — the frozen third-party fixture that exists to catch breaking spec changes — reported 14/14 green against a spec source that rejected its own fixture outright. Aliasing spec to source on the identical tree turned it red naming the injected field. Both edits were reverted. The gate walks each package's test-reachable imports (type-only imports excluded — they never resolve), keeps the deps whose own entry point is a build artifact, and resolves each specifier through the package's vitest aliases the way Vite does (in order, first match wins, string `find` by prefix). It also fails the prefix/ENOTDIR trap #7778 documented, since it performs the real replacement and can see a path running through a file. `KNOWN_UNALIASED_TEST_IMPORTS` is the measured state: 63 of 72 packages with tests, 312 package-dependency pairs. It is shrink-only and audited in both directions, so an entry that is no longer needed fails and names itself for deletion. Each entry carries its exact dependency set rather than a bare package name, so a listed package cannot acquire new artifact imports with nothing going red. No package's vitest config is touched here; per-package remediation is filed separately. Claude-Session: https://claude.ai/code/session_01CD4dmUPWszMro2K4Mwzpwj Co-authored-by: Claude <noreply@anthropic.com>
1 parent 551f899 commit 20d92e3

3 files changed

Lines changed: 1179 additions & 0 deletions

File tree

‎.github/workflows/lint.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,27 @@ jobs:
566566
- name: Cross-package test inputs
567567
run: pnpm check:cross-package-test-inputs
568568

569+
# Tests must judge SOURCE, not a sibling's build artifact (#7668/#7849).
570+
# Every publishable package resolves through `exports` to `dist/`, so a
571+
# package whose tests import a workspace dep with no vitest source alias
572+
# is reporting on build state. #7668 is the loud version of that (17 cases
573+
# erroring on a symbol its prebuilt core predated); the version this gate
574+
# is really aimed at is SILENT — a dist merely BEHIND the source runs
575+
# GREEN against old behaviour, and nothing in the output says so.
576+
# Demonstrated on this very repo: with `@objectstack/spec` unaliased, the
577+
# frozen downstream-consumer contract — the repo's backward-compatibility
578+
# gate for spec — reported 14/14 green against a spec source that rejected
579+
# its own fixture outright; aliased to source, the same tree went red.
580+
# Turbo's `test` dependsOn `^build` does not reach it, because the failing
581+
# paths are the ones turbo does not mediate (`pnpm test` in a package,
582+
# `vitest run <file>`, an editor runner, an agent in a stale tree).
583+
# The registry is measured, shrink-only and audited in BOTH directions, so
584+
# it cannot rot into a grandfather clause: an entry that is no longer
585+
# needed fails and names itself for deletion. Static scan of test sources
586+
# and vitest configs; no build needed, so it belongs in this job.
587+
- name: Test-source alias gate
588+
run: pnpm check:test-source-alias
589+
569590
# #4248 packaging-hygiene guard. Without a `files` whitelist npm packs the
570591
# whole package directory, and 20 of the 49 publishable packages declared
571592
# none — so consumers installed TypeScript sources, unit tests and build

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"check:shard-attestation": "node scripts/check-shard-attestation.mjs --self-test && node scripts/check-shard-attestation.mjs",
8181
"check:required-contexts": "node scripts/check-required-contexts.mjs --self-test && node scripts/check-required-contexts.mjs",
8282
"check:cross-package-test-inputs": "node scripts/check-cross-package-test-inputs.mjs --self-test && node scripts/check-cross-package-test-inputs.mjs",
83+
"check:test-source-alias": "node scripts/check-test-source-alias.mjs --self-test && node scripts/check-test-source-alias.mjs",
8384
"check:published-files": "node scripts/check-published-files.mjs --self-test && node scripts/check-published-files.mjs",
8485
"check:type-check-coverage": "node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs",
8586
"check:type-check-debt": "node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs --re-measure",

0 commit comments

Comments
 (0)