Fix CI: stop running pnpm install next to builds - #800
Merged
NullVoxPopuli merged 1 commit intoAug 16, 2026
Merged
Conversation
|
|
Contributor
|
`@universal-ember/docs-support#build` has been failing in CI with
Command failed with EACCES: ember-tsc --declaration --declarationDir declarations
spawn ember-tsc EACCES
`_syncPnpm` was `pnpm install --frozen-lockfile`, as a turbo task that
depended on `^build`. So `test-app#_syncPnpm` and
`@universal-ember/docs-support#build` were both unblocked by
`ember-primitives#build`, and turbo ran them at the same time. An
install rewrites every package's `node_modules/.bin`, and rollup's
declarations plugin spawns `ember-tsc` out of exactly that directory --
so the spawn could land on a shim that was momentarily absent, or
present but not yet chmod'd. That is the EACCES.
Measured, by polling the shim while building and recording when
docs-support's own `ember-tsc` was running:
shim unusable, during that spawn window
before 27
after 0
The install was redundant anyway. `.npmrc` already carries
`sync-injected-deps-after-scripts[]=build`, so pnpm re-syncs injected
workspace deps itself after each package's `build` script -- verified by
adding a marker to ember-primitives' source, building only that package,
and finding the marker in test-app's injected copy with no install of
any kind. That sync runs inside the owning package's `pnpm run build`,
which turbo waits on, so it cannot overlap a sibling.
`_syncPnpm` was also how these tasks inherited `^build`. That is now
declared directly, which is what they meant.
Local, on this branch: `pnpm build` green five times over, `pnpm lint`
24/24. `turbo test:ember --filter test-app` is green apart from four
pre-existing `<InViewport />` failures that predate this branch.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
NullVoxPopuli-ai-agent
force-pushed
the
nvp/fix-ci-bin-race
branch
from
August 16, 2026 19:04
2ffe0d2 to
d4d3fcf
Compare
NullVoxPopuli
approved these changes
Aug 16, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every PR run has been red since at least Aug 9 — including renovate lockfile-only PRs (example) — with
Setupdying at:What it actually was
_syncPnpmwaspnpm install --frozen-lockfile, declared as a turbo task withdependsOn: ["^build"]. Bothtest-app#_syncPnpmand@universal-ember/docs-support#buildare unblocked byember-primitives#build, so turbo ran an install concurrently with a build.An install rewrites every package's
node_modules/.bin. Rollup'sdeclarationsplugin spawnsember-tscout of exactly that directory. If the spawn lands mid-rewrite, the shim is either gone or written-but-not-yet-chmod'd — and spawning a non-executable file isEACCES.Nothing about the code was involved, which is why lockfile-only PRs failed identically.
Measured, not guessed
Polling
packages/docs-support/node_modules/.bin/ember-tscduring a fullpnpm build --force, while separately recording the window in which docs-support's ownember-tscprocess was alive:mainIsolated, a single
pnpm install --frozen-lockfileintest-appleaves the docs-support shim missing or-rw-rw-r--for a good fraction of its run — 178 unusable samples in one install.Note the race is probabilistic:
pnpm buildoften passes locally onmain. The CI runner loses it reliably.The install was redundant
.npmrcalready hassync-injected-deps-after-scripts[]=build, so pnpm re-syncs injected workspace deps itself after each package'sbuildscript. Verified directly: added a marker toember-primitives/src, ranpnpm --filter ember-primitives build, and found the marker intest-app's injected copy — with no install of any kind.test-app's ownsyncscript already says as much in its echo.That sync runs inside the owning package's
pnpm run build, which turbo waits on, so it cannot overlap a sibling's build. The remaining rewrites all land outside the spawn window — that is what the 0 above measures._syncPnpmwas also howbuild,build:dev,test,test:ember, andstartinherited^build. That is now declared directly on each, which is what they meant.Checked locally
pnpm buildgreen, five consecutive--forcerunspnpm lint— 24/24 taskspnpm turbo test:ember --filter test-app— green apart from four<InViewport />failures that are pre-existing onmainhere (IntersectionObserver under headless Chrome); they are unrelated to this change, and CI has never gotten far enough to say whether they fail on a runner tooThe workflow's own
pnpm i -fsteps are untouched: they run sequentially, before the build, and race nothing.🤖 Generated with Claude Code