diff --git a/docs/contributing.md b/docs/contributing.md index f97cec31a2..dbbb049ad6 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -94,7 +94,7 @@ GitHub Actions runs deterministic test sharding via `pnpm test:ci:shard --shard - `pnpm test:full` remains the explicit full workspace suite; dashboard exhaustive coverage is explicit via `pnpm --filter @fusion/dashboard test:deep`. - `pnpm verify:workspace` remains the deep opt-in lint -> test -> build verification. -`test:ci:shard` is a CI-focused entrypoint (`scripts/ci-test-shard.mjs`) that deterministically balances workspace packages with `test` scripts by counting package-local `**/__tests__/**/*.test.{ts,tsx,mjs}` files, auto-splitting oversized packages into virtual shard entries (`{ name, shardIndex, shardCount }`), then assigning entries in descending weight order with best-fit placement for unsplit entries (closest under-budget fit, otherwise minimum overshoot) while keeping slices of the same package on different shards when possible. Whole entries run as grouped `pnpm --filter test` calls, and virtual entries run one-by-one via `pnpm --filter test -- --shard /`. This keeps coverage reproducible while improving shard balance. +`test:ci:shard` is a CI-focused entrypoint (`scripts/ci-test-shard.mjs`) that deterministically balances workspace packages with `test` scripts by counting package-local `**/__tests__/**/*.test.{ts,tsx,mjs}` files, auto-splitting oversized packages into virtual shard entries (`{ name, shardIndex, shardCount }`), then assigning entries in descending weight order with best-fit placement for unsplit entries (closest under-budget fit, otherwise minimum overshoot) while keeping slices of the same package on different shards when possible. Whole entries run as grouped `pnpm --filter test` calls, and virtual entries run one-by-one via `pnpm --filter test --shard /` (no bare `--`, because Vitest's cac parser would otherwise treat the shard flag as a filter separator). This keeps coverage reproducible while improving shard balance. `pnpm test` now uses a changed-only entrypoint (`scripts/test-changed.mjs`) for faster local iteration. It resolves the comparison base from `.changeset/config.json` (`baseBranch`) and runs only affected workspaces from `pnpm-workspace.yaml` (both `packages/*` and `plugins/**`) using safe package-first filtering (`pnpm --filter test`). It runs the merge-gate suite first, then the affected set. The full suite runs only on explicit opt-in (`--full` / `pnpm test:full`); shared-infrastructure changes and unresolvable diffs widen the affected set but never escalate to an implicit full-suite run (the old escalation was the local OOM path). diff --git a/packages/cli/package.json b/packages/cli/package.json index 96d132ad9a..b32d608e1f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -51,6 +51,7 @@ "typecheck": "tsc --noEmit", "test": "vitest run --silent=passed-only --reporter=dot", "test:ci-shape": "vitest run src/__tests__/ci-workflow.test.ts --silent=passed-only --reporter=dot", + "test:docs-index": "vitest run src/__tests__/docs-readme-index.test.ts --silent=passed-only --reporter=dot", "test:slow-cli": "cross-env FUSION_TEST_SLOW_CLI=1 vitest run src/commands/__tests__/agent-export.test.ts --silent=passed-only --reporter=dot", "test:extension-integration": "cross-env FUSION_TEST_EXTENSION_INTEGRATION=1 vitest run src/__tests__/extension-integration.test.ts --silent=passed-only --reporter=dot", "test:build-exe": "cross-env FUSION_TEST_BUILD_EXE=1 vitest run --config vitest.build-exe.config.ts --silent=passed-only --reporter=dot", diff --git a/packages/cli/src/__tests__/package-config.test.ts b/packages/cli/src/__tests__/package-config.test.ts index 3d34449432..8e318a504b 100644 --- a/packages/cli/src/__tests__/package-config.test.ts +++ b/packages/cli/src/__tests__/package-config.test.ts @@ -93,6 +93,26 @@ describe("CLI package.json publishing config", () => { expect(deps).toContain("ioredis"); }); + it("defines test:docs-index as a single-file docs README index lane", () => { + const script = pkg.scripts?.["test:docs-index"]; + const parts = script?.trim().split(/\s+/) ?? []; + const docsIndexPath = "src/__tests__/docs-readme-index.test.ts"; + + expect(script).toBeDefined(); + expect(script).toContain("vitest run"); + expect(parts).toEqual([ + "vitest", + "run", + docsIndexPath, + "--silent=passed-only", + "--reporter=dot", + ]); + expect(parts.filter((part) => part.endsWith(".test.ts"))).toEqual([docsIndexPath]); + expect(parts).not.toContain("--"); + expect(script).not.toMatch(/vitest\s+run\s+(?:--silent=passed-only\s+)?(?:--reporter=dot\s+)?$/); + expect(script).not.toContain("docs-readme-index "); + }); + it("prepack manifest rewrite strips workspace-only plugin/tooling devDependencies", () => { expect(prepackScript).toContain('delete devDependencies["@fusion/pi-claude-cli"]'); expect(prepackScript).toContain('delete devDependencies["@fusion/pi-llama-cpp"]'); @@ -276,17 +296,18 @@ describe("Workspace bootstrap script contract", () => { const defaultTest = dashboardPkg.scripts?.test; const defaultAppQuality = dashboardPkg.scripts?.["test:quality:app"]; const defaultApiQuality = dashboardPkg.scripts?.["test:quality:api"]; + const appSettings = dashboardPkg.scripts?.["test:quality:app:settings"]; const apiCurated = dashboardPkg.scripts?.["test:quality:api:curated"]; const deepTest = dashboardPkg.scripts?.["test:deep"]; - expect(defaultTest).toBe("pnpm run test:quality:app && pnpm run test:quality:api"); - expect(defaultAppQuality).toContain("test:quality:app:foundation-api"); - expect(defaultAppQuality).toContain("test:quality:app:settings"); - // The api lane chains curated + backfill sub-lanes; the curated sub-lane - // carries the explicit quality project, and the backfill lane is the - // curated-gate completeness net (broad glob minus curated minus skip-list). - expect(defaultApiQuality).toContain("test:quality:api:curated"); - expect(defaultApiQuality).toContain("test:quality:api:backfill"); + expect(defaultTest).toBe("node scripts/run-quality-tests.mjs"); + expect(defaultAppQuality).toBe("node scripts/run-quality-tests.mjs --group app"); + expect(defaultApiQuality).toBe("node scripts/run-quality-tests.mjs --group api"); + expect(defaultAppQuality).toContain("--group app"); + expect(appSettings).toContain("dashboard-app-quality-settings"); + // The default quality runner dispatches grouped quality lanes by script + // name; the curated API sub-lane still carries the explicit quality project. + expect(defaultApiQuality).toContain("--group api"); expect(hasProjectArg(apiCurated, "dashboard-api-quality")).toBe(true); expect(hasProjectArg(defaultTest, "dashboard-app")).toBe(false); expect(hasProjectArg(defaultTest, "dashboard-api")).toBe(false);