ci, build: type-check tests, build the playground, and rebuild conformance - #299
Merged
Merged
Conversation
Contributor
|
Since the packages build from tsconfig.build.json, which excludes tests, nothing type-checked the test files, the test/ helpers, or pointers' example runner. Each package now has a tsconfig.typecheck.json that extends its base config with noEmit and without composite or incremental, so it checks everything the base config includes and writes nothing into dist/. A typecheck script runs it per package, root `yarn typecheck` runs all of them through Lerna, and CI runs that once in the lint job. Dependencies are checked as live source, not as built declarations. The typecheck config sets rootDir to the repository root and maps each @ethdebug/* dependency in the package's closure to that package's src/index.ts through paths. The package's own # aliases are deliberately left out of paths: # imports in every file, including pulled-in dependency source, resolve through the nearest package.json imports map under nodenext, which takes the types condition pointing at src/. That avoids alias collisions across packages (#machine exists in both evm and pointers). bugc's imports map gains the types conditions the other packages already had, and programs-react's gain .ts and .tsx fallbacks. TypeScript falls through from a missing types target to default without a diagnostic, which would silently send one alias back to stale dist declarations. bin/check-typecheck-sources.ts lists every typecheck program's files and fails on any dist/ or node_modules/@ethdebug path; CI runs it after the type-check. Because dependency source compiles under the dependent's options, per-package strictness must stay uniform; tsconfig.base.json says so. pointers' base config gains an exclude for node_modules and dist, matching its siblings.
Root `yarn build` used `lerna run build --no-private`, which skips conformance now that it is private, so its dist/ was built only by postinstall. Ignore the two packages that are not libraries by name instead, and give conformance a clean build script like the others.
The playground imports bugc-react's stylesheets from dist/ and no workflow built it, so a broken path went unnoticed. A build-playground job mirrors build-web. It also runs the root `yarn build` first, so a break in any package's build is caught here, not only in build-web.
bugc-react and pointers-react were not in the watch set, and the React watch scripts only ran tsc, so stylesheet edits never reached dist/ and the playground that imports them. Each React watch now copies the stylesheets once, then runs tsc --watch alongside a nodemon watcher that re-copies CSS on change. bin/start uses bash explicitly; it already relied on bash syntax.
gnidan
force-pushed
the
build-ci-typecheck
branch
from
September 17, 2026 00:27
ba95428 to
5b1e974
Compare
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.
Test files stopped type-checking once packages started building from tsconfig.build.json, which excludes test/, .test.ts, and pointers' bin/. Add a tsconfig.typecheck.json to each of the eight packages (the seven public ones plus conformance), extending the base tsconfig.json (which already includes tests, colocated alongside src for most packages) with noEmit, composite: false, and incremental: false, so tsc runs a plain single-project check instead of a composite build and never writes into dist/. Plain
tsc -p tsconfig.json --noEmitstill updates dist/*.tsbuildinfo because composite requires incremental; dropping composite avoids that.Cross-package imports resolve through node_modules package boundaries (main/types fields), not through tsconfig paths pointing at sibling source, so TypeScript's project-reference source-redirect doesn't apply regardless of composite/declarationMap settings, and a check run that way reports on whatever each dependency's last build produced. Each tsconfig.typecheck.json therefore maps every @ethdebug/* package in its dependency closure to that package's src/index.ts and sets rootDir to the repo root so those sources sit inside it: every check now reads live source, with no dependency on build order or on dist/ being current. Those mappings replace the base config's
#alias paths rather than extending them, since a child paths map fully overrides the parent's - which is what we want, because one flat alias table cannot serve two packages that both define#machineor#types. Without paths for them,#specifiers resolve under nodenext through the nearest package.json imports map and pick up its types condition, pointing at src. That makes the types conditions load-bearing, so bugc's imports map, which listed only built files, gains them, and the wildcards in programs-react's map fall back to the other of .ts/.tsx. Build output is byte-identical: within a package, paths in its tsconfig.json already resolved these to the same sources. Because a dependency's source is now compiled under the dependent's compilerOptions, per-package strictness has to stay uniform; tsconfig.base.json says so at the top, and notes why format's exactOptionalPropertyTypes is harmless here.Add a typecheck script per package, a root typecheck that runs them via lerna (skipping only format-web and bug-playground, so conformance is included), and a Type-check step in CI, in lint-and-format so it runs once rather than once per Node version in the test matrix. A second CI step runs bin/check-typecheck-sources.ts, which lists each type-check program's files and fails if any of them sits in a packages/*/dist tree. TypeScript falls through from a missing types target to default with no diagnostic, so without that check a typo or a moved file would quietly send one alias back to built declarations.
Root build used --no-private, which skips conformance now that it's private. Its dist/ was then only produced by postinstall, so a plain yarn build after a clean checkout left it missing. Root build (and now typecheck) instead --ignore the two packages that have no dist to produce (format-web, bug-playground), and conformance gets a build script (rm -rf dist && tsc) matching its base-config build, since it has no tsconfig.build.json and ships nothing. CI's build-playground job now also runs the root yarn build directly, so a break in any package's build is caught there too, not just in build-web.
Nothing in CI ever built packages/playground, so a break in the Vite build, or in bugc-react's compiled CSS that the playground imports from dist/, would go unnoticed until someone ran it locally. Add a build-playground job mirroring build-web.
bin/start watched programs-react but never bugc-react or pointers-react, so editing either left the running playground stale now that it imports their compiled output from dist/. Add both to the watch set. Each of the three React packages' watch script now runs an initial CSS copy and then keeps copying continuously - concurrently running tsc --watch alongside nodemon re-running copyfiles on every src/**/*.css change - the same pattern format already uses for its schema YAMLs, instead of a one-shot copy at startup.