diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba346d75a..8eaf61799 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -889,6 +889,9 @@ jobs: # matches the pattern already used by "Save Turborepo cache"/"Save TypeScript incremental build # cache" elsewhere in this file: still run after an earlier step's failure, just not after the job # was cancelled outright. The job as a whole still fails if any of the three fails. + - name: UI tests (ui-kit) + if: ${{ !cancelled() && (github.event_name == 'push' || needs.changes.outputs.ui == 'true') }} + run: npm --workspace @loopover/ui-kit run test - name: UI tests (ui) if: ${{ !cancelled() && (github.event_name == 'push' || needs.changes.outputs.ui == 'true') }} run: npm --workspace @loopover/ui run test diff --git a/package.json b/package.json index 8aed08f85..96771d876 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "db:migrations:immutable:check": "tsx scripts/check-released-migrations-immutable.ts", "turbo-inputs:check": "tsx scripts/check-turbo-typecheck-inputs.ts", "typecheck-coverage:check": "tsx scripts/check-typecheck-coverage.ts", + "test-wiring:check": "tsx scripts/check-test-coverage-wiring.ts", "fixture-clock-races:check": "tsx scripts/check-fixture-clock-races.ts", "workspace-dep-ranges:check": "tsx scripts/check-workspace-dep-ranges.ts", "db:schema-drift:check": "tsx scripts/check-schema-drift.ts", @@ -73,7 +74,7 @@ "ui:lint": "npm run ui:kit:build && npm --workspace @loopover/ui-kit run format:check && npm --workspace @loopover/ui run format:check && npm --workspace @loopover/ui run lint && npm --workspace @loopover/ui-miner run format:check && npm --workspace @loopover/ui-miner run lint", "ui:typecheck": "npm run ui:kit:build && npm --workspace @loopover/ui-kit run typecheck && npm --workspace @loopover/ui run typecheck && npm --workspace @loopover/ui-miner run typecheck", "preui:test": "npm run check-node-version", - "ui:test": "npm run ui:kit:build && npm --workspace @loopover/ui run test && npm --workspace @loopover/ui-miner run test", + "ui:test": "npm run ui:kit:build && npm --workspace @loopover/ui-kit run test && npm --workspace @loopover/ui run test && npm --workspace @loopover/ui-miner run test", "ui:openapi": "tsx scripts/write-ui-openapi.ts", "ui:openapi:check": "tsx scripts/write-ui-openapi.ts --check", "control-plane:contract": "tsx scripts/gen-control-plane-contract.ts", @@ -148,7 +149,7 @@ "test:smoke:browser:install": "playwright install chromium", "test:smoke:browser": "node --experimental-strip-types scripts/smoke-ui-browser.ts", "pretest:ci": "npm run check-node-version", - "test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:migrations:immutable:check && npm run turbo-inputs:check && npm run workspace-dep-ranges:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run validate:mcp && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:contract-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run control-plane:contract:check && npm run control-plane:openapi:check && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run import-specifiers:check && npm run ui-derived-types:check && npm run server-manifest:check && npm run dead-source-files:check && npm run dead-exports:check && npm run publishable-deps:check && npm run fixture-clock-races:check && npm run typecheck-coverage:check && npm run checkers-wired:check && npm run focus-manifest-fields:check && npm run release-commit-parsing:check && npm run releasable-commit-types:check && npm run regate-sort-key:check && npm run maintainer-associations:check && npm run command-redelivery-guards:check && npm run dispatch-gate-reasons:check && npm run validate:no-hand-written-js && npm run replay-runner-manifest:check && npm run coco-dev-versions:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run release-linked-versions:check && npm run command-reference:check && npm run mcp:tool-reference:check && npm run mcp:client-config:check && npm run contract:api-schemas:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build", + "test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:migrations:immutable:check && npm run turbo-inputs:check && npm run workspace-dep-ranges:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run validate:mcp && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:contract-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run control-plane:contract:check && npm run control-plane:openapi:check && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run import-specifiers:check && npm run ui-derived-types:check && npm run server-manifest:check && npm run dead-source-files:check && npm run dead-exports:check && npm run publishable-deps:check && npm run fixture-clock-races:check && npm run typecheck-coverage:check && npm run test-wiring:check && npm run checkers-wired:check && npm run focus-manifest-fields:check && npm run release-commit-parsing:check && npm run releasable-commit-types:check && npm run regate-sort-key:check && npm run maintainer-associations:check && npm run command-redelivery-guards:check && npm run dispatch-gate-reasons:check && npm run validate:no-hand-written-js && npm run replay-runner-manifest:check && npm run coco-dev-versions:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run release-linked-versions:check && npm run command-reference:check && npm run mcp:tool-reference:check && npm run mcp:client-config:check && npm run contract:api-schemas:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build", "test:release": "npm run test:ci && npm run changelog:check", "test:release:mcp": "npm run test:ci", "test:watch": "vitest", diff --git a/scripts/check-test-coverage-wiring.ts b/scripts/check-test-coverage-wiring.ts new file mode 100644 index 000000000..17b0c1d35 --- /dev/null +++ b/scripts/check-test-coverage-wiring.ts @@ -0,0 +1,129 @@ +#!/usr/bin/env node +// `npm run test:ci` must actually RUN every workspace's declared `test` script (#10049). +// +// THE INCIDENT. `packages/loopover-ui-kit` ships `"test": "vitest run"` and a package-local vitest.config.ts +// whose own header states the acceptance signal is "this suite runs and passes". Nothing invokes it: root +// `ui:test` builds ui-kit but only ever runs @loopover/ui and @loopover/ui-miner's tests, `test:ci` reaches +// ui-kit only through build/pack/lint/typecheck steps, and ci.yml has no ui-kit test step. The suite's 12 +// files (60+ tests) have sat there, never executed, since #7437/#7495 added them. +// +// That is the exact shape #9860 named: not a MISSING check, but a SILENTLY PARTIAL one -- trusted precisely +// because everything around it (build, pack, lint, typecheck) is green. #9860's own fix for this class was +// `scripts/check-typecheck-coverage.ts`, which proved `npm run typecheck` reaches every workspace that +// declares one. This is that same computation for `test`. +// +// WHAT THIS COMPUTES. Every workspace under apps/*/packages/* that declares its own `test` script, and +// whether the root `test:ci` chain reaches it -- following `npm run