Skip to content

fix(ci): make the website deployable on Netlify (monorepo config + build fixes)#24

Closed
dogmar wants to merge 8 commits into
mainfrom
fix/netlify-monorepo-build
Closed

fix(ci): make the website deployable on Netlify (monorepo config + build fixes)#24
dogmar wants to merge 8 commits into
mainfrom
fix/netlify-monorepo-build

Conversation

@dogmar

@dogmar dogmar commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Makes the website package build and deploy on Netlify's native build. Several independent problems were stacked; this PR fixes the config, and the investigation also surfaced two real bugs.

Root causes found & fixed

  1. Monorepo base directory. Netlify ran the build from the repo root, where there's no build script and publish resolved to <root>/dist/client. Now base = website, with package-relative publish/functions.
  2. Node version. Once the base is a subdir, Netlify stops reading the repo-root .node-version and fell back to Node 22. Pinned via website/.node-version = 24.14.1.
  3. vp hangs in Netlify's build container. vp run website#build stalls at the vite-build step until the 18-minute timeout. A marker-based diagnostic (running the steps directly via pnpm exec/vite@8) deploys cleanly in ~74s — proving the stall is specific to vp's orchestration, not the cache, Node, the Next.js runtime, the vite-plus version, or extract-api. Build command is now pnpm build (the website's own vite@8); vp stays the toolchain for local dev/CI.

Bonus bugs surfaced

  • scripts/extract-api.ts never called process.exit. It uses ts-morph, which keeps the TS program/host alive, so the process can hang on exit when stdout is piped (CI) rather than a TTY. Added process.exit(0) after the synchronous file write.
  • vite-plus 0.1.18 → 0.1.24 (latest) — tested as a hang fix; it wasn't, but it's a clean bump (local build + tests green). Can be split into its own PR if preferred.

Also fixed outside this PR (Netlify UI): a stale Next.js framework override was injecting @netlify/plugin-nextjs@4.41.6 into a TanStack Start site — removed.

Verification

  • Diagnostic deploy 83a7d3c: ready, 74s, 1 SSR function on Node 24; preview /demo returns 200 with the live app.
  • Local vp run website#build + vp run -r test: green.

🤖 Generated with Claude Code

The Netlify project is configured as a monorepo package (packagePath =
website), so Netlify reads website/netlify.toml but runs the build from the
repo root with base = root. The old `pnpm build` failed there because the
root package.json has no `build` script (it lives in website/), and
`publish = "dist/client"` resolved to <root>/dist/client.

Make the config root-cwd-aware instead of relying on a base directory:
- command: `vp run website#build` (vp resolves the workspace and runs the
  website build task; no base dir needed)
- publish/functions: repo-root-relative paths into website/

The website builds the library straight from `../package/src` (vite alias),
so no separate package build is required.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@netlify

netlify Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploy Preview for colander-cal ready!

Name Link
🔨 Latest commit 5538719
🔍 Latest deploy log https://app.netlify.com/projects/colander-cal/deploys/6a3084c23d38e500085f8da5
😎 Deploy Preview https://deploy-preview-24--colander-cal.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

dogmar and others added 7 commits June 15, 2026 13:39
The Netlify project's base directory is `website`, so the build runs with
cwd=website. The previous root-relative paths doubled up
(website/website/dist/client). Make publish/functions package-relative again.

Pin Node via website/.node-version (24.14.1): once the base directory is a
subdir, Netlify stops reading the repo-root .node-version and fell back to
Node 22, which the toolchain (engines >=24.14.1) doesn't support — the build
hung at `vite build` start.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Running the build through `vp run website#build` hangs in Netlify's build
container and hits the 18-minute timeout — `vite build` stalls at startup.
Under vp, `vite` resolves to the workspace-root vite (voidzero
vite-plus-core / rolldown) rather than the website's standard vite@8; that
variant builds fine locally but stalls in Netlify's container. `pnpm build`
runs the website's own vite@8 and builds cleanly.

Keep base=website, package-relative paths, and the Node 24 pin. vp is still
used for local dev and CI tasks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vite-plus / vite-plus-core / vite-plus-test bumped 0.1.18 → 0.1.24 (latest).
Local `vp run website#build` and `vp run -r test` pass.

Flip the Netlify build command back to `vp run website#build` to test whether
the newer vite-plus no longer hangs in Netlify's build container. If it still
hangs, revert this commit's netlify.toml change to `pnpm build` (verified
working).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conclusive after eliminating every other variable: `vp run website#build`
hangs in Netlify's build container at `vite build` even with a clean cache,
Node 24, the Next.js runtime removed, and vite-plus upgraded to 0.1.24.
`pnpm build` (the website's own vite@8) builds cleanly.

No orchestration is lost: `website#build` declares no vp `dependsOn` (empty
run.tasks graph) and the site imports @klinking/colander from source, so
there are no build deps to order. vp stays for local dev/CI.

Keeping the vite-plus 0.1.24 bump from the prior commit (latest; local
build + tests green) even though it didn't resolve the Netlify hang.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
scripts/extract-api.ts uses ts-morph, which keeps the TypeScript program /
host alive, so the Node process never exits once its work is done. On a local
TTY it happens to drain and exit, but piped into Netlify's build log it hangs
on exit — stalling the `tsx scripts/extract-api.ts && vite build` chain right
after it logs "Wrote N symbols". That matches every stalled Netlify build, and
explains why it looked like a vp-vs-pnpm difference (we never actually got a
green build with either). Add process.exit(0) after the synchronous file write.

With the script exiting deterministically, restore `vp run website#build` as
the Netlify build command to confirm the task graph now builds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Temporary: isolate where the Netlify build hangs — does extract-api exit
(STEP2 marker), does vite@8 build complete (STEP3), and does bypassing vp
change anything. Will restore a clean command after.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the diagnostic command with `pnpm build`. The diagnostic proved a
direct (non-vp) vite@8 build deploys cleanly on Netlify in ~74s, while
`vp run website#build` hangs to the 18-minute timeout. The hang is specific
to vp's orchestration — confirmed independent of cache, Node version, the
Next.js runtime, the vite-plus version, and extract-api.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dogmar dogmar changed the title fix(ci): build website from repo root via vp in netlify.toml fix(ci): make the website deployable on Netlify (monorepo config + build fixes) Jun 15, 2026
@dogmar

dogmar commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

Closing — the real fixes were Netlify-UI-side (base directory = website, removed the stale Next.js framework override). The repo's website/netlify.toml change ended up comment-only vs main, so this PR carries no functional Netlify config change.

The branch fix/netlify-monorepo-build is kept (not deleted) so the remaining non-config changes can be salvaged if wanted: extract-api.ts process.exit(0), the Node pin, and the vite-plus 0.1.24 bump.

@dogmar dogmar closed this Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant