Skip to content

Commit 905a1d2

Browse files
claude[bot]claude
andauthored
ci(test): six heavy packages split test into test and test:repo so package suites cache again (#16560)
* ci(test): six heavy packages split `test` into `test` and `test:repo` so package suites cache again Every file stays where it is. spec, core, types, runtime, objectql and rest each define two vitest projects in one config -- `local` (every other test file) and `repo` (the tests that read outside the package, listed in a vitest.repo-tests.json sidecar) -- and two turbo tasks: `test` keeps package-local inputs, `test:repo` takes the wide `$TURBO_ROOT$` inputs that used to invalidate the whole suite on any change inside the radius. check-cross-package-test-inputs gains the split rule: for a package whose manifest declares `test:repo`, the declared globs must hash on `PKG#test:repo`, `PKG#test` must carry no repo-wide input, and the sidecar list must equal the gate's own scan in both directions (16 new self-test cases in a declared battery). check-test-completeness reads `test:repo` summaries, group headers, bare headers and `Failed:` rosters as the same package. ci.yml's Test Core whole leg runs `turbo run test test:repo`; the cli slice leg is unchanged. Collected files before/after (vitest list --filesOnly): spec 482 = 456 + 26, core 51 = 49 + 2, types 20 = 19 + 1, runtime 238 = 236 + 2, objectql 284 = 283 + 1, rest 187 = 186 + 1; no overlap; each repo project equals its sidecar. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox * test(vitest): each project re-declares the root block's test options A root-level `env` / `disableConsoleIntercept` is inert for a project run (measured on vitest 4.1.10; check-registry-log-declared and check-console-intercept-disarm both pin it), so `local` and `repo` carry the root block's options themselves. Collected files re-proved on the merged tree against main's own config: 484 = 458 + 26, 51 = 49 + 2, 20 = 19 + 1, 238 = 236 + 2, 285 = 284 + 1, 188 = 187 + 1; overlap 0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent fe0d9a4 commit 905a1d2

23 files changed

Lines changed: 651 additions & 90 deletions

‎.github/workflows/ci.yml‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,13 +550,23 @@ jobs:
550550
# a second full suite to a job that is already red and already inside a
551551
# 30-minute wall — turning an informative red into a killed job with no
552552
# attestation at all, which is the #16173 failure mode itself.
553+
#
554+
# `test test:repo` (#16466): six heavy packages split their suite into
555+
# two turbo tasks -- `test` (package-local inputs) and `test:repo`
556+
# (the repo-scanning tests, hashed on the wide `$TURBO_ROOT$` inputs
557+
# that used to sit on `test`). Naming both runs a split package whole
558+
# and is a no-op for every package without a `test:repo` script. The
559+
# per-shard Turbo cache restored above (main-seeded) is what carries
560+
# an unmoved `PKG#test` across a change outside the package; the
561+
# completeness guard below reads both tasks' summaries. The cli slice
562+
# leg stays `test`-only: cli is not split.
553563
STATUS=0
554564
LOGS=""
555565
for LEG in __whole__ $SLICES; do
556566
if [ "$LEG" = __whole__ ]; then
557567
[ -n "$FILTERS" ] || continue
558568
LOG="$RUNNER_TEMP/test-core-packages.log"
559-
set -- pnpm turbo run test $FILTERS --concurrency=4 --summarize --log-order=stream
569+
set -- pnpm turbo run test test:repo $FILTERS --concurrency=4 --summarize --log-order=stream
560570
else
561571
PKG="${LEG%%=*}"
562572
SLICE="${LEG#*=}"

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"dev:crm": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-crm dev",
1111
"dev:todo": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-todo dev",
1212
"spec:rebuild": "turbo run build --filter=...@objectstack/spec",
13-
"test": "VITEST_MAX_WORKERS=$(node scripts/vitest-worker-cap.mjs) turbo run test --concurrency=50%",
13+
"test": "VITEST_MAX_WORKERS=$(node scripts/vitest-worker-cap.mjs) turbo run test test:repo --concurrency=50%",
1414
"test:smoke": "turbo run test:smoke",
1515
"typecheck": "turbo run typecheck",
1616
"clean": "turbo run clean && rm -rf dist",

‎packages/core/package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.examples.json && pnpm check:test-typecheck",
2424
"check:test-typecheck": "tsx ../../scripts/check-test-typecheck.mts --self-test && tsx ../../scripts/check-test-typecheck.mts --package packages/core --project tsconfig.test.json",
2525
"gen:test-typecheck-debt": "tsx ../../scripts/check-test-typecheck.mts --update --package packages/core --project tsconfig.test.json",
26-
"test": "vitest run",
26+
"test": "vitest run --project local",
27+
"test:repo": "vitest run --project repo",
2728
"test:watch": "vitest"
2829
},
2930
"devDependencies": {

‎packages/core/vitest.config.ts‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,49 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

3-
import { defineConfig } from 'vitest/config';
3+
import { configDefaults, defineConfig } from 'vitest/config';
4+
import { readFileSync } from 'node:fs';
45
import path from 'path';
56

7+
// #16466 -- two vitest projects, two turbo tasks. `repo` owns the tests that read
8+
// outside this package (the list is vitest.repo-tests.json, which
9+
// check:cross-package-test-inputs holds equal to its own scan); `local` owns
10+
// every other test file. turbo hashes the wide `$TURBO_ROOT$` inputs on
11+
// `test:repo` only, so `test` stays cacheable across changes elsewhere in the
12+
// repo. `extends: true` keeps the root options (aliases included) on both.
13+
const REPO_TESTS: string[] = JSON.parse(readFileSync(path.join(__dirname, 'vitest.repo-tests.json'), 'utf8'));
14+
615
export default defineConfig({
716
test: {
17+
// Each project re-declares the root block's test options: a ROOT-level
18+
// value is inert for a project run (measured on vitest 4.1.10, see
19+
// check-registry-log-declared / check-console-intercept-disarm).
20+
projects: [
21+
{
22+
extends: true,
23+
test: {
24+
name: 'local',
25+
include: configDefaults.include,
26+
exclude: [...configDefaults.exclude, ...REPO_TESTS],
27+
globals: true, environment: 'node',
28+
// A late console.* must not redden a green suite (#10374); see the root
29+
// block. A ROOT-level value is inert for a project run, so it is
30+
// declared here as well (scripts/check-console-intercept-disarm.mjs).
31+
disableConsoleIntercept: true,
32+
},
33+
},
34+
{
35+
extends: true,
36+
test: {
37+
name: 'repo',
38+
include: REPO_TESTS,
39+
globals: true, environment: 'node',
40+
// A late console.* must not redden a green suite (#10374); see the root
41+
// block. A ROOT-level value is inert for a project run, so it is
42+
// declared here as well (scripts/check-console-intercept-disarm.mjs).
43+
disableConsoleIntercept: true,
44+
},
45+
},
46+
],
847
// A late console.* must not redden a green suite (#10374): vitest's worker
948
// forwards console output over RPC and discards the promise, and a write
1049
// landing after teardown's rpcDone() snapshot is rejected into an unhandled
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
"src/security/authz-store-unavailable.test.ts",
3+
"src/security/operation-private-keys.pin.test.ts"
4+
]

‎packages/objectql/package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
},
2020
"scripts": {
2121
"build": "tsup && node ../../scripts/check-dts-emitted.mjs",
22-
"test": "vitest run",
22+
"test": "vitest run --project local",
23+
"test:repo": "vitest run --project repo",
2324
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.scripts.json && pnpm check:test-typecheck",
2425
"check:test-typecheck": "tsx ../../scripts/check-test-typecheck.mts --self-test && tsx ../../scripts/check-test-typecheck.mts --package packages/objectql --project tsconfig.test.json",
2526
"gen:test-typecheck-debt": "tsx ../../scripts/check-test-typecheck.mts --update --package packages/objectql --project tsconfig.test.json"

‎packages/objectql/vitest.config.ts‎

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,56 @@
4040
// cannot silently re-point that file's premise. Without those two lines the
4141
// file's first case stays GREEN while testing `'warn'` under a name that says
4242
// `info` — measured red before they were added.
43-
import { defineConfig } from 'vitest/config';
43+
import { configDefaults, defineConfig } from 'vitest/config';
44+
import { readFileSync } from 'node:fs';
45+
import path from 'node:path';
46+
47+
// #16466 -- two vitest projects, two turbo tasks. `repo` owns the tests that read
48+
// outside this package (the list is vitest.repo-tests.json, which
49+
// check:cross-package-test-inputs holds equal to its own scan); `local` owns
50+
// every other test file. turbo hashes the wide `$TURBO_ROOT$` inputs on
51+
// `test:repo` only, so `test` stays cacheable across changes elsewhere in the
52+
// repo. `extends: true` keeps the root options (aliases included) on both.
53+
const REPO_TESTS: string[] = JSON.parse(readFileSync(path.join(__dirname, 'vitest.repo-tests.json'), 'utf8'));
4454

4555
export default defineConfig({
4656
test: {
57+
// Each project re-declares the root block's test options: a ROOT-level
58+
// value is inert for a project run (measured on vitest 4.1.10, see
59+
// check-registry-log-declared / check-console-intercept-disarm).
60+
projects: [
61+
{
62+
extends: true,
63+
test: {
64+
name: 'local',
65+
include: configDefaults.include,
66+
exclude: [...configDefaults.exclude, ...REPO_TESTS],
67+
// #13517: quiet the registry's per-item registration chatter — the
68+
// engine's own `OS_REGISTRY_LOG` seam, not a change to its shipped
69+
// default. Enforced by scripts/check-registry-log-declared.mjs.
70+
env: { OS_REGISTRY_LOG: 'warn' },
71+
// A late console.* must not redden a green suite (#10374); see the root
72+
// block. A ROOT-level value is inert for a project run, so it is
73+
// declared here as well (scripts/check-console-intercept-disarm.mjs).
74+
disableConsoleIntercept: true,
75+
},
76+
},
77+
{
78+
extends: true,
79+
test: {
80+
name: 'repo',
81+
include: REPO_TESTS,
82+
// #13517: quiet the registry's per-item registration chatter — the
83+
// engine's own `OS_REGISTRY_LOG` seam, not a change to its shipped
84+
// default. Enforced by scripts/check-registry-log-declared.mjs.
85+
env: { OS_REGISTRY_LOG: 'warn' },
86+
// A late console.* must not redden a green suite (#10374); see the root
87+
// block. A ROOT-level value is inert for a project run, so it is
88+
// declared here as well (scripts/check-console-intercept-disarm.mjs).
89+
disableConsoleIntercept: true,
90+
},
91+
},
92+
],
4793
// A late console.* must not redden a green suite (#10374): vitest's worker
4894
// forwards console output over RPC and discards the promise, and a write
4995
// landing after teardown's rpcDone() snapshot is rejected into an unhandled
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[
2+
"src/action-owner-key-single-source.test.ts"
3+
]

‎packages/rest/package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"scripts": {
2222
"build": "tsup --config ../../tsup.config.ts && node ../../scripts/check-dts-emitted.mjs",
2323
"dev": "tsc -w",
24-
"test": "vitest run",
24+
"test": "vitest run --project local",
25+
"test:repo": "vitest run --project repo",
2526
"check:test-typecheck": "tsx ../../scripts/check-test-typecheck.mts --self-test && tsx ../../scripts/check-test-typecheck.mts --package packages/rest --project tsconfig.test.json",
2627
"gen:test-typecheck-debt": "tsx ../../scripts/check-test-typecheck.mts --update --package packages/rest --project tsconfig.test.json",
2728
"typecheck": "tsc --noEmit && pnpm check:test-typecheck"

‎packages/rest/vitest.config.ts‎

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,57 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

3-
import { defineConfig } from 'vitest/config';
3+
import { configDefaults, defineConfig } from 'vitest/config';
4+
import { readFileSync } from 'node:fs';
45
import path from 'path';
56

7+
// #16466 -- two vitest projects, two turbo tasks. `repo` owns the tests that read
8+
// outside this package (the list is vitest.repo-tests.json, which
9+
// check:cross-package-test-inputs holds equal to its own scan); `local` owns
10+
// every other test file. turbo hashes the wide `$TURBO_ROOT$` inputs on
11+
// `test:repo` only, so `test` stays cacheable across changes elsewhere in the
12+
// repo. `extends: true` keeps the root options (aliases included) on both.
13+
const REPO_TESTS: string[] = JSON.parse(readFileSync(path.join(__dirname, 'vitest.repo-tests.json'), 'utf8'));
14+
615
export default defineConfig({
716
test: {
17+
// Each project re-declares the root block's test options: a ROOT-level
18+
// value is inert for a project run (measured on vitest 4.1.10, see
19+
// check-registry-log-declared / check-console-intercept-disarm).
20+
projects: [
21+
{
22+
extends: true,
23+
test: {
24+
name: 'local',
25+
include: configDefaults.include,
26+
exclude: [...configDefaults.exclude, ...REPO_TESTS],
27+
globals: true, environment: 'node',
28+
// #13517: quiet the registry's per-item registration chatter — the
29+
// engine's own `OS_REGISTRY_LOG` seam, not a change to its shipped
30+
// default. Enforced by scripts/check-registry-log-declared.mjs.
31+
env: { OS_REGISTRY_LOG: 'warn' },
32+
// A late console.* must not redden a green suite (#10374); see the root
33+
// block. A ROOT-level value is inert for a project run, so it is
34+
// declared here as well (scripts/check-console-intercept-disarm.mjs).
35+
disableConsoleIntercept: true,
36+
},
37+
},
38+
{
39+
extends: true,
40+
test: {
41+
name: 'repo',
42+
include: REPO_TESTS,
43+
globals: true, environment: 'node',
44+
// #13517: quiet the registry's per-item registration chatter — the
45+
// engine's own `OS_REGISTRY_LOG` seam, not a change to its shipped
46+
// default. Enforced by scripts/check-registry-log-declared.mjs.
47+
env: { OS_REGISTRY_LOG: 'warn' },
48+
// A late console.* must not redden a green suite (#10374); see the root
49+
// block. A ROOT-level value is inert for a project run, so it is
50+
// declared here as well (scripts/check-console-intercept-disarm.mjs).
51+
disableConsoleIntercept: true,
52+
},
53+
},
54+
],
855
// A late console.* must not redden a green suite (#10374): vitest's worker
956
// forwards console output over RPC and discards the promise, and a write
1057
// landing after teardown's rpcDone() snapshot is rejected into an unhandled

0 commit comments

Comments
 (0)