feat: bundle private Windows runtimes with settings switches

This commit is contained in:
Codex committed 2026-10-21 16:31:24 +09:00
1 parent 759df7060d
commit bef87520c2
28 files changed
+902 -10

No files matched your search

+54
View File
@@ -0,0 +1,54 @@
// Downloads official pinned archives only. Never executes downloaded Windows files.
import fs from 'node:fs/promises'
import path from 'node:path'
import { spawnSync } from 'node:child_process'
import sevenZip from '7zip-bin'
import { transformRuntime } from './runtime-transform.mjs'
import { projectRoot, runtimeRoot, manifest, digest, inventory, verifyRuntimeBundle } from './runtime-bundle.mjs'
const cache = path.join(projectRoot, '.tmp/runtime-downloads')
await fs.mkdir(cache, { recursive: true })
const stage = await fs.mkdtemp(path.join(runtimeRoot, '.prepare-'))
try {
if (process.platform !== 'win32') await fs.chmod(sevenZip.path7za, 0o755)
for (const runtime of manifest.runtimes) {
const archive = path.join(cache, runtime.archive)
let bytes = await fs.readFile(archive).catch(() => null)
if (!bytes) {
console.log(`Downloading ${runtime.id} ${runtime.version} from ${runtime.url}`)
const response = await fetch(runtime.url, { signal: AbortSignal.timeout(300_000) })
if (!response.ok) throw new Error(`Download failed: ${response.status} ${runtime.url}`)
bytes = Buffer.from(await response.arrayBuffer())
}
if (digest(bytes, runtime.algorithm, runtime.digestEncoding) !== runtime.digest) throw new Error(`Archive integrity failure: ${runtime.id}; remove ${archive} to redownload`)
await fs.writeFile(archive, bytes)
const unpack = path.join(stage, `unpack-${runtime.id}`)
await fs.mkdir(unpack)
const result = spawnSync(sevenZip.path7za, ['x', archive, `-o${unpack}`, '-y'], { encoding: 'utf8', windowsHide: true })
if (result.error || result.status !== 0) throw new Error(`Archive extraction failed: ${runtime.id}: ${result.error || result.stderr || result.stdout}`)
const target = path.join(stage, runtime.id)
await fs.rename(path.join(unpack, runtime.prefix), target)
await transformRuntime(runtime.id, target)
// No loose mutation of the extraction lock. A source update requires reviewed tree digest changes.
const tree = digest(JSON.stringify(await inventory(target)))
if (runtime.treeSha256 && tree !== runtime.treeSha256) throw new Error(`Extracted ${runtime.id} tree mismatch: ${tree}`)
if (!runtime.treeSha256) throw new Error(`Unpinned ${runtime.id} extracted tree: ${tree}`)
}
await verifyRuntimeBundle(stage)
const destination = path.join(runtimeRoot, 'win32-x64')
const previous = `${destination}.previous`
await fs.rm(previous, { recursive: true, force: true })
const exists = await fs.stat(destination).then(() => true, () => false)
if (exists) await fs.rename(destination, previous)
try {
await fs.mkdir(destination)
for (const runtime of manifest.runtimes) await fs.rename(path.join(stage, runtime.id), path.join(destination, runtime.id))
} catch (error) {
await fs.rm(destination, { recursive: true, force: true })
if (exists) await fs.rename(previous, destination)
throw error
}
await fs.rm(previous, { recursive: true, force: true })
console.log('Windows x64 runtimes prepared; native Windows smoke tests still required.')
} finally {
await fs.rm(stage, { recursive: true, force: true })
}