build(ssh): make copied MSVC inputs deterministic

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo-H
2026-07-14 13:57:00 -04:00
co-authored by Orca
parent a51093f009
commit 6546f54d53
2 changed files with 51 additions and 7 deletions
@@ -1,6 +1,30 @@
import { readFile, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
const COMPILER_OPTIONS = ` 'VCCLCompilerTool': {
'AdditionalOptions': [
'/guard:cf',
'/sdl',
'/W3',
'/w34244',
'/w34267',
'/ZH:SHA_256'
]
}`
const REPRODUCIBLE_COMPILER_OPTIONS = ` 'VCCLCompilerTool': {
'AdditionalOptions': [
'/guard:cf',
'/sdl',
'/W3',
'/w34244',
'/w34267',
'/ZH:SHA_256',
'/Brepro',
'/experimental:deterministic'
]
}`
const LINKER_OPTIONS = ` 'VCLinkerTool': {
'AdditionalOptions': [
'/DYNAMICBASE',
@@ -12,7 +36,8 @@ const REPRODUCIBLE_LINKER_OPTIONS = ` 'VCLinkerTool': {
'AdditionalOptions': [
'/DYNAMICBASE',
'/guard:cf',
'/Brepro'
'/Brepro',
'/experimental:deterministic'
]
}`
@@ -22,10 +47,18 @@ export async function applyWindowsNodePtyBuildDeterminism({ nodePtyDirectory, tu
}
const bindingPath = join(nodePtyDirectory, 'binding.gyp')
const source = await readFile(bindingPath, 'utf8')
if (source.split(LINKER_OPTIONS).length !== 2 || source.includes("'/Brepro'")) {
throw new Error('node-pty Windows linker settings do not match the reviewed source')
if (
source.split(COMPILER_OPTIONS).length !== 2 ||
source.split(LINKER_OPTIONS).length !== 2 ||
source.includes("'/Brepro'") ||
source.includes("'/experimental:deterministic'")
) {
throw new Error('node-pty Windows build settings do not match the reviewed source')
}
// Why: MSVC otherwise embeds per-build timestamps/identities in the copied artifact binaries.
await writeFile(bindingPath, source.replace(LINKER_OPTIONS, REPRODUCIBLE_LINKER_OPTIONS), 'utf8')
// Why: ARM64 compiler output changes even with a reproducible linker unless both stages opt in.
const reproducibleSource = source
.replace(COMPILER_OPTIONS, REPRODUCIBLE_COMPILER_OPTIONS)
.replace(LINKER_OPTIONS, REPRODUCIBLE_LINKER_OPTIONS)
await writeFile(bindingPath, reproducibleSource, 'utf8')
return true
}
@@ -19,13 +19,24 @@ async function copiedSource() {
}
describe('SSH relay Windows node-pty build determinism', () => {
it('adds deterministic MSVC linking only to the copied Windows source', async () => {
it('adds deterministic MSVC compilation and linking only to the copied Windows source', async () => {
const directory = await copiedSource()
const repositorySource = await readFile(resolve('node_modules/node-pty/binding.gyp'), 'utf8')
await expect(
applyWindowsNodePtyBuildDeterminism({ nodePtyDirectory: directory, tuple: 'win32-arm64' })
).resolves.toBe(true)
const source = await readFile(join(directory, 'binding.gyp'), 'utf8')
expect(source.match(/'\/Brepro'/g)).toHaveLength(1)
const compilerStart = source.indexOf("'VCCLCompilerTool'")
const linkerStart = source.indexOf("'VCLinkerTool'")
const compilerOptions = source.slice(compilerStart, linkerStart)
const linkerOptions = source.slice(linkerStart)
expect(compilerOptions).toContain("'/Brepro'")
expect(compilerOptions).toContain("'/experimental:deterministic'")
expect(linkerOptions).toContain("'/Brepro'")
expect(linkerOptions).toContain("'/experimental:deterministic'")
expect(await readFile(resolve('node_modules/node-pty/binding.gyp'), 'utf8')).toBe(
repositorySource
)
})
it('leaves POSIX source untouched and rejects an unexpected Windows source shape', async () => {