Skip to content

fix(tests): serialize package builds across parallel vitest workers#3480

Open
arham766 wants to merge 1 commit into
facebook:mainfrom
arham766:fix/build-theme-test-race
Open

fix(tests): serialize package builds across parallel vitest workers#3480
arham766 wants to merge 1 commit into
facebook:mainfrom
arham766:fix/build-theme-test-race

Conversation

@arham766

@arham766 arham766 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #3479. Three test files build into packages/core/dist from beforeAll: scripts/build-css.test.mjs runs a full pnpm build unconditionally, and the two build-theme test files build core when dist/theme/index.js is missing. Vitest runs test files in parallel worker processes, so two of those builds can run concurrently over the same dist directory: one build's rimraf dist races the other's output, failing with ENOTEMPTY: rmdir dist/utils or esbuild: Could not resolve dist/index.js. That is exactly the failure on the CI run for #3466 (a PR whose diff touches none of these files; adding a test file reshuffled vitest's worker distribution enough to expose the race).

The fix adds scripts/repo-build-lock.mjs: a withRepoBuildLock(fn) helper that serializes the builds with an atomic lock directory (fs.mkdirSync either creates it or throws EEXIST) and a bounded wait with a stale-lock hint. All three files run their build under the lock, and the build-theme files re-check existsSync inside it, so a waiter skips the rebuild the holder already completed. The lock directory is gitignored.

Test plan

  • Mutual-exclusion stress: 6 concurrent node processes each acquire the lock and write/hold/remove a marker file that fails the run if a second holder ever enters. All 6 serialize cleanly; the lock directory is released at exit.
  • Normal path: with core built, both build-theme files run through the lock (acquire, skip build, release) and their tests behave exactly as before. build-theme.prose.test.mjs passes 2/2 locally; build-theme.import-path.test.mjs is 4/5 with the one failure being the pre-existing Windows path-separator issue tracked in [Bug] Test suite fails on Windows due to path separator and URL.pathname issues #3233 (present on main before this change).
  • The race path itself (two workers both seeing dist missing) cannot be exercised faithfully on this Windows machine because execFileSync('pnpm', ...) cannot spawn pnpm.cmd there (also pre-existing, part of [Bug] Test suite fails on Windows due to path separator and URL.pathname issues #3233), so the concurrency correctness is covered by the stress test above plus Linux CI on this PR.
  • node scripts/check-changesets.mjs passes.

Three test files build into packages/core/dist from beforeAll
(build-css.test.mjs runs pnpm build unconditionally; the two build-theme
files build core when dist/theme is missing). Vitest runs test files in
parallel worker processes, so two builds could run concurrently and race
each other's rimraf/output, failing CI with ENOTEMPTY on dist/utils or
an unresolvable dist/index.js. Adds a repo-wide lock (atomic mkdir with
a bounded wait) shared by all three, with the exists-check re-run inside
the lock so waiters skip a rebuild the holder already did.

Fixes facebook#3479
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

@arham766 is attempting to deploy a commit to the Meta Open Source Team on Vercel.

A member of the Team first needs to authorize it.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Flaky CI: build-theme test files race concurrent core builds over the same dist directory (ENOTEMPTY / unresolvable dist/index.js)

1 participant