chore: use global virtual store - #10587
Conversation
PR Summary by QodoEnable Bit global virtual store for pnpm installs
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1. Prune deletes pnpm internals
|
| "resolveEnvsFromRoots": true | ||
| }, | ||
| "teambit.dependencies/dependency-resolver": { | ||
| "enableGlobalVirtualStore": true, |
There was a problem hiding this comment.
1. Prune deletes pnpm internals 🐞 Bug ☼ Reliability
With enableGlobalVirtualStore enabled, pnpm keeps pnpm-owned dot entries under node_modules/.pnpm, but pnpmPruneModules() does not exclude dot entries and will remove them when they don’t appear in the lockfile’s package list. This can break or destabilize subsequent installs by deleting pnpm-managed virtual-store state (or forcing it to be recreated unpredictably).
Agent Prompt
### Issue description
After this PR enables `enableGlobalVirtualStore` in `workspace.jsonc`, installs run in the global virtual store layout where `node_modules/.pnpm` contains pnpm-owned entries (including dot-prefixed directories). The post-install prune step (`pnpmPruneModules`) currently treats *all* entries except `lock.yaml` and `node_modules` as prune candidates, so it may delete pnpm-owned dot entries.
### Issue Context
- The workspace runs a prune step after installs.
- Repo e2e/helper code explicitly treats dot entries under `node_modules/.pnpm` as pnpm-owned internals that should not be considered dependency directories.
### Fix Focus Areas
- scopes/dependencies/pnpm/pnpm-prune-modules.ts[21-50]
### Suggested fix
- Change `readPackageDirsFromVirtualStore()` to:
- use `readdir(..., { withFileTypes: true })`
- include **directories only**
- exclude entries that start with `.`
- keep excluding `node_modules` and `lock.yaml`
- Add/adjust an e2e or unit test for the global virtual store path to ensure prune does not remove dot-prefixed pnpm entries under `node_modules/.pnpm`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
With enableGlobalVirtualStore, node_modules holds only symlinks into <store-dir>/links. pnpm's default store is ~/.local/share/pnpm, outside setup_harmony's persist_to_workspace root, so every job that merely attaches the workspace received dangling symlinks (lint died on a missing node_modules/oxlint/bin/oxlint). Point store-dir under ~/bit and persist the links directory. files/ is left out: the consumers of this workspace read node_modules, they never fetch packages, and carrying the content-addressable store too would duplicate every package in the archive. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| # only the global virtual store, not the content-addressable files/ it hardlinks from: | ||
| # the consumers of this workspace read node_modules, they never fetch packages, and | ||
| # carrying files/ too would duplicate every package in the archive. | ||
| - .pnpm-store/*/links |
There was a problem hiding this comment.
1. Persisted links path mismatch 🐞 Bug ☼ Reliability
The CircleCI workspace persists .pnpm-store/*/links, but Bit resolves the global virtual store at <storeDir>/links; if the resolved storeDir is /home/circleci/bit/.pnpm-store (as configured), downstream jobs that only attach the workspace may miss the actual links directory and end up with broken node_modules symlinks.
Agent Prompt
## Issue description
CircleCI persists `.pnpm-store/*/links`, but Bit/pnpm’s global virtual store directory is computed as `<storeDir>/links`. If pnpm resolves `storeDir` to the configured `/home/circleci/bit/.pnpm-store`, the actual required directory would be `.pnpm-store/links`, which is not matched by `.pnpm-store/*/links`.
This can break downstream jobs that rely on the attached workspace (without reinstalling) because `node_modules` entries may symlink into the missing global virtual store.
## Issue Context
- CI explicitly sets `store-dir=/home/circleci/bit/.pnpm-store`.
- Bit’s pnpm adapter computes the global virtual store as `join(config.storeDir, 'links')`.
- Downstream jobs (e.g. `lint`) attach the workspace and run commands without reinstalling.
## Fix Focus Areas
- .circleci/config.yml[665-710]
## Suggested fix
Update `persist_to_workspace.paths` to persist the exact `links` directory that Bit/pnpm uses.
A pragmatic, layout-tolerant option that still avoids persisting `files/` is to include both possible layouts:
- `.pnpm-store/links`
- `.pnpm-store/*/links`
(If you want to be stricter/cleaner, ensure the persisted path exactly matches the resolved `<storeDir>/links` layout you expect in CI.)
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit 9424647 |
store-dir in .npmrc is ignored: pnpm keeps only npm-compatible settings there, and bit installs through @pnpm/napi's config reader, which takes storeDir from the pnpm-workspace.yaml cascade. The store stayed in ~/.local/share/pnpm, outside the persist_to_workspace root, so the node_modules symlinks reaching into <storeDir>/links still dangled in every job that only attaches the workspace. Write a CI-only pnpm-workspace.yaml instead, and check the store landed inside the workspace before persisting it — a persist path that matches nothing is not an error, so the previous attempt failed as a MODULE_NOT_FOUND in lint rather than in the job that got it wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| "resolveEnvsFromRoots": true | ||
| }, | ||
| "teambit.dependencies/dependency-resolver": { | ||
| "enableGlobalVirtualStore": true, |
There was a problem hiding this comment.
1. Schema missing gvs key 🐞 Bug ⚙ Maintainability
workspace.jsonc now sets enableGlobalVirtualStore, but the repo’s workspace-jsonc-schema.json does not define this property under teambit.dependencies/dependency-resolver, so schema-driven validation/autocomplete cannot surface/validate the new config key.
Agent Prompt
### Issue description
`workspace.jsonc` enables `enableGlobalVirtualStore`, but `workspace-jsonc-schema.json` does not declare this option in the `teambit.dependencies/dependency-resolver` schema. This creates schema/config drift: editors and any schema validation tooling won’t recognize the new key.
### Issue Context
The config key is a real, supported option in code (`DependencyResolverWorkspaceConfig.enableGlobalVirtualStore?: boolean`), so the schema should be updated to match.
### Fix Focus Areas
- workspace-jsonc-schema.json[51-320]
- workspace.jsonc[13-16]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit ebfb668 |
The global virtual store puts every package's real directory outside the project, so a package that requires an undeclared dependency by bare name no longer finds it: node resolves from the realpath, and the ancestor walk out of <store>/links/@/mocha/... never reaches the project's node_modules the way the walk out of node_modules/.pnpm/mocha@11.1.0/ did. mocha requires the reporter, and mocha-multi-reporters requires each reporter it composes, so both hops died — taking down every e2e job before a single test ran. Both accept a path resolved against cwd, which is the repo root for these scripts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Code review by qodo was updated up to the latest commit 23abbf3 |
Proposed Changes