Files
orca/config/scripts/package-electron-runtime-contract.test.mjs
T
Jinwoo Hong a5f7da4928 revert(daemon): ship official Node in the macOS terminal host again, keep stall telemetry (#33688)
Reverts #29133 except its daemon async-I/O stall telemetry, so we can measure how often stalls happen on official Node before committing to a patched runtime. The macOS terminal host goes back to the official Node 24.22.1 download and the daemon protocol back to v51; no release or hourly build published v52.
2026-10-25 20:07:30 -04:00

210 lines
9.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { existsSync, readFileSync } from 'node:fs'
import { createRequire } from 'node:module'
import { join, resolve } from 'node:path'
import { runInNewContext } from 'node:vm'
import { describe, expect, it } from 'vitest'
import { parse } from 'yaml'
import { compileAggregateExpression } from './pr-aggregate-gate-context.mjs'
const projectDir = resolve(import.meta.dirname, '../..')
const require = createRequire(import.meta.url)
const { createPackagedRuntimeNodeModuleResources } = require('../packaged-runtime-node-modules.cjs')
const readProject = (file) => readFileSync(join(projectDir, file), 'utf8')
const packageJson = JSON.parse(readProject('package.json'))
const pnpmWorkspace = parse(readProject('pnpm-workspace.yaml'))
// Resolve the win32 plan wherever its OS-gated addon is installed; windows-registry is a workspace link on every platform.
const windowsAddonsInstalled = existsSync(
join(projectDir, 'node_modules', '@vscode', 'windows-process-tree', 'package.json')
)
describe('Electron runtime package contract', () => {
const packageTargets = {
win32: windowsAddonsInstalled ? createPackagedRuntimeNodeModuleResources('win32') : [],
darwin: createPackagedRuntimeNodeModuleResources('darwin'),
linux: createPackagedRuntimeNodeModuleResources('linux')
}
it('keeps the native Windows registry addon optional and platform-gated', () => {
expect(packageJson.optionalDependencies['@orca/windows-registry']).toBe('workspace:*')
// allowBuilds suppresses install-time node-gyp; the Windows rebuild owns the addon’s runtime ABI.
expect(pnpmWorkspace.allowBuilds['@orca/windows-registry']).toBe(false)
if (windowsAddonsInstalled) {
expect(packageTargets.win32).toEqual(
expect.arrayContaining([
expect.objectContaining({ to: join('node_modules', '@orca', 'windows-registry') }),
expect.objectContaining({ to: join('node_modules', 'node-addon-api') })
])
)
}
for (const platform of ['darwin', 'linux']) {
expect(packageTargets[platform]).not.toEqual(
expect.arrayContaining([
expect.objectContaining({ to: join('node_modules', '@orca', 'windows-registry') })
])
)
}
})
// Without it the secure-file writes report unrestricted and orcad's privacy check fails closed.
it('ships the native Windows ACL addon on Windows only, built by the Windows rebuild', () => {
expect(packageJson.optionalDependencies['@orca/windows-security']).toBe('workspace:*')
expect(pnpmWorkspace.allowBuilds['@orca/windows-security']).toBe(false)
if (windowsAddonsInstalled) {
expect(packageTargets.win32).toEqual(
expect.arrayContaining([
expect.objectContaining({ to: join('node_modules', '@orca', 'windows-security') })
])
)
}
for (const platform of ['darwin', 'linux']) {
expect(packageTargets[platform]).not.toEqual(
expect.arrayContaining([
expect.objectContaining({ to: join('node_modules', '@orca', 'windows-security') })
])
)
}
})
it('keeps the native Windows process-table addon optional and platform-gated', () => {
expect(packageJson.optionalDependencies['@vscode/windows-process-tree']).toBe('0.8.0')
// As with registry, suppress install-time node-gyp so the Windows rebuild selects the runtime ABI.
expect(pnpmWorkspace.allowBuilds['@vscode/windows-process-tree']).toBe(false)
// Patch removes unavailable Spectre-library requirement and 1024-process enumeration cap that hides descendants on busy hosts.
expect(pnpmWorkspace.patchedDependencies['@vscode/windows-process-tree@0.8.0']).toBe(
'config/patches/@vscode__windows-process-tree@0.8.0.patch'
)
if (windowsAddonsInstalled) {
expect(packageTargets.win32).toEqual(
expect.arrayContaining([
expect.objectContaining({ to: join('node_modules', '@vscode', 'windows-process-tree') })
])
)
}
for (const platform of ['darwin', 'linux']) {
expect(packageTargets[platform]).not.toEqual(
expect.arrayContaining([
expect.objectContaining({ to: join('node_modules', '@vscode', 'windows-process-tree') })
])
)
}
})
it('keeps release-cut signing provenance on GitHub-hosted runners', () => {
const releaseWorkflow = parse(
readFileSync(join(projectDir, '.github/workflows/release-cut.yml'), 'utf8')
)
const buildMatrixRunners = releaseWorkflow.jobs.build.strategy.matrix.include.map(
({ os }) => os
)
const releaseWorkflowText = readFileSync(
join(projectDir, '.github/workflows/release-cut.yml'),
'utf8'
)
const macDispatchStep = releaseWorkflow.jobs['build-mac'].steps.find(
(step) => step.name === 'Run isolated macOS release build'
)
expect(releaseWorkflowText).not.toContain('blacksmith-')
for (const caller of Object.values(releaseWorkflow.jobs)) {
if (!caller.uses?.startsWith('./.github/workflows/')) {
continue
}
const child = parse(readProject(caller.uses))
const inputs = {
...Object.fromEntries(
Object.entries(child.on.workflow_call.inputs).map(([name, input]) => [
name,
input.default ?? ''
])
),
...caller.with
}
for (const job of Object.values(child.jobs)) {
if (!job['runs-on']) {
continue
}
const runner = job['runs-on'].startsWith('${{')
? compileAggregateExpression(job['runs-on'], ['inputs'])({ inputs }).coerceString()
: job['runs-on']
expect(runner).not.toMatch(/^(blacksmith-|orca-)/)
}
}
expect(releaseWorkflow.jobs['build-mac']['runs-on']).toBe('ubuntu-latest')
expect(releaseWorkflow.jobs['build-mac'].permissions.actions).toBe('write')
expect(macDispatchStep.run).toBe(
'node config/scripts/run-release-mac-build-workflow.mjs dispatch'
)
expect(macDispatchStep.env.RELEASE_MAC_BUILD_WORKFLOW).toBe('release-mac-build.yml')
expect(macDispatchStep.env.RELEASE_MAC_BUILD_TAG).toBe('${{ needs.cut.outputs.tag }}')
expect(buildMatrixRunners).not.toContain('blacksmith-6vcpu-macos-15')
expect(releaseWorkflow.jobs['publish-release'].needs).toContain('build')
expect(releaseWorkflow.jobs['publish-release'].needs).toContain('build-mac')
expect(releaseWorkflow.jobs['publish-release'].needs).toContain('verify-mac-build')
const macVerification = releaseWorkflow.jobs['verify-mac-build']
expect(macVerification.needs).toEqual(['cut', 'build-mac', 'build'])
expect(macVerification.if).toContain('!cancelled()')
expect(macVerification.if).not.toContain('needs.build.result')
expect(macVerification.permissions).toEqual({ actions: 'read', contents: 'read' })
expect(releaseWorkflow.jobs['publish-release'].if).toContain(
"needs.verify-mac-build.result == 'success'"
)
})
it('qualifies macOS after failed sibling builds and publishes only complete successful builds', () => {
const { jobs } = parse(readProject('.github/workflows/release-cut.yml'))
const evaluate = (source, needs, cancelled) =>
runInNewContext(source.replace(/needs\.([a-z][a-z0-9-]*)/g, 'needs["$1"]'), {
needs,
cancelled: () => cancelled,
contains: (value, part) => value.includes(part)
})
const results = ['success', 'failure', 'skipped', 'cancelled']
for (const matrix of results) {
for (const dispatch of results) {
for (const verification of results) {
for (const cancelled of [false, true]) {
const needs = {
cut: { result: 'success', outputs: { should_release: 'true', tag: 'v1.5.0' } },
build: { result: matrix },
'build-mac': { result: dispatch },
'verify-mac-build': { result: verification },
'skill-sharing-linux-floor-release-gate': { result: 'success' },
'skill-sharing-release-gate': { result: 'success' },
'terminal-rendering-golden': { result: 'success' }
}
expect(evaluate(jobs['verify-mac-build'].if, needs, cancelled)).toBe(
!cancelled && dispatch === 'success'
)
expect(evaluate(jobs['publish-release'].if, needs, cancelled)).toBe(
!cancelled &&
matrix === 'success' &&
dispatch === 'success' &&
verification === 'success'
)
}
}
}
}
for (const prerequisite of [
'cut',
'skill-sharing-linux-floor-release-gate',
'skill-sharing-release-gate',
'terminal-rendering-golden'
]) {
const needs = Object.fromEntries([
['cut', { result: 'success', outputs: { should_release: 'true', tag: 'v1.5.0' } }],
...[
'build',
'build-mac',
'verify-mac-build',
'skill-sharing-linux-floor-release-gate',
'skill-sharing-release-gate',
'terminal-rendering-golden'
].map((name) => [name, { result: 'success' }])
])
needs[prerequisite].result = 'failure'
expect(evaluate(jobs['publish-release'].if, needs, false)).toBe(false)
}
})
})