mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* build: share one pnpm virtual store across worktrees, off under CI
Each worktree carried a full node_modules; the global virtual store links
one slot per package version instead. pnpm keeps an explicit setting on
under CI, so a pnpmfile hook turns it off there: CI packages from,
caches and verifies a project-local node_modules.
* fix(build): keep shared electron and windows-process-tree dirs untouched under GVS
Every worktree runs Electron from the one shared electron package, so the
per-repo dist cache must not swap that dist and a foreign-arch install must
not land in it. The relay addon builder now repairs and compiles a private
copy instead of the shared windows-process-tree dir.
* fix(build): accept CLI runtime imports reached through an in-artifact store link
Under the global virtual store node_modules/<pkg> realpaths into a store
outside the repo. The check still rejects anything not reached through a
node_modules link inside the artifact, such as a stray ~/node_modules.
* docs: explain the global virtual store layout and the ~/node_modules hazard
* test: compare CLI closure paths with POSIX separators so the suite passes on Windows
* build: keep Windows on the normal pnpm layout unless ORCA_PNPM_GLOBAL_VIRTUAL_STORE=1
Store links are true symlinks on Windows, and installs without admin or
Developer Mode are unverified; CI still forces the normal layout first.
* fix(build): close the remaining shared-slot gaps under the global virtual store
- verify-skills-cli-runtime resolves each import from the importer's realpath,
as Node does, so an artifact-local copy can't mask a ~/node_modules load.
- A concurrent sibling install of the shared Electron dist is kept, not swapped out.
- rebuild:node goes through ensure-native-runtime, which builds a shared
node-pty beside the slot instead of node-gyp cleaning its build/ dir.
* fix(build): keep pnpm rebuild:node a forced rebuild
It replaced pnpm rebuild node-pty, which always rebuilt; without --force it
only rebuilt a node-pty that failed to load.
* docs: note that the store switches must stay set, since pnpm run relinks
* build: move the pnpmfile under config/ to keep the repo root allowlisted
pnpm-workspace.yaml points pnpm at it; the lockfile checksum is unchanged
because the content is.
* fix(build): enable the global virtual store from the pnpmfile, not the workspace file
pnpm exec derives NODE_PATH from the file setting, so even with the store
forced off under CI every child process got the root node_modules on its
NODE_PATH; a Windows rebuild fixture then resolved the real
@orca/windows-registry it deliberately omits. The hook now sets the store
both ways, and ORCA_PNPM_GLOBAL_VIRTUAL_STORE=0/1 is the one switch.
* test(pty): keep F3's concurrent spawns on the node-pty mock
Two concurrent first import('node-pty') calls race vitest's mock registry
and the loser loads the real addon under the mocked linux platform. It
passed only where a platform-agnostic build/Release happened to exist,
so it failed on every shared-store worktree.
* ci: fail PRs whose packages need a dependency they never declared
A new dependency_isolation job installs with the global virtual store
forced on (ORCA_PNPM_FORCE_GLOBAL_VIRTUAL_STORE_IN_CI), HOME and the store
in an empty temp dir, then runs pnpm tc and the undeclared-dependency test.
Postinstall now warns when a node_modules above the shared store, such as
~/node_modules, would mask the same class of bug locally.
* ci: set the isolation job's HOME and store through GITHUB_ENV
Job-level env cannot read the runner context, which made pr.yml invalid.
47 lines
1.6 KiB
JavaScript
47 lines
1.6 KiB
JavaScript
import { existsSync, realpathSync } from 'node:fs'
|
|
import { basename, dirname, join } from 'node:path'
|
|
import { isSharedPackageDir } from './native-build-entry.cjs'
|
|
|
|
/**
|
|
* node_modules dirs above the global virtual store's `links` root, given one store slot's path.
|
|
*
|
|
* Node resolves upward from a slot, so a stray `~/node_modules` (or `/tmp/node_modules`) above
|
|
* the store hands every package dependencies it never declared and hides exactly the bugs the
|
|
* isolated layout exists to surface.
|
|
*/
|
|
export function nodeModulesAboveStore(slotPackageDir, exists = existsSync) {
|
|
let storeRoot = slotPackageDir
|
|
while (basename(storeRoot) !== 'links') {
|
|
const parent = dirname(storeRoot)
|
|
if (parent === storeRoot) {
|
|
return []
|
|
}
|
|
storeRoot = parent
|
|
}
|
|
const found = []
|
|
for (let dir = dirname(storeRoot); ; dir = dirname(dir)) {
|
|
if (exists(join(dir, 'node_modules'))) {
|
|
found.push(join(dir, 'node_modules'))
|
|
}
|
|
if (dirname(dir) === dir) {
|
|
return found
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Warns, never fails: the install itself is fine, only undeclared-dependency checks are blinded. */
|
|
export function warnAboutNodeModulesAboveSharedStore(projectDir, probePackage = 'zod') {
|
|
const linked = join(projectDir, 'node_modules', probePackage)
|
|
if (!existsSync(linked) || !isSharedPackageDir(linked, projectDir)) {
|
|
return []
|
|
}
|
|
const found = nodeModulesAboveStore(realpathSync(linked))
|
|
for (const dir of found) {
|
|
console.warn(
|
|
`[gvs] ${dir} sits above the shared pnpm store, so packages there resolve dependencies ` +
|
|
'they never declared and undeclared-dependency bugs stay hidden. Move or remove it.'
|
|
)
|
|
}
|
|
return found
|
|
}
|