Files
orca/config/scripts/native-build-entry-probe.cjs
T
Neil df0c44571b fix(build): shared native packages get one immutable build instead of in-place rebuilds (#30226)
* refactor(build): extract the lock-free shared tree publish from the Electron dist cache

Native builds in package dirs shared across worktrees need the same
stage, validate, rename-into-place publish; one implementation keeps the
never-replace-a-good-entry and quarantine-restore rules in one place.

* fix(build): never rebuild a native addon in a package dir other worktrees load

Under pnpm's global virtual store node_modules/node-pty is one store slot
shared by every worktree, so an in-place node-gyp or @electron/rebuild run
in one worktree replaced the pty.node another was running. A shared
package dir now gets an immutable per-ABI build/orca-napi-<platform>-<arch>
compiled in a scratch copy, load-checked in a fresh process, and published
atomically; a usable entry is reused, never rebuilt. The patched node-pty
and windows-process-tree loaders try that dir before build/Release, and
packaging renames it to build/Release so packaged layouts are unchanged.
Private (non-GVS, CI) installs keep the existing in-place path.

* fix(build): find shared native packages through the project's own node_modules link

require.resolve with paths fell back to another install under Bun, so a
test fixture's private node-pty was judged shared.

* ci: run native checks when the shared native build modules change

* fix(build): pin the shared native slot and keep sibling publishes intact

Resolve the package's physical dir once so a concurrent relink cannot publish
one slot's build into another, verify the quarantined tree is the one judged
unusable before replacing it, and keep in-flight staging/quarantine trees out
of the packaged resource copy.

* fix(build): never move a sibling's fresh native entry, and refuse off-platform builds

Re-check the entry's identity right before quarantining it, and fail instead
of publishing a host-OS binary under another platform's entry name.
2026-10-18 20:21:50 -07:00

54 lines
1.9 KiB
JavaScript

'use strict'
// Loads one native build dir in a fresh Node or Electron process: `<runtime> this.cjs <module> <dir>`.
// Why a child: a failed addon load can poison the process that attempted it.
const { accessSync, constants, existsSync } = require('node:fs')
const { join } = require('node:path')
const { assertNodePtyJobOwnership } = require('./node-pty-job-ownership.cjs')
const { assertWindowsProcessTreeCreationTime } = require('./windows-process-tree-creation-time.cjs')
const { nodePtyNativeModuleName } = require('./native-build-entry.cjs')
const NODE_PTY_CONPTY_RUNTIME_FILES = ['conpty.dll', 'OpenConsole.exe']
function probeNativeBuildDir(moduleName, dir) {
if (moduleName === 'node-pty') {
const nativeName = nodePtyNativeModuleName()
const addonPath = join(dir, `${nativeName}.node`)
const native = { dir, module: require(addonPath) }
assertNodePtyJobOwnership({ nativeName, native, addonPath })
if (process.platform === 'darwin') {
accessSync(join(dir, 'spawn-helper'), constants.X_OK)
}
if (nativeName === 'conpty') {
for (const filename of NODE_PTY_CONPTY_RUNTIME_FILES) {
if (!existsSync(join(dir, 'conpty', filename))) {
throw new Error(
`node-pty ConPTY runtime file is missing: ${join(dir, 'conpty', filename)}`
)
}
}
}
return
}
if (moduleName === '@vscode/windows-process-tree') {
assertWindowsProcessTreeCreationTime({
module: require(join(dir, 'windows_process_tree.node'))
})
return
}
throw new Error(`no probe for ${moduleName}`)
}
if (require.main === module) {
const [moduleName, dir] = process.argv.slice(2)
try {
probeNativeBuildDir(moduleName, dir)
} catch (error) {
console.error(`${moduleName}: ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
}
}
module.exports = { probeNativeBuildDir }