ci: repair the project-reference wiring and add a CI workflow - #96
Merged
Conversation
Follow-up to #94/#95. Investigating the stale-`dist` trap turned up two larger problems than the one I set out to fix. **`npm run lint` was broken in every workspace that references another.** `tsc -b --noEmit` is invalid when a referenced composite project must emit (TS6310), so `extension` and `pwa` failed the moment the command ran. Only `build` ever typechecked anything. Lint is now plain `tsc -b` across all four workspaces — the leaf tsconfigs already set `noEmit`, so they still emit nothing but `.tsbuildinfo` while their references build properly. **`core` had no project reference to `tsp-js`,** despite importing it and typechecking against its emitted `dist`. `tsc -b` therefore had no idea it must build tsp-js first, and a missing dist surfaced as "cannot find module @openvtc/vti-tsp-js" inside core's own source — a build-order problem wearing a code-bug costume. This is the same failure that cost time on #94 one level down, and unlike that one it could not self-heal. Added the reference, plus the missing tsp-js entry in the root solution tsconfig. **There was no CI at all** — no `.github/workflows`. Neither build, lint nor tests ran on a PR; DCO was the only check. Added a workflow running lint → build → test on Node 20 (the `engines` floor) and 22, from a cold checkout so the reference wiring above stays honest: if it regresses, CI fails rather than the next person's clone. It also asserts the MV3 invariant from #95 — that `dist/background.js` is a single bundle with no dynamic `import()`. A service worker cannot load one (w3c/ServiceWorker#1356), so losing Rollup's `codeSplitting: false` in a future upgrade would break the worker in users' browsers with a green build. Verified: every workspace lints from a cold tree individually and together, clean `npm run build`, 171/171 tests pass, and the full CI sequence re-run against a fresh `npm ci`. The bundle guard was checked against a planted `import()` to confirm it is not a vacuous grep. Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
This was referenced Aug 21, 2026
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.
Follow-up to #94/#95, closing the stale-
disttrap. Investigating it turned up two problems larger than the one I set out to fix.1.
npm run lintwas broken in every workspace that references anothertsc -b --noEmitis invalid when a referenced composite project must emit — TS6310. So:npm run lintbeforecoretsp-jsextensionpwaThe two packages that actually consume
corefailed the instant the command ran. Onlybuildwas ever typechecking anything. Lint is now plaintsc -bin all four; the leaf tsconfigs already setnoEmit, so they still emit nothing but.tsbuildinfowhile their references build properly.I should flag that I reported "lint clean" on #95 — that was wrong. I misread a
$pipestatusindex and read a failing command as passing. The lint failure predates #95, but I stated it was green without it being green.2.
corehad no project reference totsp-jscoreimports@openvtc/vti-tsp-jsand typechecks against its emitteddist, but declared no reference.tsc -bhad no idea it must build tsp-js first, so a missing dist surfaced asCannot find module '@openvtc/vti-tsp-js'inside core's own, entirely correct, source.This is the same failure that cost time on #94, one level further down — and unlike that one it could not self-heal, because no reference existed for
tsc -bto follow. Added it, plus the missingtsp-jsentry in the root solution tsconfig.3. There was no CI at all
No
.github/workflows. Neither build, lint, nor tests ran on a PR — DCO was the only check, which is why both problems above could sit there. Added a workflow running lint → build → test on Node 20 (theenginesfloor) and 22, from a cold checkout so the reference wiring stays honest: if it regresses, CI fails instead of the next person's clone.It also asserts the MV3 invariant from #95 —
dist/background.jsmust be a single bundle with no dynamicimport(). A service worker cannot load one (w3c/ServiceWorker#1356), so losing Rollup'scodeSplitting: falsein a future upgrade would break the worker in users' browsers behind a green build.Verification
npm run build— passnpm test— 171/171 (42 tsp-js + 129 core)npm ci— passimport()to confirm it catches one rather than being a vacuous grepNot verified: the workflow has never executed on GitHub Actions — this PR is its first run, so watch the checks here.
npm ciemitsallow-scriptswarnings (esbuild, @swc/core, cbor-extract) under npm 11; the full sequence passes with those scripts unrun, but if a runner behaves differently that's the likely spot.Pre-merge checklist
reqwest::Client::new()/ barefetch(); timeouts (R1.2) — no network code