fix(ci): align shared-auth build outputPath with tsconfig.lib.json outDir #209

Merged
julien merged 1 commits from fix/ci-shared-auth-output-path into main 2026-05-23 23:33:22 +02:00
Owner

Summary

pnpm ci:check was failing on main after #208 merged: portal-bff:build raised TS6305 Output file 'dist/out-tsc/libs/shared/auth/src/index.d.ts' has not been built from source file 'libs/shared/auth/src/index.ts' against every file in apps/portal-bff/src/auth/ that imports from shared-auth. Fresh CI runners hit it; my local runs masked it because a manual tsc --build during development had populated both candidate output dirs.

Root cause

When nx sync was first run for #206, it added a TypeScript project reference to apps/portal-bff/tsconfig.app.json:

"references": [{ "path": "../../libs/shared/auth" }]

portal-bff's build runs webpack with compiler: 'tsc' against that tsconfig, so tsc validates the referenced project's outputs exist at the location its tsconfig.lib.json declares as outDirdist/out-tsc/libs/shared/auth/.

But libs/shared/auth/project.json set outputPath: dist/libs/shared/auth and Nx's @nx/js:tsc executor honours its own outputPath over the tsconfig's outDir, emitting the declarations to dist/libs/shared/auth/ instead. tsc looks at the empty dist/out-tsc/libs/shared/auth/ location and fails with TS6305.

This was harmless until #208: the previous PRs only had a single import from shared-auth (in principal-builder.ts), and apparently tsc's incremental cache from the local dev box's pre-fix runs was reused in CI. #208 added enough new imports across enough files that the missing declarations became unavoidable.

What lands

File Change
libs/shared/auth/project.json outputPath: dist/libs/shared/authdist/out-tsc/libs/shared/auth. Aligns Nx's emit location with the tsconfig.lib.json's declared outDir, so the project-reference validation finds the declaration files.

One-line change, no other files touched.

Notes for the reviewer

  • Why this didn't show in the green CI on #206 / #208. Both PRs ran the same nx affected -t format:check lint test build recipe and both reported green. The likely explanation is that during PR-level runs Nx's distributed cache hit on the portal-bff:build task (the inputs included the source files but the cache stored the result of the build, which was green from an earlier successful run before the project reference landed). Post-merge runs on main evict the cache differently (different commit SHA → cache miss → tsc actually re-runs and hits the missing declarations).

  • Why shared-util, shared-tokens, etc. don't have the same problem. They share the exact same outputPath / outDir mismatch in their project.json + tsconfig.lib.json, but they're only consumed by the Angular SPAs (portal-shell, portal-admin). @angular/build does not validate TypeScript project references the same way webpack + compiler: 'tsc' does, so the mismatch sits silently. shared-auth is the first lib in the workspace that crosses into portal-bff, which is why the trap surfaced now.

  • Alternative considered: drop the project reference in portal-bff/tsconfig.app.json. Path aliases in tsconfig.base.json resolve shared-auth to source files directly, so webpack would still find the imports. Rejected because nx sync adds project references back automatically — the alignment-of-paths fix is more durable than a configuration deletion.

  • Why not align the other shared libs preemptively. They aren't broken — their project references aren't being validated. Touching them in the same PR would expand the diff for zero current benefit. The pattern documented here is what the next lib that's consumed by portal-bff will need; the precedent is on the books.

  • Locally reproducible. pnpm nx reset && rm -rf dist .nx/cache .nx/workspace-data && pnpm ci:check reproduces the original failure on the previous commit and passes on this commit.

Test plan

  • pnpm nx reset && rm -rf dist .nx/cache .nx/workspace-data && pnpm nx affected -t format:check lint test build --base=main --skip-nx-cache — 3 projects green from a fully cold state.
  • Post-merge CI on main runs through pnpm ci:check cleanly.
## Summary `pnpm ci:check` was failing on `main` after #208 merged: `portal-bff:build` raised `TS6305 Output file 'dist/out-tsc/libs/shared/auth/src/index.d.ts' has not been built from source file 'libs/shared/auth/src/index.ts'` against every file in `apps/portal-bff/src/auth/` that imports from `shared-auth`. Fresh CI runners hit it; my local runs masked it because a manual `tsc --build` during development had populated both candidate output dirs. ## Root cause When `nx sync` was first run for #206, it added a TypeScript project reference to `apps/portal-bff/tsconfig.app.json`: ```json "references": [{ "path": "../../libs/shared/auth" }] ``` `portal-bff`'s build runs webpack with `compiler: 'tsc'` against that tsconfig, so tsc validates the referenced project's outputs exist at the location its tsconfig.lib.json declares as `outDir` — `dist/out-tsc/libs/shared/auth/`. But `libs/shared/auth/project.json` set `outputPath: dist/libs/shared/auth` and Nx's `@nx/js:tsc` executor honours its own `outputPath` over the tsconfig's `outDir`, emitting the declarations to `dist/libs/shared/auth/` instead. tsc looks at the empty `dist/out-tsc/libs/shared/auth/` location and fails with TS6305. This was harmless until #208: the previous PRs only had a single `import` from `shared-auth` (in `principal-builder.ts`), and apparently tsc's incremental cache from the local dev box's pre-fix runs was reused in CI. #208 added enough new imports across enough files that the missing declarations became unavoidable. ## What lands | File | Change | | --- | --- | | `libs/shared/auth/project.json` | `outputPath: dist/libs/shared/auth` → `dist/out-tsc/libs/shared/auth`. Aligns Nx's emit location with the tsconfig.lib.json's declared `outDir`, so the project-reference validation finds the declaration files. | One-line change, no other files touched. ## Notes for the reviewer - **Why this didn't show in the green CI on #206 / #208.** Both PRs ran the same `nx affected -t format:check lint test build` recipe and both reported green. The likely explanation is that during PR-level runs Nx's distributed cache hit on the `portal-bff:build` task (the inputs included the source files but the cache stored the *result* of the build, which was green from an earlier successful run before the project reference landed). Post-merge runs on `main` evict the cache differently (different commit SHA → cache miss → tsc actually re-runs and hits the missing declarations). - **Why `shared-util`, `shared-tokens`, etc. don't have the same problem.** They share the exact same outputPath / outDir mismatch in their project.json + tsconfig.lib.json, but they're only consumed by the Angular SPAs (`portal-shell`, `portal-admin`). `@angular/build` does not validate TypeScript project references the same way `webpack + compiler: 'tsc'` does, so the mismatch sits silently. `shared-auth` is the first lib in the workspace that crosses into `portal-bff`, which is why the trap surfaced now. - **Alternative considered: drop the project reference in `portal-bff/tsconfig.app.json`.** Path aliases in `tsconfig.base.json` resolve `shared-auth` to source files directly, so webpack would still find the imports. Rejected because `nx sync` adds project references back automatically — the alignment-of-paths fix is more durable than a configuration deletion. - **Why not align the other shared libs preemptively.** They aren't broken — their project references aren't being validated. Touching them in the same PR would expand the diff for zero current benefit. The pattern documented here is what the next lib that's consumed by `portal-bff` will need; the precedent is on the books. - **Locally reproducible.** `pnpm nx reset && rm -rf dist .nx/cache .nx/workspace-data && pnpm ci:check` reproduces the original failure on the previous commit and passes on this commit. ## Test plan - [x] `pnpm nx reset && rm -rf dist .nx/cache .nx/workspace-data && pnpm nx affected -t format:check lint test build --base=main --skip-nx-cache` — 3 projects green from a fully cold state. - [ ] Post-merge CI on `main` runs through `pnpm ci:check` cleanly.
julien added 1 commit 2026-05-23 23:33:07 +02:00
fix(ci): align shared-auth build outputPath with tsconfig.lib.json outDir
CI / commits (pull_request) Successful in 2m44s
CI / check (pull_request) Successful in 3m15s
CI / scan (pull_request) Failing after 3m23s
CI / a11y (pull_request) Successful in 3m33s
CI / perf (pull_request) Successful in 7m44s
e055578142
portal-bff/tsconfig.app.json declares a TypeScript project reference
to libs/shared/auth, so when webpack runs tsc against that tsconfig
it validates that the referenced project's declarations exist at the
location libs/shared/auth/tsconfig.lib.json declares as outDir
(dist/out-tsc/libs/shared/auth). But nx's @nx/js:tsc executor was
emitting them to dist/libs/shared/auth (the project.json outputPath),
so tsc fails with TS6305 "Output file ... has not been built".

The mismatch was harmless locally because a manual `tsc --build`
during development populated both directories. Fresh CI runners
only run nx's executor, so only one directory was populated.

Aligning outputPath to dist/out-tsc/libs/shared/auth makes both
agree. shared-auth is the first lib in the workspace that's
consumed by portal-bff in a way that triggers tsc project-reference
validation; the SPA-targeted libs (shared-util, shared-tokens)
ride the same mismatch but don't hit it because the Angular build
pipeline doesn't validate project references the same way.
julien merged commit 5f1ef2444a into main 2026-05-23 23:33:22 +02:00
julien deleted branch fix/ci-shared-auth-output-path 2026-05-23 23:33:24 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#209