mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
270 lines
8.8 KiB
JavaScript
Executable File
270 lines
8.8 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
// Exercise packaged CLI paths under the hostile Linux conditions from #11609/#12530/#13719/#14229.
|
||
import { execFileSync } from 'node:child_process'
|
||
import { existsSync } from 'node:fs'
|
||
import { resolve } from 'node:path'
|
||
|
||
const commandArgs = process.argv.slice(2)
|
||
const appImageArg = valueAfter('--appimage')
|
||
const appImage = appImageArg ? resolve(appImageArg) : null
|
||
const platform = valueAfter('--platform')
|
||
const dockerPlatformArgs = platform ? ['--platform', platform] : []
|
||
|
||
const suffix = `${process.pid}-${Date.now()}`
|
||
const artifactVolume = `orca-cli-contract-artifact-${suffix}`
|
||
const tagArchitecture = platform?.split('/')[1] ?? process.arch
|
||
const tag = `orca-cli-launch-contract:ubuntu-24.04-${tagArchitecture}-${suffix}`
|
||
const containers = new Set()
|
||
let artifactVolumeCreated = false
|
||
const CASE_TIMEOUT_MS = 90_000
|
||
const BUILD_TIMEOUT_MS = 10 * 60_000
|
||
const STAGING_TIMEOUT_MS = 5 * 60_000
|
||
const DOCKER_TIMEOUT_MS = 2 * 60_000
|
||
const CLEANUP_TIMEOUT_MS = 30_000
|
||
|
||
// Exact statuses reject silent no-op launches as well as crashes.
|
||
const CASES = [
|
||
{
|
||
name: 'nofuse-userns-bundled-help',
|
||
expectStatus: 0,
|
||
expectOutput: 'Usage: orca <command>',
|
||
why: 'The bundled launcher must run with no FUSE, no display, and userns restricted (#11609, #12530).'
|
||
},
|
||
{
|
||
name: 'nofuse-userns-bundled-version',
|
||
expectStatus: 0,
|
||
expectOutput: /^\d+\.\d+\.\d+/m,
|
||
why: 'A deployment must be able to read the installed version without a display (#13719).'
|
||
},
|
||
{
|
||
name: 'nofuse-userns-bundled-status',
|
||
// No runtime is running; the CLI must report that itself.
|
||
expectStatus: 1,
|
||
expectOutput: 'appRunning',
|
||
why: 'A command that needs the runtime must report its absence, not abort.'
|
||
},
|
||
{
|
||
name: 'nofuse-userns-bundled-skills',
|
||
expectStatus: 0,
|
||
// Why: the rendered help header, not a bare 'skills' — the case name contains that word.
|
||
expectOutput: 'Usage: orca skills',
|
||
why: 'skills is a pure-text command that must never need Chromium (#14229).'
|
||
},
|
||
{
|
||
name: 'nofuse-userns-bundled-worktree',
|
||
expectStatus: 1,
|
||
expectOutput: "Orca is not running. Run 'orca open' first.",
|
||
why: 'A runtime-dependent command must report the missing runtime, not abort.'
|
||
},
|
||
{
|
||
name: 'nofuse-nosandbox-direct-binary-skills',
|
||
expectStatus: 0,
|
||
expectOutput: 'Usage: orca skills',
|
||
why: 'A direct binary launch that reaches JavaScript must run the command, not boot a GUI (#14229).'
|
||
},
|
||
{
|
||
name: 'nofuse-nosandbox-direct-binary-gui',
|
||
// A missing display is an expected diagnosis, not a crash.
|
||
expectStatus: 1,
|
||
expectOutput: 'needs a usable display server',
|
||
why: 'A desktop launch with no display must diagnose it instead of dying in uv_close (#13719).'
|
||
},
|
||
{
|
||
name: 'stale-display-nosandbox-direct-binary-gui',
|
||
expectStatus: 1,
|
||
expectOutput: 'needs a usable display server',
|
||
why: 'A stale DISPLAY value must diagnose the unreachable endpoint instead of dying in uv_close (#13719).'
|
||
}
|
||
]
|
||
|
||
try {
|
||
if (!appImage) {
|
||
fail(
|
||
'Usage: run-linux-cli-launch-contract-docker.mjs --appimage /path/to/orca-linux.AppImage [--platform linux/amd64|linux/arm64]'
|
||
)
|
||
}
|
||
if (commandArgs.includes('--platform') && !platform) {
|
||
fail('Missing value for --platform')
|
||
}
|
||
if (platform !== null && platform !== 'linux/amd64' && platform !== 'linux/arm64') {
|
||
fail(`Unsupported --platform: ${platform}`)
|
||
}
|
||
if (!existsSync(appImage)) {
|
||
fail(`AppImage not found: ${appImage}`)
|
||
}
|
||
docker(['volume', 'create', artifactVolume], { timeoutMs: DOCKER_TIMEOUT_MS })
|
||
artifactVolumeCreated = true
|
||
buildImage()
|
||
stageArtifacts()
|
||
runContract()
|
||
console.log('\nLinux CLI launch contract passed.')
|
||
} catch (error) {
|
||
console.error(error instanceof Error ? error.message : String(error))
|
||
process.exitCode = 1
|
||
} finally {
|
||
for (const container of containers) {
|
||
docker(['rm', '-f', container], { allowFailure: true, timeoutMs: CLEANUP_TIMEOUT_MS })
|
||
}
|
||
if (artifactVolumeCreated) {
|
||
docker(['volume', 'rm', artifactVolume], {
|
||
allowFailure: true,
|
||
timeoutMs: CLEANUP_TIMEOUT_MS
|
||
})
|
||
}
|
||
docker(['image', 'rm', tag], { allowFailure: true, timeoutMs: CLEANUP_TIMEOUT_MS })
|
||
}
|
||
|
||
function runContract() {
|
||
const failures = []
|
||
for (const testCase of CASES) {
|
||
const output = runCase(testCase.name)
|
||
const statusMatch = /^RESULT status=(\d+)/m.exec(output)
|
||
if (!statusMatch) {
|
||
failures.push(`${testCase.name}: ${firstLine(output)}\n ${testCase.why}`)
|
||
console.log(` FAIL ${testCase.name} — ${firstLine(output)}`)
|
||
continue
|
||
}
|
||
const status = Number(statusMatch[1])
|
||
// Avoid asserting harness’s RESULT case-name echo: expected substring must come from CLI output.
|
||
const commandOutput = output
|
||
.split('\n')
|
||
.filter((line) => !/^(?:RESULT|CRASHED|PRECONDITION_FAILED) /.test(line))
|
||
.join('\n')
|
||
const matchesOutput =
|
||
typeof testCase.expectOutput === 'string'
|
||
? commandOutput.includes(testCase.expectOutput)
|
||
: testCase.expectOutput.test(commandOutput)
|
||
if (status !== testCase.expectStatus || !matchesOutput) {
|
||
failures.push(
|
||
`${testCase.name}: expected status ${testCase.expectStatus} and ${testCase.expectOutput}, ` +
|
||
`got status ${status}\n ${testCase.why}`
|
||
)
|
||
console.log(` FAIL ${testCase.name} — status ${status}`)
|
||
continue
|
||
}
|
||
console.log(` ok ${testCase.name} (status ${status})`)
|
||
}
|
||
if (failures.length > 0) {
|
||
fail(`Linux CLI launch contract failed:\n - ${failures.join('\n - ')}`)
|
||
}
|
||
}
|
||
|
||
function runCase(caseName) {
|
||
const container = `orca-cli-contract-${caseName}-${suffix}`
|
||
containers.add(container)
|
||
// FUSE and extra capabilities would invalidate the test conditions.
|
||
return docker(
|
||
[
|
||
'run',
|
||
...dockerPlatformArgs,
|
||
'--name',
|
||
container,
|
||
'--rm',
|
||
'-v',
|
||
`${artifactVolume}:/artifacts`,
|
||
tag,
|
||
caseName
|
||
],
|
||
{ allowFailure: true, capture: true, timeoutMs: CASE_TIMEOUT_MS }
|
||
)
|
||
}
|
||
|
||
function buildImage() {
|
||
console.log(`Building ${tag}…`)
|
||
const buildArgs = [
|
||
'build',
|
||
...dockerPlatformArgs,
|
||
...(process.env.ORCA_CLI_FIXTURE_CACHE_IMAGE
|
||
? ['--cache-from', process.env.ORCA_CLI_FIXTURE_CACHE_IMAGE]
|
||
: []),
|
||
'-f',
|
||
'config/docker/cli-launch-contract/Dockerfile',
|
||
'-t',
|
||
tag,
|
||
'config/docker/cli-launch-contract'
|
||
]
|
||
// Why: apt fetches from archive.ubuntu.com stall or fail mid-sync; a second build usually lands on a healthy index.
|
||
try {
|
||
docker(buildArgs, { timeoutMs: BUILD_TIMEOUT_MS })
|
||
} catch (error) {
|
||
console.error(
|
||
`${error instanceof Error ? error.message : String(error)}\nRetrying docker build once…`
|
||
)
|
||
docker(buildArgs, { timeoutMs: BUILD_TIMEOUT_MS })
|
||
}
|
||
}
|
||
|
||
// Extract unprivileged so chrome-sandbox is not root-owned setuid.
|
||
function stageArtifacts() {
|
||
console.log('Staging the AppImage payload…')
|
||
const container = `orca-cli-contract-stage-${suffix}`
|
||
containers.add(container)
|
||
docker(
|
||
[
|
||
'run',
|
||
...dockerPlatformArgs,
|
||
'--name',
|
||
container,
|
||
'--rm',
|
||
'-v',
|
||
`${artifactVolume}:/artifacts`,
|
||
'-v',
|
||
`${appImage}:/input/orca-linux.AppImage:ro`,
|
||
'--entrypoint',
|
||
'bash',
|
||
tag,
|
||
'-lc',
|
||
[
|
||
'set -euo pipefail',
|
||
'cp /input/orca-linux.AppImage /artifacts/orca-linux.AppImage',
|
||
'chmod +x /artifacts/orca-linux.AppImage',
|
||
'chown -R orca:orca /artifacts',
|
||
// Use the AppImage runtime's no-FUSE extraction path.
|
||
'cd /artifacts && runuser --user orca -- ./orca-linux.AppImage --appimage-extract >/dev/null',
|
||
'test -x /artifacts/squashfs-root/resources/bin/orca-ide'
|
||
].join(' && ')
|
||
],
|
||
{ timeoutMs: STAGING_TIMEOUT_MS }
|
||
)
|
||
}
|
||
|
||
function docker(args, options = {}) {
|
||
try {
|
||
const output = execFileSync('docker', args, {
|
||
encoding: 'utf8',
|
||
stdio: options.capture ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
||
timeout: options.timeoutMs ?? DOCKER_TIMEOUT_MS,
|
||
killSignal: 'SIGTERM'
|
||
})
|
||
return output ?? ''
|
||
} catch (error) {
|
||
const timedOut = error instanceof Error && 'code' in error && error.code === 'ETIMEDOUT'
|
||
if (timedOut) {
|
||
const message = `docker ${args.join(' ')} timed out after ${options.timeoutMs ?? DOCKER_TIMEOUT_MS}ms`
|
||
if (!options.allowFailure) {
|
||
fail(message)
|
||
}
|
||
return message
|
||
}
|
||
if (!options.allowFailure) {
|
||
fail(
|
||
`docker ${args.join(' ')} failed: ${error instanceof Error ? error.message : String(error)}`
|
||
)
|
||
}
|
||
return `${error?.stdout ?? ''}${error?.stderr ?? ''}`
|
||
}
|
||
}
|
||
|
||
function firstLine(value) {
|
||
return (value ?? '').trim().split('\n')[0] || '(no output)'
|
||
}
|
||
|
||
function valueAfter(flag) {
|
||
const index = commandArgs.indexOf(flag)
|
||
return index === -1 ? null : (commandArgs[index + 1] ?? null)
|
||
}
|
||
|
||
function fail(message) {
|
||
throw new Error(message)
|
||
}
|