Files
orca/config/scripts/ssh-relay-runtime-workflow.test.mjs
T
2026-07-15 01:30:16 -04:00

351 lines
18 KiB
JavaScript

import { readFile } from 'node:fs/promises'
import { parse } from 'yaml'
import { describe, expect, it } from 'vitest'
const workflowUrl = new URL(
'../../.github/workflows/ssh-relay-runtime-artifacts.yml',
import.meta.url
)
const linuxBuilderUrl = new URL('../ssh-relay-runtime-linux-builder.Containerfile', import.meta.url)
function normalizeCheckoutNewlines(source) {
return source.replaceAll('\r\n', '\n')
}
describe('SSH relay runtime artifact workflow', () => {
it('normalizes Windows checkout newlines for text contracts', () => {
expect(normalizeCheckoutNewlines('first\r\nsecond\r\n')).toBe('first\nsecond\n')
})
it('uses exact native runner labels and SHA-pinned actions without publication authority', async () => {
const workflow = parse(await readFile(workflowUrl, 'utf8'))
const posixJob = workflow.jobs['build-posix-runtime']
const windowsJob = workflow.jobs['build-windows-runtime']
expect(posixJob.strategy.matrix.include.map((entry) => [entry.runner, entry.tuple])).toEqual([
['ubuntu-24.04', 'linux-x64-glibc'],
['ubuntu-24.04-arm', 'linux-arm64-glibc'],
['macos-15-intel', 'darwin-x64'],
['macos-15', 'darwin-arm64']
])
expect(
posixJob.strategy.matrix.include.slice(0, 2).map((entry) => entry.container_image)
).toEqual([
'docker.io/library/rockylinux@sha256:2d05a9266523bbf24f33ebc3a9832e4d5fd74b973c220f2204ca802286aa275d',
'docker.io/library/rockylinux@sha256:3c2d0ce12bf79fc5ff05e43b1000e30ff062dc89405525f3307cbff71661f1a0'
])
expect(windowsJob.strategy.matrix.include.map((entry) => [entry.runner, entry.tuple])).toEqual([
['windows-2022', 'win32-x64'],
['windows-11-arm', 'win32-arm64']
])
expect(workflow.permissions).toEqual({ contents: 'read' })
expect(posixJob['timeout-minutes']).toBe(20)
expect(windowsJob['timeout-minutes']).toBe(30)
for (const job of [posixJob, windowsJob]) {
expect(job.env.ORCA_RUNTIME_REQUESTED_RUNNER).toBe('${{ matrix.runner }}')
expect(job.steps[0].with.ref).toBe('${{ github.event.pull_request.head.sha || github.sha }}')
for (const step of job.steps.filter((candidate) => candidate.uses)) {
expect(step.uses).toMatch(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+@[0-9a-f]{40}$/)
}
}
})
it('uploads only the first output after two clean builds verify and compare', async () => {
const source = await readFile(workflowUrl, 'utf8')
const workflow = parse(source)
const steps = workflow.jobs['build-posix-runtime'].steps
const windowsSteps = workflow.jobs['build-windows-runtime'].steps
const buildIndex = steps.findIndex(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
)
const uploadIndex = steps.findIndex(
(step) => step.name === 'Upload unpublished artifact evidence'
)
expect(buildIndex).toBeGreaterThan(-1)
expect(uploadIndex).toBeGreaterThan(buildIndex)
expect(source).toContain('verify-ssh-relay-runtime.mjs')
expect(source).toContain('ssh-relay-runtime-workflow.test.mjs')
expect(source).toContain('pnpm install --frozen-lockfile --ignore-scripts')
expect(source).toContain('--connect-timeout 20 --max-time 300 --retry 2')
expect(source).toContain('mkdir -p "$output_root"')
expect(source).toContain('source_commit=$(git rev-parse HEAD)')
expect(source).toContain('--git-commit "$source_commit"')
expect(source).not.toContain('--git-commit "$GITHUB_SHA"')
expect(source).toContain('for output in "$first_output" "$second_output"')
expect(source).toContain('foreach ($output in @($firstOutput, $secondOutput))')
expect(source).toContain('ssh-relay-runtime-reproducibility.mjs')
expect(source).toContain('ssh-relay-runtime-reproducibility.test.mjs')
expect(source.match(/ssh-relay-runtime-closure\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-sbom\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-provenance\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-toolchain\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-native-signing-plan\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-native-signing-selection\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-native-signing-payload\.test\.mjs/g)).toHaveLength(4)
expect(
source.match(/ssh-relay-runtime-windows-authenticode-assessment\.test\.mjs/g)
).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-native-signing-stage\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-native-signing-apply\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/ssh-relay-runtime-macos-signature-verification\.test\.mjs/g)).toHaveLength(
4
)
expect(
source.match(/ssh-relay-runtime-windows-signature-verification\.test\.mjs/g)
).toHaveLength(4)
for (const moduleName of [
'windows-source-signature-verification',
'release-stage-gate',
'draft-recovery',
'aggregate-input',
'draft-readback'
]) {
const script = `ssh-relay-runtime-${moduleName}`
expect(source.split(`${script}.test.mjs`)).toHaveLength(5)
expect(source.split(`node --check config/scripts/${script}.mjs`)).toHaveLength(3)
}
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-native-signing-plan\.mjs/g)
).toHaveLength(2)
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-native-signing-selection\.mjs/g)
).toHaveLength(2)
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-native-signing-payload\.mjs/g)
).toHaveLength(2)
expect(
source.match(
/node --check config\/scripts\/ssh-relay-runtime-windows-authenticode-assessment\.mjs/g
)
).toHaveLength(2)
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-native-signing-stage\.mjs/g)
).toHaveLength(2)
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-native-signing-apply\.mjs/g)
).toHaveLength(2)
expect(
source.match(
/node --check config\/scripts\/ssh-relay-runtime-macos-signature-verification\.mjs/g
)
).toHaveLength(2)
expect(
source.match(
/node --check config\/scripts\/ssh-relay-runtime-windows-signature-verification\.mjs/g
)
).toHaveLength(2)
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-closure\.mjs/g)
).toHaveLength(2)
expect(source).toContain('ssh-relay-runtime-windows-pe-diagnostic.mjs')
expect(source).toContain('ssh-relay-runtime-windows-pe-diagnostic.test.mjs')
expect(source).toContain('llvm-objdump.exe')
expect(source).toContain('--start-address=0x180001000 --stop-address=0x180001200')
expect(source).toContain(
'node --check config/scripts/ssh-relay-runtime-reproducibility.test.mjs'
)
expect(
source.match(/node --check config\/scripts\/build-ssh-relay-runtime\.mjs/g)
).toHaveLength(2)
expect(
source.match(/node --check config\/scripts\/ssh-relay-runtime-build\.test\.mjs/g)
).toHaveLength(2)
expect(source.match(/ssh-relay-node-pty-build\.test\.mjs/g)).toHaveLength(2)
expect(source.match(/ssh-relay-node-pty-windows-build-determinism\.test\.mjs/g)).toHaveLength(2)
expect(source.match(/ssh-relay-runtime-build\.test\.mjs/g)).toHaveLength(4)
expect(source.match(/--work-directory/g)).toHaveLength(3)
expect(source).toContain('work_directory="$RUNNER_TEMP/orca-ssh-relay-runtime-build-work"')
expect(source).toContain(
"$workDirectory = Join-Path $env:RUNNER_TEMP 'orca-ssh-relay-runtime-build-work'"
)
expect(source).not.toContain('work_directory="$output_root/build-work"')
expect(source).not.toContain("Join-Path $outputRoot 'build-work'")
expect(source).toContain('cp "$first_output"/*.tar.xz')
expect(source).toContain("Get-ChildItem -LiteralPath $firstOutput -Filter '*.zip'")
expect(source).toContain('ssh-relay-node-zip-inspection.test.mjs')
expect(source).toContain('ssh-relay-runtime-pty-smoke.test.mjs')
expect(source).toContain('ssh-relay-runtime-resource-diagnostics.test.mjs')
expect(source).toContain('ssh-relay-runtime-zip.test.mjs')
expect(source).toContain('node-v24.18.0-headers.tar.gz')
expect(source).toContain('node_library: win-x64/node.lib')
expect(source).toContain("@('gpg.exe', 'gpgv.exe')")
for (const jobSteps of [steps, windowsSteps]) {
const run = jobSteps.find(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
).run
expect(run.indexOf('ssh-relay-runtime-reproducibility.mjs')).toBeGreaterThan(
run.indexOf('verify-ssh-relay-runtime.mjs')
)
expect(run.lastIndexOf('runtime-evidence/${{ matrix.tuple }}')).toBeGreaterThan(
run.indexOf('ssh-relay-runtime-reproducibility.mjs')
)
}
const windowsRun = windowsSteps.find(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
).run
expect(windowsRun.indexOf('ssh-relay-runtime-windows-pe-diagnostic.mjs')).toBeGreaterThan(
windowsRun.indexOf('ssh-relay-runtime-reproducibility.mjs')
)
expect(windowsRun.indexOf('llvm-objdump.exe')).toBeGreaterThan(
windowsRun.indexOf('ssh-relay-runtime-windows-pe-diagnostic.mjs')
)
expect(
windowsRun.indexOf("throw 'runtime reproducibility verification failed'")
).toBeGreaterThan(windowsRun.indexOf('llvm-objdump.exe'))
expect(windowsRun.indexOf('runtime-evidence/${{ matrix.tuple }}')).toBeGreaterThan(
windowsRun.indexOf("throw 'runtime reproducibility verification failed'")
)
expect(steps[uploadIndex].with.path).toBe('runtime-evidence/${{ matrix.tuple }}/')
expect(source).not.toMatch(/releases\/|gh release|contents:\s*write/i)
})
it('assesses and stages real first-build candidates without signing authority', async () => {
const source = await readFile(workflowUrl, 'utf8')
const workflow = parse(source)
const posixRun = workflow.jobs['build-posix-runtime'].steps.find(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
).run
const windowsRun = workflow.jobs['build-windows-runtime'].steps.find(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
).run
expect(posixRun.match(/ssh-relay-runtime-native-signing-stage\.mjs/g)).toHaveLength(2)
expect(windowsRun.match(/ssh-relay-runtime-native-signing-stage\.mjs/g)).toHaveLength(1)
expect(posixRun.indexOf('ssh-relay-runtime-native-signing-stage.mjs')).toBeGreaterThan(
posixRun.indexOf('ssh-relay-runtime-linux-build-evidence.mjs')
)
expect(posixRun.lastIndexOf('ssh-relay-runtime-native-signing-stage.mjs')).toBeGreaterThan(
posixRun.indexOf('ssh-relay-runtime-reproducibility.mjs')
)
expect(windowsRun.indexOf('ssh-relay-runtime-native-signing-stage.mjs')).toBeGreaterThan(
windowsRun.indexOf('ssh-relay-runtime-reproducibility.mjs')
)
expect(posixRun).toContain('Linux signing-stage report violates the hash-only contract')
expect(posixRun).toContain('macOS signing-stage report violates the Developer ID contract')
expect(posixRun).toContain('test ! -e "$signing_stage/bin/node"')
expect(windowsRun).toContain('Windows signing-stage report violates the Authenticode contract')
expect(windowsRun).toContain('@($report.signingFiles).Count -ne 3')
expect(windowsRun).toContain('@($report.preservedUpstreamFiles).Count -ne 2')
expect(windowsRun).toContain('Required upstream signature was not preserved')
expect(windowsRun).toContain("Join-Path $signingStage 'bin/node.exe'")
expect(windowsRun).toContain('ssh-relay-runtime-windows-source-signature-verification.mjs')
expect(
windowsRun.indexOf('ssh-relay-runtime-windows-source-signature-verification.mjs')
).toBeGreaterThan(windowsRun.indexOf('ssh-relay-runtime-native-signing-stage.mjs'))
expect(
windowsRun.indexOf('ssh-relay-runtime-windows-source-signature-verification.mjs')
).toBeLessThan(windowsRun.indexOf('Remove-Item -LiteralPath $signingStage'))
expect(windowsRun).toContain(
'Windows source signature report violates the immutable/preserved trust contract'
)
expect(windowsRun).toContain("$_.signerKind -eq 'official-node'")
expect(windowsRun).toContain("$_.signerKind -eq 'preserved-upstream'")
expect(source.match(/\.signing-stage\.json/g)).toHaveLength(3)
expect(source.match(/\.source-signatures\.json/g)).toHaveLength(1)
expect(source).not.toMatch(/SIGNPATH_|APPLE_(?:ID|KEY)|Developer ID Application/)
})
it('builds Linux native modules in the pinned oldest userland with an offline build phase', async () => {
const source = await readFile(workflowUrl, 'utf8')
const workflow = parse(source)
const job = workflow.jobs['build-posix-runtime']
const prepare = job.steps.find(
(step) => step.name === 'Prepare digest-pinned Linux floor builder'
)
const build = job.steps.find(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
)
const containerfile = await readFile(linuxBuilderUrl, 'utf8')
// Why: Git may materialize CRLF on Windows, but the Containerfile contract is newline-agnostic.
const normalizedContainerfile = normalizeCheckoutNewlines(containerfile)
expect(prepare.if).toBe("runner.os == 'Linux'")
expect(prepare.run).toContain('docker pull "$image"')
expect(prepare.run).toContain('--pull=false')
expect(prepare.run).toContain('config/ssh-relay-runtime-linux-builder.Containerfile')
expect(build.run).toContain("if [[ '${{ matrix.tuple }}' == linux-* ]]")
expect(build.run).toContain('--network none --read-only --cap-drop all')
expect(build.run).toContain('--user "$(id -u):$(id -g)"')
expect(build.run).toContain('--security-opt no-new-privileges')
expect(build.run).toContain('--tmpfs /tmp:rw,nosuid,size=1g,mode=1777')
expect(build.run).toContain('ssh-relay-runtime-linux-build-evidence.mjs')
expect(build.run.indexOf('--network none')).toBeLessThan(
build.run.indexOf('ssh-relay-runtime-linux-build-evidence.mjs')
)
expect(normalizedContainerfile).toContain('ARG BASE_IMAGE=scratch\nFROM ${BASE_IMAGE}')
expect(normalizedContainerfile).toContain("getconf GNU_LIBC_VERSION)\" = 'glibc 2.28'")
expect(normalizedContainerfile).toContain('libstdc++.so.6.0.25')
expect(normalizedContainerfile).toContain('dnf module enable -y -q nodejs:20')
expect(normalizedContainerfile).toContain('Number(process.versions.node.split')
expect(normalizedContainerfile).toContain('python39')
expect(normalizedContainerfile).toContain('NODE_GYP_FORCE_PYTHON=/usr/bin/python3.9')
expect(normalizedContainerfile).toContain(' which \\\n')
expect(source).not.toMatch(/releases\/|gh release|contents:\s*write/i)
})
it('separates qualifying Windows floors from supplemental Linux userland evidence', async () => {
const source = await readFile(workflowUrl, 'utf8')
const workflow = parse(source)
const linuxJob = workflow.jobs['verify-linux-runtime-baseline-userland']
const windowsJob = workflow.jobs['verify-windows-runtime-baseline']
expect(linuxJob.needs).toBe('build-posix-runtime')
expect(windowsJob.needs).toBe('build-windows-runtime')
expect(linuxJob.strategy.matrix.include).toEqual([
{
runner: 'ubuntu-24.04',
tuple: 'linux-x64-glibc',
container_image:
'docker.io/library/rockylinux@sha256:2d05a9266523bbf24f33ebc3a9832e4d5fd74b973c220f2204ca802286aa275d'
},
{
runner: 'ubuntu-24.04-arm',
tuple: 'linux-arm64-glibc',
container_image:
'docker.io/library/rockylinux@sha256:3c2d0ce12bf79fc5ff05e43b1000e30ff062dc89405525f3307cbff71661f1a0'
}
])
expect(windowsJob.strategy.matrix.include).toEqual([
{ runner: 'windows-2022', tuple: 'win32-x64' },
{ runner: 'windows-11-arm', tuple: 'win32-arm64' }
])
for (const job of [linuxJob, windowsJob]) {
expect(job.env.ORCA_RUNTIME_REQUESTED_RUNNER).toBe('${{ matrix.runner }}')
expect(job['timeout-minutes']).toBe(15)
expect(job.steps[0].with.ref).toBe('${{ github.event.pull_request.head.sha || github.sha }}')
for (const step of job.steps.filter((candidate) => candidate.uses)) {
expect(step.uses).toMatch(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+@[0-9a-f]{40}$/)
}
}
const linuxRun = linuxJob.steps.find(
(step) => step.name === 'Prove oldest Linux userland and retain the kernel gap'
).run
expect(linuxRun).toContain('--scope linux-userland')
expect(linuxRun).toContain('--network none')
expect(linuxRun).toContain('--read-only --cap-drop all')
expect(linuxRun).toContain('--security-opt no-new-privileges')
expect(linuxRun).toContain('ssh-relay-runtime-smoke-child.cjs')
expect(linuxRun).not.toContain('--scope full')
const linuxVerification = linuxJob.steps.find(
(step) => step.name === 'Verify bytes before supplemental baseline execution'
).run
expect(linuxVerification).toContain('${#identities[@]} != 1')
expect(linuxVerification).toContain('${#archives[@]} != 1')
const windowsRun = windowsJob.steps.find(
(step) => step.name === 'Verify bytes and execute on the declared Windows floor'
).run
expect(windowsRun.indexOf('verify-ssh-relay-runtime.mjs')).toBeLessThan(
windowsRun.indexOf('ssh-relay-runtime-baseline.mjs')
)
expect(windowsRun).toContain('--scope full')
expect(windowsRun).toContain('$identities.Count -ne 1')
expect(windowsRun).toContain('$archives.Count -ne 1')
expect(source).not.toMatch(/releases\/|gh release|contents:\s*write/i)
})
})