Files
orca/config/scripts/package-electron-runtime-contract.test.mjs
T
Neil 65e513b193 fix(daemon): recover lost macOS worker wake-ups in the packaged terminal runtime (#29133)
Builds the macOS terminal host's Node 24.22.1 from pinned source with a libuv patch: idle threadpool workers recheck for queued work every 30 s instead of waiting forever, so a lost Darwin condition-variable wake-up (libuv #5280) no longer strands terminal I/O. Bumps the daemon protocol to v52 so new terminals start on the patched runtime right after an update; older daemons stay attachable. Adds stalled/recovered daemon async-I/O telemetry, and lets release workflows rebuild older refs that predate the source build.

Fixes STA-11709, #31926.
2026-10-25 17:28:34 -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'])
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)
}
})
})