Files
orca/config/scripts/ci-unit-module-cache.mjs
T
Neil 39815a086f Reduce CI import, frame-capture, teardown, and shard costs (#28879)
* Avoid unused module imports and trim cosmetic test coverage

* Capture hidden popup frames and attach CDP before guest creation

* Overlap relay test projects within the existing worker budget

* Consolidate native preparation and add an opt-in transform cache comparison

* Release inherited debugger sockets during final E2E teardown

* Refresh unit scheduling weights from all five qualified ARM shards

* Avoid retaining unasserted RPC call history in the delivery model

* Use the supported unconditional background wait syntax

* Overlap unconditional output upload with native preparation

* Verify relay integration stays enabled for ordinary unit callers
2026-10-14 17:10:55 -07:00

240 lines
7.4 KiB
JavaScript

import { createHash } from 'node:crypto'
import {
appendFileSync,
existsSync,
globSync,
readFileSync,
realpathSync,
rmSync,
statSync
} from 'node:fs'
import { createRequire } from 'node:module'
import { join, resolve } from 'node:path'
import { performance } from 'node:perf_hooks'
import { pathToFileURL } from 'node:url'
import { runProcessSync } from '@orca/process-host'
import { collectNodeServerInputs } from './node-server-change-scope.mjs'
import { workspacePackageManifests } from './workspace-source-exports.mjs'
import { writeAssignment } from './ci-shard-assignment.mjs'
import { sealModuleCache, validateModuleCache } from './ci-unit-module-cache-contents.mjs'
const ROOT = resolve(import.meta.dirname, '../..')
const IDENTITY_REPORT = 'ci-shards/unit-module-cache-identity.json'
const CACHE_REPORT = 'ci-shards/unit-module-cache.json'
const CACHE_FORMAT = '1.0.0-beta.8'
function digestInputs(root, files) {
const hash = createHash('sha256')
for (const file of [...new Set(files)].sort()) {
if (!existsSync(join(root, file))) {
hash.update(`${file}\0missing\0`)
continue
}
const bytes = readFileSync(join(root, file))
hash.update(`${file}\0${bytes.length}\0`).update(bytes)
}
return hash.digest('hex')
}
export async function moduleCachePolicyHash(root = ROOT) {
const runnerScripts = globSync('config/scripts/vitest*.{mjs,ts}', { cwd: root }).filter(
(file) => !file.includes('.test.')
)
const configInputs = await collectNodeServerInputs({
root,
entryPoints: [
'config/vitest.config.ts',
'config/scripts/run-vitest.mjs',
'config/scripts/ci-unit-timing-reporter.mjs',
...runnerScripts
]
})
return digestInputs(root, [
...configInputs,
...workspacePackageManifests(root),
...globSync(['config/patches/**', '**/tsconfig*.json'], {
cwd: root,
exclude: ['**/node_modules/**', '**/.git/**', '**/dist/**', '**/out/**', 'mobile/vendor/**']
}).filter((file) => statSync(join(root, file)).isFile()),
'package.json',
'pnpm-lock.yaml',
'pnpm-workspace.yaml',
'.npmrc',
'.pnpmfile.cjs',
'config/.bun-version',
'config/scripts/ci-unit-module-cache.mjs',
'config/scripts/ci-unit-module-cache-contents.mjs',
'config/scripts/ci-unit-module-cache-trailer.mjs'
])
}
export function moduleCacheIdentity({
root = ROOT,
cacheRoot = process.env.RUNNER_TEMP,
policyHash,
installedLockHash,
versions,
shard,
platform = process.platform,
arch = process.arch,
nodeEnv = process.env.NODE_ENV ?? 'test',
namespace = ''
}) {
if (
!cacheRoot ||
!/^[a-f0-9]{64}$/.test(policyHash ?? '') ||
!/^[a-f0-9]{64}$/.test(installedLockHash ?? '') ||
![versions?.node, versions?.bun, versions?.vitest].every((version) =>
/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/.test(version ?? '')
) ||
!Number.isInteger(shard?.index) ||
!Number.isInteger(shard?.count) ||
shard.index < 1 ||
shard.index > shard.count
) {
throw new Error('Unit module cache identity is incomplete')
}
const identity = {
format: CACHE_FORMAT,
root: realpathSync(root),
platform,
arch,
versions,
policyHash,
installedLockHash,
nodeEnv,
shard,
namespace
}
const digest = createHash('sha256').update(JSON.stringify(identity)).digest('hex')
return {
...identity,
key: `unit-module-v1-${platform}-${arch}-n${versions.node}-b${versions.bun}-v${versions.vitest}-s${shard.index}of${shard.count}-${digest}`,
path: join(resolve(cacheRoot), 'orca-vitest-module-cache')
}
}
export async function resolveModuleCacheIdentity({
root = ROOT,
cacheRoot = process.env.RUNNER_TEMP,
shard,
namespace = ''
} = {}) {
const require = createRequire(join(root, 'package.json'))
const bun = runProcessSync({ program: 'bun', args: ['--version'], cwd: root, timeoutMs: 10_000 })
if (bun.code !== 0) {
throw new Error('Bun version is unavailable')
}
return moduleCacheIdentity({
root,
cacheRoot,
shard,
namespace,
policyHash: await moduleCachePolicyHash(root),
installedLockHash: createHash('sha256')
.update(readFileSync(join(root, 'node_modules', '.pnpm', 'lock.yaml')))
.digest('hex'),
versions: {
node: process.versions.node,
bun: bun.stdout.trim(),
vitest: require('vitest/package.json').version
}
})
}
export async function prepareModuleCache(identity, { restoreHit = false } = {}) {
const started = performance.now()
try {
if (!restoreHit) {
throw new Error('No exact cache was restored')
}
const manifest = await validateModuleCache({
path: identity.path,
key: identity.key,
format: identity.format,
versions: identity.versions,
lockfileHash: identity.installedLockHash.slice(0, 8)
})
return {
available: true,
entries: manifest.entries.length,
bytes: manifest.totalBytes,
producerSourceSha: manifest.sourceSha,
validationMs: performance.now() - started
}
} catch (error) {
rmSync(identity.path, { recursive: true, force: true })
return {
available: false,
reason: String(error),
validationMs: performance.now() - started
}
}
}
export async function finishModuleCache(identity, { sourceSha } = {}) {
const started = performance.now()
const manifest = await sealModuleCache({
...identity,
sourceSha,
lockfileHash: identity.installedLockHash.slice(0, 8)
})
return {
entries: manifest.entries.length,
bytes: manifest.totalBytes,
sealMs: performance.now() - started
}
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
const phase = process.argv[2]
const output = (values) => {
if (process.env.GITHUB_OUTPUT) {
for (const [key, value] of Object.entries(values)) {
appendFileSync(process.env.GITHUB_OUTPUT, `${key}=${value}\n`)
}
}
}
if (phase === 'identity') {
try {
const identity = await resolveModuleCacheIdentity({
shard: {
index: Number(process.env.ORCA_UNIT_SHARD_INDEX),
count: Number(process.env.ORCA_UNIT_SHARD_COUNT)
},
namespace: process.env.ORCA_UNIT_CACHE_NAMESPACE ?? ''
})
writeAssignment(IDENTITY_REPORT, identity)
output({ key: identity.key, path: identity.path })
if (process.env.GITHUB_ENV) {
appendFileSync(process.env.GITHUB_ENV, `ORCA_UNIT_MODULE_CACHE_PATH=${identity.path}\n`)
}
} catch (error) {
console.warn(`Unit module cache unavailable: ${String(error)}`)
}
} else {
const identity = JSON.parse(readFileSync(IDENTITY_REPORT, 'utf8'))
if (phase === 'prepare') {
const result = await prepareModuleCache(identity, {
restoreHit: process.env.ORCA_UNIT_CACHE_RESTORE_HIT === 'true'
})
writeAssignment(CACHE_REPORT, { key: identity.key, mode: 'restore', ...result })
console.log(JSON.stringify(result))
} else if (phase === 'seal') {
try {
const result = await finishModuleCache(identity, {
sourceSha: process.env.ORCA_SHARD_SOURCE_SHA ?? process.env.GITHUB_SHA
})
const previous = JSON.parse(readFileSync(CACHE_REPORT, 'utf8'))
writeAssignment(CACHE_REPORT, { ...previous, produced: result })
output({ ready: true })
console.log(JSON.stringify(result))
} catch (error) {
console.warn(`Unit module cache was not saved: ${String(error)}`)
}
} else {
throw new Error(`Unknown unit module cache phase: ${phase}`)
}
}
}