mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* fix(ci): run only selected managed SSH specs on pull requests * fix(ci): retain full SSH coverage for routed shared helpers
185 lines
6.3 KiB
JavaScript
185 lines
6.3 KiB
JavaScript
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { delimiter, join } from 'node:path'
|
|
import { parse } from 'yaml'
|
|
import { runProcess } from '@orca/process-host'
|
|
import { managedSshShards, MANAGED_SSH_E2E_SPEC_PREFIX } from './ci-e2e-job-selection.mjs'
|
|
import { compileAggregateExpression } from './pr-aggregate-gate-context.mjs'
|
|
import { selectPrE2eSpecs } from './pr-e2e-source-routing.mjs'
|
|
|
|
const workflow = parse(readFileSync('.github/workflows/e2e.yml', 'utf8'))
|
|
const prWorkflow = parse(readFileSync('.github/workflows/pr.yml', 'utf8'))
|
|
const lane = workflow.jobs['orcad-ssh-docker']
|
|
const command = lane.steps.find(
|
|
(step) => step.name === 'Run managed SSH specs on a Docker host'
|
|
).run
|
|
const selector = readFileSync('config/scripts/ci-e2e-job-selection.mjs', 'utf8')
|
|
const small = ['tests/e2e/ssh-orcad-open-in-owner.spec.ts', 'tests/e2e/ssh-orcad-idle-exit.spec.ts']
|
|
const directories = []
|
|
afterEach(() => {
|
|
for (const directory of directories.splice(0)) {
|
|
rmSync(directory, { recursive: true, force: true })
|
|
}
|
|
})
|
|
|
|
it('uses one PR shard for at most two selected files and preserves the full default', () => {
|
|
const caller = compileAggregateExpression(prWorkflow.jobs.e2e.with.managed_ssh_shards)
|
|
const matrix = compileAggregateExpression(lane.strategy.matrix.shard, ['inputs'])
|
|
for (const [specs, expected] of [
|
|
[[small[0]], ['1/1']],
|
|
[small, ['1/1']],
|
|
[
|
|
[...small, 'tests/e2e/ssh-orcad-workspace-tools.spec.ts'],
|
|
['1/2', '2/2']
|
|
],
|
|
[[MANAGED_SSH_E2E_SPEC_PREFIX], ['1/2', '2/2']]
|
|
]) {
|
|
const shards = caller({
|
|
needs: {
|
|
code_paths: {
|
|
outputs: {
|
|
e2e_ssh_shards: JSON.stringify(managedSshShards(JSON.stringify(specs)))
|
|
}
|
|
}
|
|
}
|
|
}).coerceString()
|
|
expect(
|
|
matrix({ inputs: { managed_ssh_shards: shards } })
|
|
.values()
|
|
.map((item) => item.value)
|
|
).toEqual(expected)
|
|
}
|
|
expect(
|
|
matrix({ inputs: {} })
|
|
.values()
|
|
.map((item) => item.value)
|
|
).toEqual(['1/2', '2/2'])
|
|
})
|
|
|
|
it('keeps shared SSH fixtures on the full suite but excludes the experimental sidebar spec', () => {
|
|
for (const file of [
|
|
'tests/e2e/helpers/orcad-managed-workspace.ts',
|
|
'tests/e2e/helpers/paired-host-terminal.ts',
|
|
'.github/workflows/e2e.yml'
|
|
]) {
|
|
expect(selectPrE2eSpecs([file])).toContain(MANAGED_SSH_E2E_SPEC_PREFIX)
|
|
}
|
|
for (const file of [
|
|
'tests/e2e/ssh-orcad-phone-feed-list.spec.ts',
|
|
'tests/e2e/helpers/phone-feed-list.ts',
|
|
'tests/e2e/helpers/sidebar-inputs-build.ts',
|
|
'src/shared/sidebar-list/sidebar-feed-list.ts'
|
|
]) {
|
|
expect(
|
|
selectPrE2eSpecs([file]).some((spec) => spec.startsWith(MANAGED_SSH_E2E_SPEC_PREFIX)),
|
|
file
|
|
).toBe(false)
|
|
}
|
|
})
|
|
|
|
async function execute(input, version = 'current') {
|
|
const directory = mkdtempSync(join(tmpdir(), 'orca-ssh-selection-'))
|
|
directories.push(directory)
|
|
const bin = join(directory, 'bin')
|
|
mkdirSync(bin)
|
|
const moduleDir = join(directory, 'config', 'scripts')
|
|
mkdirSync(moduleDir, { recursive: true })
|
|
if (version !== 'missing') {
|
|
writeFileSync(
|
|
join(moduleDir, 'ci-e2e-job-selection.mjs'),
|
|
version === 'current' ? selector : 'export const old = true\n'
|
|
)
|
|
}
|
|
writeFileSync(
|
|
join(bin, 'xvfb-run'),
|
|
`#!/usr/bin/env bash
|
|
while [ "$#" -gt 0 ] && [ "$1" != pnpm ]; do shift; done
|
|
exec "$@"
|
|
`,
|
|
{ mode: 0o755 }
|
|
)
|
|
const capture = join(directory, 'argv.json')
|
|
writeFileSync(
|
|
join(bin, 'pnpm'),
|
|
`#!/usr/bin/env node
|
|
require('node:fs').writeFileSync(process.env.ARGV_CAPTURE, JSON.stringify(process.argv.slice(2)))
|
|
`,
|
|
{ mode: 0o755 }
|
|
)
|
|
const result = await runProcess({
|
|
program: 'bash',
|
|
args: ['-e', '-o', 'pipefail', '-c', command],
|
|
cwd: directory,
|
|
env: {
|
|
...process.env,
|
|
PATH: bin + delimiter + process.env.PATH,
|
|
TEST_FILES_JSON: input,
|
|
RUNNER_TEMP: directory,
|
|
ARGV_CAPTURE: capture,
|
|
SHARD: '1/1',
|
|
LAYOUT_OWNER: '',
|
|
SHARD_INDEX: '0'
|
|
},
|
|
timeoutMs: 10000
|
|
})
|
|
return {
|
|
result,
|
|
args: existsSync(capture) ? JSON.parse(readFileSync(capture, 'utf8')) : undefined
|
|
}
|
|
}
|
|
|
|
// The production lane runs Bash on Linux; the stubs never start Docker, Electron, or Xvfb.
|
|
describe.skipIf(process.platform === 'win32')('managed SSH workflow command', () => {
|
|
it('passes only the selected SSH files to Playwright, with literal file matching', async () => {
|
|
const { result, args } = await execute(
|
|
JSON.stringify([...small, 'tests/e2e/other.spec.ts', small[0]])
|
|
)
|
|
expect(result.code, result.stderr).toBe(0)
|
|
const filters = args.slice(
|
|
args.indexOf('tests/playwright.config.ts') + 1,
|
|
args.indexOf('--project=electron-headless')
|
|
)
|
|
expect(filters).toHaveLength(2)
|
|
expect(small.map((file) => filters.some((filter) => new RegExp(filter).test(file)))).toEqual([
|
|
true,
|
|
true
|
|
])
|
|
expect(
|
|
filters.some((filter) => new RegExp(filter).test('tests/e2e/ssh-orcad-open-in-ownerXspecYts'))
|
|
).toBe(false)
|
|
expect(
|
|
filters.some((filter) => new RegExp(filter).test('tests/e2e/ssh-orcad-unselected.spec.ts'))
|
|
).toBe(false)
|
|
expect(args).toContain('--shard=1/1')
|
|
})
|
|
|
|
it.each(['', JSON.stringify([MANAGED_SSH_E2E_SPEC_PREFIX, small[0]])])(
|
|
'keeps full daily and explicit suite execution for %s',
|
|
async (input) => {
|
|
const { result, args } = await execute(input)
|
|
expect(result.code, result.stderr).toBe(0)
|
|
expect(args).toContain(MANAGED_SSH_E2E_SPEC_PREFIX)
|
|
}
|
|
)
|
|
|
|
it.each(['legacy', 'missing'])('keeps compatibility with %s checkout refs', async (version) => {
|
|
const { result, args } = await execute(JSON.stringify(small), version)
|
|
expect(result.code, result.stderr).toBe(0)
|
|
expect(args).toContain(MANAGED_SSH_E2E_SPEC_PREFIX)
|
|
})
|
|
|
|
it.each([
|
|
'malformed',
|
|
'[]',
|
|
'[null]',
|
|
JSON.stringify(['tests/e2e/other.spec.ts']),
|
|
JSON.stringify(['tests/e2e/ssh-orcad-../../other.spec.ts'])
|
|
])('refuses invalid selection before starting Playwright: %s', async (input) => {
|
|
const { result, args } = await execute(input)
|
|
expect(result.code).not.toBe(0)
|
|
expect(args).toBeUndefined()
|
|
expect(managedSshShards(input)).toEqual(['1/2', '2/2'])
|
|
})
|
|
})
|