Skip to content

Fail fast when bootstrapping workspaces#378

Closed
kraenhansen wants to merge 1 commit into
mainfrom
claude/node-exit-code-propagation-g4vg93
Closed

Fail fast when bootstrapping workspaces#378
kraenhansen wants to merge 1 commit into
mainfrom
claude/node-exit-code-propagation-g4vg93

Conversation

@kraenhansen

Copy link
Copy Markdown
Collaborator

Problem

A npm run bootstrap step in CI (e.g. this Test app (iOS) run) doesn't stop on the first real error. Instead it continues and fails a series of secondary commands that only fail because an earlier command failed, making the log noisy and the real root cause hard to spot.

Root cause

The root bootstrap script was:

node --run build && npm run bootstrap --workspaces --if-present

npm's --workspaces iteration is not fail-fast. When one workspace's bootstrap script exits non-zero, npm keeps running the bootstrap script for every remaining workspace and only surfaces a non-zero exit code once they've all run.

In the linked run, the actual first failure is weak-node-api's bootstrap — a CMake configuration error prevents the weak-node-api.xcframework from being produced:

> weak-node-api@0.1.1 bootstrap
...
CMake Error in CMakeLists.txt:
  The file set "HEADERS", of type "HEADERS", is incompatible with the "FRAMEWORK" target "weak-node-api".
...
ERROR Running 'cmake' failed (code = 1)
npm error workspace weak-node-api@0.1.1

That exit code is propagated correctly, but because npm doesn't fail fast, the workspaces that consume the xcframework then run and fail with confusing downstream errors:

  • node-addon-examplesExpected an XCFramework at .../weak-node-api/build/Release/weak-node-api.xcframework
  • node-tests → same missing-xcframework assertion
  • ferric-exampleNo matching slice found in weak-node-api.xcframework for target aarch64-apple-ios-sim

So the run "doesn't fail on the first error" — it fails three more times on commands that depend on the first one having succeeded, and the genuine root cause (the CMake error in weak-node-api) is buried in the middle of the log.

Note: the underlying CMake HEADERS/FRAMEWORK incompatibility in weak-node-api is a separate build issue and is intentionally not addressed here — this PR only fixes the error-propagation/fail-fast behavior so that such a failure is surfaced clearly instead of triggering a cascade.

Fix

Replace the non-fail-fast --workspaces iteration with a small scripts/bootstrap.ts that:

  • iterates the workspaces in their declared order (which is the build order — weak-node-api before its consumers),
  • runs npm run bootstrap --workspace <name> for each workspace that has a bootstrap script (preserving the --if-present semantics),
  • and stops at the first workspace that fails, propagating its exit code.

This mirrors the existing scripts/run-in-published.ts pattern already used in the repo.

Verification

Reproduced npm's non-fail-fast behavior with a 3-workspace fixture (a ok, b fails, c ok): c still ran after b failed, matching the CI log. Ran the new scripts/bootstrap.ts against the same fixture:

  • b fails → c is not run, script exits 1 immediately.
  • all-success case → every workspace with a bootstrap script runs, workspaces without one are skipped, script exits 0.

Also confirmed the generated bootstrap plan against the real repo matches the previous behavior exactly (weak-node-apihostnode-addon-examplesnode-testsferric-example, with script-less workspaces skipped).

Follow-up (not in this PR)

The prerelease root script uses the same non-fail-fast pattern (npm run prerelease --workspaces --if-present) and would benefit from the same treatment.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MFfJiaaqbgMqnrNUB6e76m


Generated by Claude Code

The root `bootstrap` script ran `npm run bootstrap --workspaces
--if-present`, but npm does not fail fast across workspaces: when one
workspace's bootstrap fails, npm keeps running the bootstrap script for
the remaining workspaces and only reports a non-zero exit code at the
end.

Because later workspaces depend on artifacts produced by earlier ones
(e.g. the weak-node-api xcframework consumed by node-addon-examples,
node-tests and ferric-example), a failure while building weak-node-api
produced a cascade of confusing secondary "missing xcframework" errors
that buried the actual root cause.

Replace the `--workspaces` iteration with a small script that bootstraps
each workspace in declared order and stops at the first failing one, so
CI surfaces the real error instead of the downstream cascade.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MFfJiaaqbgMqnrNUB6e76m
@kraenhansen

Copy link
Copy Markdown
Collaborator Author

I think this gives me the collateral to resurrect #204

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.

2 participants