test: make publish-all exercise the bundles it ships, and gate the dist target - #817
Merged
sroussey merged 1 commit intoAug 16, 2026
Conversation
Coverage Report
File CoverageNo changed files found. |
sroussey
force-pushed
the
claude/coverage-dist-bundle-fix-ew0vj8
branch
from
August 16, 2026 16:34
758c0b2 to
27b4958
Compare
…st target
Every vitest project now attaches the source-resolving plugin unconditionally,
so under the default target nothing resolves `@workglow/*` through `exports`.
`publish-all`'s test step therefore stopped touching the bundles it is about to
version-bump and push, and `WORKGLOW_TEST_TARGET=dist` existed only as an inline
`env:` block on one CI job.
- `test:vitest:dist` is the one definition of the dist target, unit tier only
(matching the CI job; the other tiers want keys, databases and model
downloads). The variable is set INSIDE the script, so dropping it now means
deleting the script call.
- `publish-all` runs it after `rebuild`/`format` and before `bunset`.
- The `test-vitest-dist` job invokes the script instead of restating the
variable.
The dist run also had no precondition. `use-source` writes stubs carrying
`SOURCE_STUB_SENTINEL` and nothing read it, so under a stubbed dist
`@workglow/ai` and `@workglow/ai/worker` collapse onto one source module: every
cross-entry `instanceof` succeeds trivially and export-name parity compares a
file with itself. `assertNoSourceStubs` now runs at CONFIG LOAD under the dist
target, which kills the whole run before any suite can pass vacuously.
`containsSourceStubSentinel` is the node-portable half of the existing Bun-only
`isSourceStub`, since vitest.config.ts is loaded by Vite under node.
`shared.env` hands the validated target down to the workers: `packages/test` is
a composite program rooted at ./src and cannot import scripts/lib/*, so
re-deriving it there would reintroduce the silent-comparison bug
`resolveTestTarget` exists to remove.
`scripts/` was in no CI type gate — `typecheck:budget` globs packages|providers
and `typecheck:tests` globs packages/*/tsconfig.test.json — while now holding
vitest.config.ts's resolution logic. `tsconfig.scripts.json` + `typecheck:scripts`
close that, and the first run surfaced four real errors, all fixed here:
three `WorkspacePackage` literals missing the required `publishes`, a
`TestProjectConfiguration` callback annotation that ignores the union's string
variant, a missing root `vite` devDependency behind
`import type { Plugin } from "vite"`, and a `coverage.root` key that vitest 4
neither types nor reads (its provider derives coverage roots from the resolved
project configs), so it was inert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lgxtp7mQECdh7F2UT9CVwN
sroussey
force-pushed
the
claude/optimistic-goldberg-d74u5n-publish-tests-bundles
branch
from
August 16, 2026 16:37
5c5071c to
7014948
Compare
sroussey
merged commit Aug 16, 2026
7014948
into
claude/coverage-dist-bundle-fix-ew0vj8
11 of 12 checks passed
sroussey
deleted the
claude/optimistic-goldberg-d74u5n-publish-tests-bundles
branch
August 24, 2026 18:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked fix onto #741 (
claude/coverage-dist-bundle-fix-ew0vj8), which is the base of this PR — notmain. Review/merge #741 first.HIGH —
publish-allno longer tests the artifacts it publishesBefore #741, every vitest run resolved
@workglow/*throughexportsintodist, sopublish-all'srebuild && format && test vitestexercised the bundles it was about to version-bump and push. #741 attaches the source-resolution plugin to every project unconditionally under the default target, so that step now exercisessrconly — andWORKGLOW_TEST_TARGET=distexisted solely as an inlineenv:block on one CI job. There was no script exposing the dist target at all, andpublish-allwas not updated. The three newPublishedEntry*.test.tsfiles document themselves as vacuous under the source target.test:vitest:dist—WORKGLOW_TEST_TARGET=dist bun scripts/test.ts vitest unit. Unit tier only, matching what the CI job runs: the integration/rag/provider tiers want API keys, databases and multi-GB model downloads, which is not what a bundle-wiring check needs. The variable is set inside the script, not by the caller — that is what makes it impossible for a workflow edit to silently drop it.publish-allruns it afterrebuild/formatand beforebunset, so the bundles under test are the bundles about to be tagged and pushed. The existingbun run test viteststays.test-vitest-distintest.ymldrops its inlineenv:block and callsbun run test:vitest:dist. One definition of "the dist target", shared by CI and publish.test:vitest:all— that fans seven suites out concurrently and merges coverage fragments; the dist pass emits none (scripts/test.tsskips--coveragewhen targeting dist).MEDIUM — the dist run had no self-verification and ignored the source-stub sentinel
use-sourcewrites stubs carryingSOURCE_STUB_SENTINEL(scripts/lib/sourceStubs.ts) and nothing here read it. Under a stubbeddist,@workglow/aiand@workglow/ai/workercollapse onto one source module: every cross-entryinstanceofsucceeds trivially and export-name parity compares a file with itself. The run stays green and covers nothing.containsSourceStubSentinel(file)— a node-portable (node:fs) sentinel probe. The existingisSourceStubusesBun.fileand is therefore Bun-only, unusable fromvitest.config.ts, which Vite loads under node. The async helper now delegates to it, sopublish-workspaces.tskeeps working unchanged and the two can never disagree about what a stub is.assertNoSourceStubs(packages)— walks each package'sexportsdist targets and throws one aggregated error naming every offender, pointing atbun run use-dist. A developer who ranuse-sourcehas stubbed all 39 packages; failing on the first would take 39 fix-and-rerun cycles to learn one fact.vitest.config.tskeeps the resolved target in a const and calls it at config load underdist. Failing there rather than in a test is deliberate: it kills the whole run before any suite can pass vacuously, and it covers the export-parity sweep too, which a test-shaped guard could only protect by being imported into every file it defends.shared.env = { WORKGLOW_TEST_TARGET: target }hands the validated value to the workers.packages/testis a composite program rooted at./srcand cannot importscripts/lib/*(which is why the threePublishedEntryfiles duplicate their derivations), so re-implementing the=== "dist"comparison there would reintroduce exactly the silent-typo bugresolveTestTargetexists to remove.Note on what cannot be asserted. No in-process check can distinguish "the job meant source" from "the env block was deleted":
resolveTestTarget(undefined)returns"source", so a target-keyed assertion just flips branches and stays green. The only fix is structural — the variable is now set bytest:vitest:distitself, so deleting it requires deleting the script call, which the wiring guard below catches.MEDIUM —
scripts/is outside every CI type gatetypecheck:budgetglobspackages|providersandtypecheck:testsglobspackages/*/tsconfig.test.json, so nothing typecheckedscripts/— now home tovitest.config.ts's resolution logic, and already carrying real errors.tsconfig.scripts.jsonat the root (notscripts/tsconfig.json, which risks being swept up by a future*/tsconfig.jsonglob):include: ["scripts/**/*.ts", "vitest.config.ts"],composite: false,incremental: false,noEmit: true,allowImportingTsExtensions: true. The last is required rather than cosmetic —workspaceSource.tsimports./workspaceGroups.tsandvitest.config.tsimports./scripts/lib/*.tswith explicit extensions (Vite's native config loader needs them), which is TS5097 without it; legal here becausenoEmitis set.typecheck:scripts(tsgo, the same binarytypecheck:testsuses) plus a step in thetypecheck-budgetjob beside "Typecheck co-located tests".The first run surfaced four real errors, all fixed here:
WorkspacePackagegained a requiredreadonly publishesin #741; three annotated literals inscripts/workspaceSource.test.tsomit itpublishes: truescripts/testDiscovery.test.tsannotates a.mapcallback as{ test: { root: string } }, butTestProjectConfigurationalso admits a glob stringimport type { Plugin } from "vite"with no rootvitedevDependency (it exists only nested under vitest)viteto root devDependenciescoverage.rootcoverage.rootwas inert. Vitest 4 neither types it nor reads it:BaseCoverageProviderderives the roots it globs fromctx.config.root/ the resolved project configs, never from the coverage block (this.roots = ctx.config.project?.length ? ... : [ctx.config.root]). Removing it is behaviour-neutral. What actually makes the repo-relativeincludeglobs work from a package directory ispm.isMatch(..., { contains: true }), which the comment now says.Out of scope, noted for a follow-up:
eslint.config.jsalso scopes to{packages,providers,examples}/**, soscripts/is unlinted as well.Tests
scripts/publishPipeline.test.ts(new) — a dependency-free wiring guard reading the raw rootpackage.jsonand.github/workflows/test.ymlas text, because the question is whether the shell command a human reads names the script, and because asserting the absence of a YAML key is what a text read does well:test:vitest:distexists and its command containsWORKGLOW_TEST_TARGET=distpublish-allcontainstest:vitest:dist, beforebunsettest.ymlcontainsbun run test:vitest:distand no bareWORKGLOW_TEST_TARGET:YAML keytest:vitest:alldoes not contain itMeasured on the base commit: 3 of 4 fail, the fourth passing only because the script did not exist.
scripts/workspaceSource.test.ts— three cases drivingassertNoSourceStubsovermkdtempSyncfixtures: a dist file containing the sentinel throws and names the file anduse-dist; a real-looking bundle and anexportsentry that was never built both pass; two stubbed packages are both named in one message.Verification (actual output)
Generated by Claude Code