Files
deepseek-harness/scripts/cua-helper/select-artifact.spec.ts
T

95 lines
5.1 KiB
TypeScript

/** Retained CUA selection stays within one producer, attempt and immutable artifact. */
import { expect, it, vi } from 'vitest'
import { selectCuaHelperArtifact } from './select-artifact.ts'
const repository = 'deepseek-harness/deepseek-harness'
const base = `repos/${repository}/actions/runs/123`
function fixture() {
const run = { id: 123, run_attempt: 2, status: 'completed', conclusion: 'success', event: 'workflow_dispatch',
path: '.github/workflows/cua-helper-package.yml', repository: { full_name: repository } }
const jobs = [{ jobs: [{ name: 'package', conclusion: 'success' }] }]
const artifact = { id: 456, name: 'cua-helper-123-2', expired: false, size_in_bytes: 4096 }
const artifacts = [{ artifacts: [{ ...artifact, id: 455, name: 'cua-helper-123-1' }] }, { artifacts: [artifact] }]
const api = vi.fn((path: string, paginate?: boolean) => {
if (path === base) { expect(paginate).toBeUndefined(); return { run_attempt: 2 } }
if (path === `${base}/attempts/2`) { expect(paginate).toBeUndefined(); return run }
expect(paginate).toBe(true)
if (path === `${base}/attempts/2/jobs?per_page=100`) return jobs
if (path === `${base}/artifacts?per_page=100`) return artifacts
throw new Error(`Unexpected GitHub request ${path}`)
})
return { run, jobs, artifact, artifacts, api }
}
it.each([undefined, '', '2'])('pins attempt %s and finds its artifact across pages', (attempt) => {
const f = fixture()
expect(selectCuaHelperArtifact(repository, { cua_run_id: '123', cua_run_attempt: attempt }, f.api))
.toEqual({ runId: '123', attempt: '2', artifactId: '456' })
expect(f.api.mock.calls.some(([path]) => path === base)).toBe(attempt !== '2')
})
it('allows successful CUA packaging when later publication jobs failed', () => {
const f = fixture()
f.run.path = '.github/workflows/release-publish.yml'
f.run.conclusion = 'failure'
f.jobs[0]!.jobs = [{ name: 'cua-helper / package', conclusion: 'success' }, { name: 'Publish to npm', conclusion: 'failure' }]
expect(selectCuaHelperArtifact(repository, { cua_run_id: '123' }, f.api).artifactId).toBe('456')
})
it.each([
{}, { cua_run_attempt: '2' }, { cua_run_id: '' }, { cua_run_id: '123/other' }, { cua_run_id: ' 123' },
{ cua_run_id: '0' }, { cua_run_id: '123', cua_run_attempt: '-1' }, { cua_run_id: '123', cua_run_attempt: '2\nartifact-id=9' },
])('rejects invalid selection fields before reading GitHub: %j', (inputs) => {
const f = fixture()
expect(() => selectCuaHelperArtifact(repository, inputs, f.api)).toThrow()
expect(f.api).not.toHaveBeenCalled()
})
it.each(['wrong/repo/extra', '../repo', 'owner/..', 'owner/.'])('rejects invalid repository %s before reading GitHub', (repo) => {
const f = fixture()
expect(() => selectCuaHelperArtifact(repo, { cua_run_id: '123' }, f.api)).toThrow('invalid repository')
expect(f.api).not.toHaveBeenCalled()
})
it.each(['workflow', 'event', 'repository', 'id', 'attempt', 'running', 'failed'] as const)('rejects %s run evidence', (change) => {
const f = fixture()
if (change === 'workflow') f.run.path = '.github/workflows/ci.yml'
if (change === 'event') f.run.event = 'pull_request'
if (change === 'repository') f.run.repository.full_name = 'outsider/fork'
if (change === 'id') f.run.id = 124
if (change === 'attempt') f.run.run_attempt = 1
if (change === 'running') f.run.status = 'in_progress'
if (change === 'failed') f.run.conclusion = 'failure'
expect(() => selectCuaHelperArtifact(repository, { cua_run_id: '123' }, f.api)).toThrow()
expect(f.api.mock.calls.some(([path]) => path.includes('/artifacts'))).toBe(false)
})
it.each(['failure', 'cancelled', 'skipped', 'missing', 'duplicate'])(
'rejects %s helper jobs without falling back to attempt 1', (status) => {
const f = fixture()
f.run.path = '.github/workflows/release-publish.yml'
f.run.conclusion = 'failure'
f.jobs[0]!.jobs = status === 'missing' ? [] : status === 'duplicate'
? [{ name: 'cua-helper / package', conclusion: 'success' }, { name: 'cua-helper / package', conclusion: 'success' }]
: [{ name: 'cua-helper / package', conclusion: status }]
expect(() => selectCuaHelperArtifact(repository, { cua_run_id: '123' }, f.api)).toThrow('successful cua-helper / package job')
expect(f.api.mock.calls.some(([path]) => path.includes('/attempts/1') || path.includes('/artifacts'))).toBe(false)
},
)
it.each(['missing', 'expired', 'empty', 'duplicate'] as const)('rejects %s artifacts instead of another attempt', (change) => {
const f = fixture()
if (change === 'missing') f.artifacts.pop()
if (change === 'expired') f.artifact.expired = true
if (change === 'empty') f.artifact.size_in_bytes = 0
if (change === 'duplicate') f.artifacts.push({ artifacts: [{ ...f.artifact, id: 457 }] })
expect(() => selectCuaHelperArtifact(repository, { cua_run_id: '123' }, f.api)).toThrow('select an available build or rebuild')
})
it('propagates unavailable GitHub evidence without returning a selection', () => {
const api = vi.fn(() => { throw new Error('HTTP 404') })
expect(() => selectCuaHelperArtifact(repository, { cua_run_id: '123' }, api)).toThrow('HTTP 404')
expect(api).toHaveBeenCalledTimes(1)
})