Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions config/scripts/ensure-native-runtime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ensureWindowsProcessTreeCommandLinePatch,
inspectWindowsProcessTreeAddon,
nodeGypRebuildInvocation,
nodeGypRebuildTimeoutMs,
stageWindowsProcessTreeNodeAddonApiHeaders,
windowsProcessTreeAddonPath
} from './windows-process-tree-gyp-rebuild.mjs'
Expand Down Expand Up @@ -405,6 +406,7 @@ function rebuildNodeRuntimeModules(moduleNames) {
console.warn(`[native-runtime] Rebuilding ${moduleName} with node-gyp.`)
// pnpm exec inside an installed addon cannot discover the root build tool.
runNodeGyp(
moduleName,
nodeGypRebuildInvocation(
process.arch,
moduleDir,
Expand All @@ -417,7 +419,7 @@ function rebuildNodeRuntimeModules(moduleNames) {
}
}

function runNodeGyp({ args, cwd }) {
function runNodeGyp(moduleName, { args, cwd }) {
const env =
process.platform === 'linux'
? { ...process.env, CXXFLAGS: `${process.env.CXXFLAGS ?? ''} -std=gnu++2a`.trim() }
Expand All @@ -428,7 +430,7 @@ function runNodeGyp({ args, cwd }) {
cwd,
env,
stdio: 'inherit',
timeoutMs: 300_000
timeoutMs: nodeGypRebuildTimeoutMs(moduleName)
})
if (result.code !== 0) {
console.error(
Expand Down
15 changes: 13 additions & 2 deletions config/scripts/ensure-native-runtime.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { resolveCliCommand } from '../../src/shared/node-cli-command-resolution.
import { removeTreeSync } from '../../src/shared/windows-transient-lock-removal.ts'
import { resolvePnpmCliInvocation } from './pnpm-cli-invocation.mjs'
import { copyScriptWithLocalModules } from './script-module-dependencies.mjs'
import { nodeGypRebuildInvocation } from './windows-process-tree-gyp-rebuild.mjs'
import {
nodeGypRebuildInvocation,
nodeGypRebuildTimeoutMs
} from './windows-process-tree-gyp-rebuild.mjs'

const sourceScriptPath = fileURLToPath(new URL('./ensure-native-runtime.mjs', import.meta.url))
// The import walk sees `from './x.mjs'` only, so the createRequire'd CJS
Expand Down Expand Up @@ -60,6 +63,7 @@ describe('ensure-native-runtime', () => {
expect(result.stderr).toContain('node-gyp stderr complete\n')
const log = readFileSync(logPath, 'utf8')
expect(log).toContain(`node-gyp rebuild --arch=${process.arch}\n`)
expect(log).toContain(`node-gyp timeout=${nodeGypRebuildTimeoutMs('node-pty')}\n`)
expect(log).toContain(`trackFileAccess=${process.platform === 'win32' ? 'false' : ''}\n`)
expect(log).toContain(join('node_modules', 'node-pty'))
if (process.platform === 'linux') {
Expand Down Expand Up @@ -275,7 +279,14 @@ function mkTempProject() {
copyScriptWithLocalModules(sourceScriptPath, join(projectDir, 'config', 'scripts'))
writeFileSync(
join(projectDir, 'config', 'scripts', 'script-child-process.mjs'),
`export { describeProcessFailure, runProcessSync } from ${JSON.stringify(new URL('./script-child-process.mjs', import.meta.url).href)}\n`
`import { appendFileSync } from 'node:fs'
import { describeProcessFailure, runProcessSync as run } from ${JSON.stringify(new URL('./script-child-process.mjs', import.meta.url).href)}
export { describeProcessFailure }
export function runProcessSync(options) {
appendFileSync(process.env.ORCA_NATIVE_TEST_LOG, \`node-gyp timeout=\${options.timeoutMs}\\n\`)
return run(options)
}
`
)
for (const name of REQUIRED_CJS_SIBLINGS) {
copyFileSync(
Expand Down
10 changes: 10 additions & 0 deletions config/scripts/windows-process-tree-gyp-rebuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ export function nodeGypRebuildInvocation(
}
}

export function nodeGypRebuildTimeoutMs(
moduleName,
{ platform = process.platform, arch = process.arch, ci = process.env.CI } = {}
) {
// Cold headers and toolchain discovery consumed over four minutes on Windows ARM CI.
return moduleName === 'node-pty' && platform === 'win32' && arch === 'arm64' && ci === 'true'
? 600_000
: 300_000
}

/** The binary the addon actually loads. */
export function windowsProcessTreeAddonPath(packageDir = WINDOWS_PROCESS_TREE_PACKAGE_DIR) {
return join(packageDir, 'build', 'Release', 'windows_process_tree.node')
Expand Down
28 changes: 28 additions & 0 deletions config/scripts/windows-process-tree-gyp-rebuild.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
assertWindowsProcessTreeRuntimeCreationTime,
inspectWindowsProcessTreeAddon,
nodeGypRebuildInvocation,
nodeGypRebuildTimeoutMs,
stageWindowsProcessTreeNodeAddonApiHeaders,
WINDOWS_PROCESS_TREE_NODE_ADDON_API_HEADERS,
WINDOWS_PROCESS_TREE_PACKAGE_DIR
Expand Down Expand Up @@ -54,6 +55,33 @@ describe('windows-process-tree node-gyp rebuild', () => {
})
})

it('allows cold setup and compilation only for node-pty on a Windows ARM CI host', () => {
expect(
nodeGypRebuildTimeoutMs('node-pty', { platform: 'win32', arch: 'arm64', ci: 'true' })
).toBe(600_000)
})

it.each([
{ moduleName: 'node-pty', platform: 'win32', arch: 'x64', ci: 'true' },
{ moduleName: 'node-pty', platform: 'linux', arch: 'arm64', ci: 'true' },
{ moduleName: 'node-pty', platform: 'darwin', arch: 'arm64', ci: 'true' },
{ moduleName: 'node-pty', platform: 'win32', arch: 'arm64', ci: '' },
{ moduleName: 'node-pty', platform: 'win32', arch: 'arm64', ci: 'false' },
{ moduleName: 'node-pty', platform: 'win32', arch: 'arm64', ci: '1' },
{ moduleName: '@orca/windows-registry', platform: 'win32', arch: 'arm64', ci: 'true' },
{ moduleName: '@vscode/windows-process-tree', platform: 'win32', arch: 'arm64', ci: 'true' }
])('keeps the five-minute bound for $moduleName on $platform/$arch with CI=$ci', (host) => {
expect(nodeGypRebuildTimeoutMs(host.moduleName, host)).toBe(300_000)
})

it('uses the execution host rather than an ARM cross-compilation target', () => {
const { args } = nodeGypRebuildInvocation('arm64', import.meta.dirname)
expect(args).toContain('--arch=arm64')
expect(
nodeGypRebuildTimeoutMs('node-pty', { platform: 'win32', arch: 'x64', ci: 'true' })
).toBe(300_000)
})

it('copies node-addon-api headers into the patched include dir', () => {
const packageDir = mkdtempSync(join(tmpdir(), 'orca-windows-process-tree-headers-'))
try {
Expand Down
Loading