Skip to content

ci: a node_modules cache hit skips postinstall codegen, so every UI typecheck fails on 'collections/*' #9975

Description

@JSONbored

main has been red for four consecutive CI runs with nothing wrong in the tree.

The failure

src/lib/docs-client-loader.tsx(1,32): error TS2307: Cannot find module 'collections/browser'
src/lib/docs-client-loader.tsx(17,24): error TS7031: Binding element 'MDXContent' implicitly has an 'any' type
src/lib/docs-source.server.ts(1,22): error TS2307: Cannot find module 'collections/server'
npm error workspace @loopover/ui@0.0.0
npm error command sh -c tsc --noEmit

It hits validate-code on every PR regardless of what the PR changes — including a test-only PR that touches no UI file at all.

Root cause

.github/actions/setup-workspace restores a node_modules cache and, on a hit, skips npm ci entirely. Skipping npm ci skips every workspace lifecycle script — and apps/loopover-ui has "postinstall": "fumadocs-mdx", which generates .source/. That directory is what tsconfig.json maps collections/* onto:

"collections/*": ["./.source/*"]

.source/ is gitignored and is not among the cached paths (node_modules, apps/*/node_modules, packages/*/node_modules). So on a cache hit the UI typechecks against modules that do not exist.

Reproduced locally by simulating the cache-hit state — rm -rf apps/loopover-ui/.source with node_modules intact gives exactly the three errors above, and npm run postinstall --workspace @loopover/ui clears them.

Why it started when it did

The cache key includes the lockfile. A lockfile change mints a fresh key: the first run MISSES, installs, generates .source, passes, and saves the cache. Every run afterwards HITS and fails. That is the observed pattern — green through 507960134, then red from 40133d789 onward with no relevant change in between.

This is the same shape as the @eslint/js hoist bug the cache step's own comment already documents: "a failure that reproduces on no developer machine, because a real npm ci always creates those directories."

Fix

Run the codegen unconditionally, after the conditional install.

Regenerate rather than cache .source. Caching it looks like the smaller fix and is wrong: the cache key derives from manifests + lockfile, while .source derives from source.config.ts and content/docs/**. A cached copy would serve a docs collection generated from different MDX than the commit under test — a stale pass, which is worse than an honest failure.

Acceptance

  • A cache-hit run typechecks the UI successfully.
  • Adding a workspace lifecycle script in future does not silently reintroduce this.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions