From e2bcd6e09ca5259a10a25096e23b1165925e4916 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Wed, 21 Oct 2026 01:10:17 -0700 Subject: [PATCH] Reuse Windows server native prebuilds across app version bumps (#31450) * Measure Windows ARM qualification worker concurrency * Reuse Windows server prebuilds across app version bumps * Match native cache measurement to adhoc compiler settings * Keep measured cache fix and remove temporary comparison modes --- .../scripts/orcad-windows-prebuild-cache.mjs | 10 ++++++- .../orcad-windows-prebuild-cache.test.mjs | 26 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/config/scripts/orcad-windows-prebuild-cache.mjs b/config/scripts/orcad-windows-prebuild-cache.mjs index 3c3942ee544..de2112d0134 100644 --- a/config/scripts/orcad-windows-prebuild-cache.mjs +++ b/config/scripts/orcad-windows-prebuild-cache.mjs @@ -73,7 +73,15 @@ export function windowsPrebuildCacheIdentity({ } const digest = createHash('sha256').update(JSON.stringify({ slot, imageOS, imageVersion })) for (const file of WINDOWS_PREBUILD_CACHE_INPUTS) { - digest.update(`\0${file}\0`).update(readFileSync(join(repository, file))) + const bytes = readFileSync(join(repository, file)) + if (file === 'package.json') { + const manifest = JSON.parse(bytes.toString('utf8')) + // App versions do not affect the separately versioned node-pty binary. + delete manifest.version + digest.update(`\0${file}\0`).update(JSON.stringify(manifest)) + } else { + digest.update(`\0${file}\0`).update(bytes) + } } return { slot, diff --git a/config/scripts/orcad-windows-prebuild-cache.test.mjs b/config/scripts/orcad-windows-prebuild-cache.test.mjs index 3abe13a08bc..189a0cdf94f 100644 --- a/config/scripts/orcad-windows-prebuild-cache.test.mjs +++ b/config/scripts/orcad-windows-prebuild-cache.test.mjs @@ -242,6 +242,25 @@ describe('Windows server prebuild cache inputs', () => { ) }) + it('reuses native binaries across app versions but invalidates every other manifest field', () => { + const repository = mkdtempSync(join(tmpdir(), 'orca-prebuild-version-key-')) + temporary.push(repository) + const source = resolve(import.meta.dirname, '../..') + for (const relative of WINDOWS_PREBUILD_CACHE_INPUTS) { + mkdirSync(dirname(join(repository, relative)), { recursive: true }) + cpSync(join(source, relative), join(repository, relative)) + } + const path = join(repository, 'package.json') + const manifest = JSON.parse(readFileSync(path, 'utf8')) + const before = windowsPrebuildCacheIdentity({ ...options, repository }).key + writeFileSync(path, JSON.stringify({ ...manifest, version: '999.0.0' })) + expect(windowsPrebuildCacheIdentity({ ...options, repository }).key).toBe(before) + for (const field of Object.keys(manifest).filter((field) => field !== 'version')) { + writeFileSync(path, JSON.stringify({ ...manifest, [field]: 'changed' })) + expect(windowsPrebuildCacheIdentity({ ...options, repository }).key).not.toBe(before) + } + }) + it.each(WINDOWS_PREBUILD_CACHE_INPUTS)('invalidates a changed %s input', (file) => { const repository = mkdtempSync(join(tmpdir(), 'orca-prebuild-key-')) temporary.push(repository) @@ -253,7 +272,12 @@ describe('Windows server prebuild cache inputs', () => { const before = windowsPrebuildCacheIdentity({ ...options, repository }).key writeFileSync( join(repository, file), - `${readFileSync(join(repository, file), 'utf8')}\nchanged input` + file === 'package.json' + ? JSON.stringify({ + ...JSON.parse(readFileSync(join(repository, file), 'utf8')), + engines: { node: 'changed' } + }) + : `${readFileSync(join(repository, file), 'utf8')}\nchanged input` ) expect(windowsPrebuildCacheIdentity({ ...options, repository }).key).not.toBe(before) })