mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 00:02:43 +00:00
fix(build): turn off MSBuild file tracking for Windows native rebuilds
Default Windows native rebuilds to TrackFileAccess=false while preserving explicit caller preferences. Co-authored-by: B1nh M1nh <43268322+b1nhm1nh@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
co-authored by
Claude Opus 5.5
Neil
parent
7b8498b406
commit
126f7096a3
@@ -13,6 +13,7 @@ import {
|
||||
windowsProcessTreeAddonPath
|
||||
} from './windows-process-tree-gyp-rebuild.mjs'
|
||||
import { describeProcessFailure, runProcessSync } from './script-child-process.mjs'
|
||||
import { disableMsbuildFileTrackingOnWindows } from './msbuild-file-tracking.mjs'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const { assertNodePtyJobOwnership, nodePtyAddonPath } = require('./node-pty-job-ownership.cjs')
|
||||
@@ -420,7 +421,7 @@ function runNodeGyp({ args, cwd }) {
|
||||
const env =
|
||||
process.platform === 'linux'
|
||||
? { ...process.env, CXXFLAGS: `${process.env.CXXFLAGS ?? ''} -std=gnu++2a`.trim() }
|
||||
: process.env
|
||||
: disableMsbuildFileTrackingOnWindows({ ...process.env })
|
||||
const result = runProcessSync({
|
||||
program: process.execPath,
|
||||
args,
|
||||
|
||||
@@ -60,6 +60,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(`trackFileAccess=${process.platform === 'win32' ? 'false' : ''}\n`)
|
||||
expect(log).toContain(join('node_modules', 'node-pty'))
|
||||
if (process.platform === 'linux') {
|
||||
expect(log).toMatch(/^cxxflags=(?:.*\s)?-std=gnu\+\+2a$/m)
|
||||
@@ -73,9 +74,14 @@ describe('ensure-native-runtime', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it.skipIf(process.platform !== 'win32')(
|
||||
'rebuilds other failed Windows addons with patched node-pty',
|
||||
() => {
|
||||
it.skipIf(process.platform !== 'win32').each([
|
||||
{ trackingEnv: {}, tracking: 'false' },
|
||||
{ trackingEnv: { TrackFileAccess: 'true' }, tracking: 'true' },
|
||||
{ trackingEnv: { trackfileaccess: 'true' }, tracking: 'true' },
|
||||
{ trackingEnv: { tRaCkFiLeAcCeSs: 'false' }, tracking: 'false' }
|
||||
])(
|
||||
'rebuilds other failed Windows addons with patched node-pty and tracking=$tracking',
|
||||
({ trackingEnv, tracking }) => {
|
||||
const projectDir = mkTempProject()
|
||||
|
||||
try {
|
||||
@@ -90,6 +96,7 @@ describe('ensure-native-runtime', () => {
|
||||
cwd: projectDir,
|
||||
encoding: 'utf8',
|
||||
env: envForNativeFixture(projectDir, {
|
||||
...trackingEnv,
|
||||
ORCA_NATIVE_TEST_LOG: logPath,
|
||||
ORCA_NATIVE_TEST_MARKER: markerPath
|
||||
})
|
||||
@@ -100,6 +107,9 @@ describe('ensure-native-runtime', () => {
|
||||
expect(
|
||||
log.split('\n').filter((line) => line === `node-gyp rebuild --arch=${process.arch}`)
|
||||
).toHaveLength(2)
|
||||
expect(
|
||||
log.split('\n').filter((line) => line === `trackFileAccess=${tracking}`)
|
||||
).toHaveLength(2)
|
||||
expect(log).toContain(join('node_modules', 'node-pty'))
|
||||
expect(log).toContain(join('node_modules', '@orca', 'windows-registry'))
|
||||
} finally {
|
||||
@@ -277,8 +287,12 @@ function mkTempProject() {
|
||||
}
|
||||
|
||||
function envForNativeFixture(projectDir, extraEnv) {
|
||||
// An inherited tracking preference would mask the Windows default under test.
|
||||
const inherited = Object.fromEntries(
|
||||
Object.entries(process.env).filter(([key]) => key.toLowerCase() !== 'trackfileaccess')
|
||||
)
|
||||
return {
|
||||
...process.env,
|
||||
...inherited,
|
||||
...extraEnv,
|
||||
npm_config_node_gyp: join(projectDir, 'node_modules', 'node-gyp', 'bin', 'node-gyp.js')
|
||||
}
|
||||
@@ -323,7 +337,7 @@ exports.loadNativeModule = function loadNativeModule(nativeName) {
|
||||
writeFakeWindowsRegistry(projectDir, { requiresMarker: windowsRegistryRequiresMarker })
|
||||
if (process.platform === 'win32') {
|
||||
const buildDir = join(nodePtyDir, 'build', 'Release')
|
||||
mkdirSync(buildDir, { recursive: true })
|
||||
writePatchedNodePtyBuildArtifacts(projectDir)
|
||||
writeFileSync(join(buildDir, 'conpty.node'), Buffer.from('msys-2.0.dll', 'utf16le'))
|
||||
}
|
||||
}
|
||||
@@ -419,6 +433,7 @@ const { appendFileSync, writeFileSync, writeSync } = require('node:fs')
|
||||
appendFileSync(process.env.ORCA_NATIVE_TEST_LOG, \`node-gyp \${process.argv.slice(2).join(' ')}\\n\`)
|
||||
appendFileSync(process.env.ORCA_NATIVE_TEST_LOG, \`cwd=\${process.cwd()}\\n\`)
|
||||
appendFileSync(process.env.ORCA_NATIVE_TEST_LOG, \`cxxflags=\${process.env.CXXFLAGS || ''}\\n\`)
|
||||
appendFileSync(process.env.ORCA_NATIVE_TEST_LOG, \`trackFileAccess=\${process.env.TrackFileAccess ?? ''}\\n\`)
|
||||
if (process.env.ORCA_NATIVE_TEST_VERBOSE_OUTPUT_BYTES) {
|
||||
const output = Buffer.alloc(Number(process.env.ORCA_NATIVE_TEST_VERBOSE_OUTPUT_BYTES), 'x')
|
||||
for (let offset = 0; offset < output.length;) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// FileTracker's long-path-unsafe .tlog files serve incremental builds; these rebuilds are forced.
|
||||
export function disableMsbuildFileTrackingOnWindows(
|
||||
env = process.env,
|
||||
platform = process.platform
|
||||
) {
|
||||
// Windows environment keys are case-insensitive, including caller overrides in copied objects.
|
||||
if (
|
||||
platform === 'win32' &&
|
||||
!Object.keys(env).some((key) => key.toLowerCase() === 'trackfileaccess')
|
||||
) {
|
||||
env.TrackFileAccess = 'false'
|
||||
}
|
||||
return env
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { disableMsbuildFileTrackingOnWindows } from './msbuild-file-tracking.mjs'
|
||||
|
||||
describe('disableMsbuildFileTrackingOnWindows', () => {
|
||||
it('turns tracking off on Windows when the caller left it unset', () => {
|
||||
expect(disableMsbuildFileTrackingOnWindows({ PATH: 'x' }, 'win32')).toEqual({
|
||||
PATH: 'x',
|
||||
TrackFileAccess: 'false'
|
||||
})
|
||||
})
|
||||
|
||||
it.each(['TrackFileAccess', 'trackfileaccess', 'TRACKFILEACCESS', 'tRaCkFiLeAcCeSs'])(
|
||||
'preserves explicit %s values without adding a duplicate key',
|
||||
(key) => {
|
||||
for (const value of ['true', 'false', '']) {
|
||||
const env = { [key]: value }
|
||||
expect(disableMsbuildFileTrackingOnWindows(env, 'win32')).toBe(env)
|
||||
expect(env).toEqual({ [key]: value })
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['linux', 'darwin'])('leaves %s hosts alone', (platform) => {
|
||||
const env = { PATH: 'x' }
|
||||
expect(disableMsbuildFileTrackingOnWindows(env, platform)).toBe(env)
|
||||
expect(env).toEqual({ PATH: 'x' })
|
||||
})
|
||||
})
|
||||
@@ -22,6 +22,51 @@ import {
|
||||
} from './rebuild-native-deps-test-fixtures.mjs'
|
||||
|
||||
describe('rebuild-native-deps patched node-pty rebuild', () => {
|
||||
it.skipIf(process.platform !== 'win32')(
|
||||
'passes the Windows tracking default and explicit overrides to forced Electron rebuilds',
|
||||
() => {
|
||||
const projectDir = mkTempProject()
|
||||
|
||||
try {
|
||||
const rebuildLogPath = join(projectDir, 'electron-rebuild.log')
|
||||
writeFakeUsableElectronPackage(projectDir, { platform: 'win32' })
|
||||
writeFakeElectronRebuild(projectDir, { logPathEnv: 'ORCA_REBUILD_TEST_LOG' })
|
||||
writeFakeLoadableNodePty(projectDir)
|
||||
writeFakeWindowsProcessTree(projectDir)
|
||||
writeFakeNodePtyConptyPayload(projectDir, process.arch)
|
||||
|
||||
const env = {
|
||||
ORCA_REBUILD_TEST_LOG: rebuildLogPath,
|
||||
npm_config_platform: 'win32',
|
||||
npm_config_arch: process.arch
|
||||
}
|
||||
for (const override of [
|
||||
{},
|
||||
{ TrackFileAccess: 'true' },
|
||||
{ trackfileaccess: 'true' },
|
||||
{ tRaCkFiLeAcCeSs: 'false' }
|
||||
]) {
|
||||
const result = runRebuildScript(projectDir, { ...env, ...override })
|
||||
expect(result.status, result.stderr).toBe(0)
|
||||
}
|
||||
|
||||
const calls = readFileSync(rebuildLogPath, 'utf8')
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map((line) => JSON.parse(line))
|
||||
expect(calls.map((call) => call.trackFileAccess)).toEqual([
|
||||
'false',
|
||||
'true',
|
||||
'true',
|
||||
'false'
|
||||
])
|
||||
expect(calls.every((call) => call.force)).toBe(true)
|
||||
} finally {
|
||||
removeTreeSync(projectDir)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
it.skipIf(process.platform !== 'win32')(
|
||||
'repairs a missing ConPTY runtime before probing without recompiling node-pty',
|
||||
() => {
|
||||
|
||||
@@ -110,7 +110,7 @@ export function writeWindowsProcessTreePatchFile(projectDir) {
|
||||
export function mkTempProject() {
|
||||
const projectDir = mkdtempSync(join(tmpdir(), 'orca-rebuild-native-deps-'))
|
||||
mkdirSync(join(projectDir, 'config', 'scripts'), { recursive: true })
|
||||
copyFileSync(sourceScriptPath, join(projectDir, 'config', 'scripts', 'rebuild-native-deps.mjs'))
|
||||
copyScriptWithLocalModules(sourceScriptPath, join(projectDir, 'config', 'scripts'))
|
||||
copyScriptWithLocalModules(sourceInstallScriptPath, join(projectDir, 'config', 'scripts'))
|
||||
copyScriptWithLocalModules(sourceNodePtyJobOwnershipPath, join(projectDir, 'config', 'scripts'))
|
||||
copyFileSync(
|
||||
@@ -134,7 +134,8 @@ export function runRebuildScript(projectDir, extraEnv = {}, args = []) {
|
||||
for (const key of Object.keys(env)) {
|
||||
if (
|
||||
key.toLowerCase() === 'orca_strict_electron_install' ||
|
||||
key.toLowerCase() === 'npm_lifecycle_event'
|
||||
key.toLowerCase() === 'npm_lifecycle_event' ||
|
||||
key.toLowerCase() === 'trackfileaccess'
|
||||
) {
|
||||
delete env[key]
|
||||
}
|
||||
@@ -286,6 +287,7 @@ export async function rebuild(options) {${emitAddon}
|
||||
electronVersion: options.electronVersion,
|
||||
force: options.force,
|
||||
ignoreModules: options.ignoreModules,
|
||||
trackFileAccess: process.env.TrackFileAccess ?? null,
|
||||
onlyModules: options.onlyModules,
|
||||
platform: options.platform
|
||||
}) + '\\n'
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
stageWindowsProcessTreeNodeAddonApiHeaders,
|
||||
windowsProcessTreeAddonPath
|
||||
} from './windows-process-tree-gyp-rebuild.mjs'
|
||||
import { disableMsbuildFileTrackingOnWindows } from './msbuild-file-tracking.mjs'
|
||||
import {
|
||||
copyFileSync,
|
||||
existsSync,
|
||||
@@ -162,6 +163,7 @@ try {
|
||||
console.warn('[rebuild] Repaired the un-applied windows-process-tree command-line patch.')
|
||||
}
|
||||
}
|
||||
disableMsbuildFileTrackingOnWindows()
|
||||
await rebuild({
|
||||
buildPath: projectDir,
|
||||
electronVersion,
|
||||
|
||||
Reference in New Issue
Block a user