chore(cli-test): exclude node_modules on Windows and tolerate dangling symlinks#1127
chore(cli-test): exclude node_modules on Windows and tolerate dangling symlinks#1127gu-stav wants to merge 2 commits into
Conversation
|
Claude finished @gu-stav's task in 1m 32s —— View job Review
FindingsMissing changeset (please add)
Recommend adding a patch changeset, e.g.: ---
'@sanity/cli-test': patch
---
fix: exclude node_modules from bundled fixtures on Windows and skip dangling symlinks when cloning fixturesSilent skip could surprise callers (minor) Follow-up scope (already called out in description) Verified
|
📦 Bundle Stats —
|
| Metric | Value | vs main (cd110e7) |
|---|---|---|
| Internal (raw) | 2.1 KB | - |
| Internal (gzip) | 799 B | - |
| Bundled (raw) | 10.97 MB | - |
| Bundled (gzip) | 2.06 MB | - |
| Import time | 827ms | -1ms, -0.1% |
bin:sanity
| Metric | Value | vs main (cd110e7) |
|---|---|---|
| Internal (raw) | 1023 B | - |
| Internal (gzip) | 486 B | - |
| Bundled (raw) | 9.84 MB | - |
| Bundled (gzip) | 1.77 MB | - |
| Import time | 1.95s | -1ms, -0.1% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-core
Compared against main (cd110e7c)
| Metric | Value | vs main (cd110e7) |
|---|---|---|
| Internal (raw) | 97.0 KB | - |
| Internal (gzip) | 22.7 KB | - |
| Bundled (raw) | 21.61 MB | - |
| Bundled (gzip) | 3.42 MB | - |
| Import time | 786ms | -1ms, -0.1% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — create-sanity
Compared against main (cd110e7c)
| Metric | Value | vs main (cd110e7) |
|---|---|---|
| Internal (raw) | 908 B | - |
| Internal (gzip) | 483 B | - |
| Bundled (raw) | 931 B | - |
| Bundled (gzip) | 491 B | - |
| Import time | ❌ ChildProcess denied: node | - |
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
…g symlinks
The copy-fixtures filter used `src.split('/').pop()` which fails on Windows
(paths use `\`), so `node_modules` was copied into the bundled fixtures dir
during the Windows build. Node's `fs.cp` resolves symlinks to absolute paths,
and since `fixtures/**` is a turbo build output the Windows-absolute symlinks
were cached and replayed on Linux, where they became dangling and crashed
`testFixture` setup with ENOENT.
Switch the filter to `path.basename` so it's platform-aware, and skip dangling
symlinks in `testFixture` defensively so cross-OS cache replay can't ever
crash fixture loading again.
1d86b9b to
a64133f
Compare
Drop `| undefined` from `targetStats` — every path reaching `symlink(...)` definitively assigns it (the symlink branch assigns, continues, or throws; the else branch assigns), so the wider type was misleading.
Coverage DeltaNo covered files changed in this PR. Overall Coverage
|
Description
Fixes two flaky test failures observed in CI (e.g. run 26275207771):
build.app.test.ts > should error when @sanity/sdk-react is not installedbuild.studio.test.ts > should error when styled-components is not installedBoth crashed with
ENOENT: no such file or directory, stat '.../packages/@sanity/cli-test/fixtures/basic-app/node_modules/react'attestFixture.ts:159, wherestat()follows a symlink in the bundled fixtures'node_modules.Root cause (cross-OS turbo cache corruption):
copy-fixtures.tsusedsrc.split('/').pop()to filter outnode_modules/dist/.turbo. On Windows, paths use\, sosplit('/')returns the whole path as a single segment and the filter never matches.pnpm installpopulatesfixtures/basic-app/node_modules(workspace install).copy-fixturesthen copies thatnode_modulesintopackages/@sanity/cli-test/fixtures/basic-app/node_modules, and Node'sfs.cpresolves symlinks to absolute Windows paths.turbo.jsondeclaresfixtures/**as a build output, so those Windows-absolute symlinks get cached.C:\a\cli\cli\...paths). On Linux, the Windows-path symlink targets don't exist → dangling → ENOENT onstat.Fixes:
copy-fixtures.ts: switch the filter topath.basename(src)so it's platform-aware.testFixture.ts: defensively skip dangling symlinks (ENOENT onstat) so cross-OS cache replay or other leftover state can't crash fixture loading again.What to review
Worth flagging as a follow-up (not in this PR): even after fix #1, sharing a turbo cache between Windows and Linux for
@sanity/cli-test:buildis fragile because its output contains resolved symlinks. Consider scoping the turbo cache key per-OS for this task, or droppingfixtures/**fromoutputs.Testing
pnpm check:types(clean) andpnpm check:lint(clean, only pre-existing warnings).pnpm test --changed --bail=1→ 1329/1329 passed.path.win32.basenamereturningnode_modulescorrectly.Note
Low Risk
Low risk: small, localized changes to test/fixture build tooling that only affect how fixtures and
node_modulessymlinks are copied, with narrow error handling (onlyENOENTis tolerated).Overview
Fixes flaky
@sanity/cli-testruns across Windows/Linux by making fixture bundling and cloning more robust.The fixture copy script now uses
path.basename()when filtering duringfs.cp, ensuringnode_modules,.turbo, and optionaldistare correctly excluded on Windows path separators.testFixture()now skips danglingnode_modulessymlinks by swallowingENOENTfromstat()when determining symlink type, preventing cross-OS cache replays from crashing.Reviewed by Cursor Bugbot for commit 489a86a. Bugbot is set up for automated code reviews on this repo. Configure here.