mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 16:02:29 +00:00
133 lines
5.1 KiB
JavaScript
133 lines
5.1 KiB
JavaScript
import { readFileSync } from 'node:fs'
|
|
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
BUNDLED_AGENT_STATE_RULES_VERSION,
|
|
LIVE_UPDATABLE_AGENT_STATE_RULE_IDS,
|
|
parseAgentStateRulesBundle
|
|
} from '../../src/main/runtime/agent-state-rules/agent-state-rules-bundle.ts'
|
|
import { BUNDLED_AGENT_STATE_RULE_FILES } from '../../src/main/runtime/agent-state-rules/agent-state-rules-catalog.ts'
|
|
import { agentStateRulesDownloadUrl } from '../../src/main/runtime/agent-state-rules/agent-state-rules-live-update.ts'
|
|
import { AGENT_STATE_RULES_ENGINE_VERSION } from '../../src/main/runtime/agent-state-rules/agent-state-rules-schema.ts'
|
|
import {
|
|
AGENT_STATE_RULES_ASSET,
|
|
buildAgentStateRulesBundle,
|
|
promoteAgentStateRules,
|
|
publishAgentStateRules
|
|
} from './agent-state-rules-bundle.mjs'
|
|
import { agentStateRulesTag } from './release-tag-patterns.mjs'
|
|
|
|
const REPO = 'stablyai/orca'
|
|
const NEXT = agentStateRulesTag(1, 'next')
|
|
const STABLE = agentStateRulesTag(1, 'stable')
|
|
|
|
describe('agent state rules bundle build', () => {
|
|
it('builds a bundle the app accepts, under the bundled version and engine', () => {
|
|
const text = buildAgentStateRulesBundle()
|
|
const parsed = parseAgentStateRulesBundle(text, 'live-updatable')
|
|
expect(parsed.ok).toBe(true)
|
|
const bundle = JSON.parse(text)
|
|
expect(bundle.engineVersion).toBe(AGENT_STATE_RULES_ENGINE_VERSION)
|
|
expect(bundle.version).toBe(BUNDLED_AGENT_STATE_RULES_VERSION)
|
|
expect(bundle.files).toEqual(
|
|
BUNDLED_AGENT_STATE_RULE_FILES.filter((file) =>
|
|
LIVE_UPDATABLE_AGENT_STATE_RULE_IDS.has(file.id)
|
|
)
|
|
)
|
|
expect(bundle.bundledOnly).toBeUndefined()
|
|
expect(JSON.parse(buildAgentStateRulesBundle({ bundledOnly: true })).bundledOnly).toBe(true)
|
|
})
|
|
|
|
it('publishes to the exact URL the app fetches', () => {
|
|
for (const channel of ['next', 'stable']) {
|
|
expect(agentStateRulesDownloadUrl(channel)).toBe(
|
|
`https://github.com/${REPO}/releases/download/${agentStateRulesTag(AGENT_STATE_RULES_ENGINE_VERSION, channel)}/${AGENT_STATE_RULES_ASSET}`
|
|
)
|
|
}
|
|
})
|
|
})
|
|
|
|
/** A `gh` stand-in over an in-memory set of releases, recording each call. */
|
|
function fakeGh(releases = {}) {
|
|
const calls = []
|
|
const gh = (args) => {
|
|
calls.push(args)
|
|
const [, verb, tag] = args
|
|
if (verb === 'download') {
|
|
return tag in releases
|
|
? { status: 0, stdout: releases[tag], stderr: '' }
|
|
: { status: 1, stdout: '', stderr: 'release not found' }
|
|
}
|
|
if (verb === 'upload' || verb === 'create') {
|
|
expect(args[3].endsWith(`/${AGENT_STATE_RULES_ASSET}`)).toBe(true)
|
|
releases[tag] = readFileSync(args[3], 'utf8')
|
|
}
|
|
return { status: 0, stdout: '', stderr: '' }
|
|
}
|
|
return { gh, calls, releases }
|
|
}
|
|
|
|
const at = (version, engineVersion = 1) =>
|
|
`${JSON.stringify({ version, engineVersion, files: [] })}\n`
|
|
|
|
describe('publishAgentStateRules', () => {
|
|
it("creates the engine's channel release as a prerelease that can never be Latest", () => {
|
|
const fake = fakeGh()
|
|
expect(
|
|
publishAgentStateRules({
|
|
repo: REPO,
|
|
channel: 'next',
|
|
text: at(2),
|
|
target: 'abc',
|
|
gh: fake.gh
|
|
})
|
|
).toEqual({ tag: NEXT, version: 2 })
|
|
expect(fake.calls.find((args) => args[1] === 'create')).toEqual(
|
|
expect.arrayContaining([NEXT, '--prerelease', '--latest=false', '--target', 'abc'])
|
|
)
|
|
expect(fake.releases[NEXT]).toBe(at(2))
|
|
})
|
|
|
|
it('replaces the asset in place on an existing release, keeping the tag', () => {
|
|
const fake = fakeGh({ [NEXT]: at(1) })
|
|
publishAgentStateRules({ repo: REPO, channel: 'next', text: at(2), target: 'abc', gh: fake.gh })
|
|
expect(fake.calls.map((args) => args[1])).toEqual(['download', 'upload'])
|
|
expect(fake.calls[1]).toContain('--clobber')
|
|
expect(fake.releases[NEXT]).toBe(at(2))
|
|
})
|
|
|
|
it.each([1, 2])('refuses version %s over a published 2, uploading nothing', (version) => {
|
|
const fake = fakeGh({ [NEXT]: at(2) })
|
|
expect(() =>
|
|
publishAgentStateRules({
|
|
repo: REPO,
|
|
channel: 'next',
|
|
text: at(version),
|
|
target: 'abc',
|
|
gh: fake.gh
|
|
})
|
|
).toThrow('bump agent-state-rules-release.json')
|
|
expect(fake.calls.map((args) => args[1])).toEqual(['download'])
|
|
})
|
|
|
|
it('fails when the release exists but its download fails', () => {
|
|
const gh = () => ({ status: 1, stdout: '', stderr: 'no assets match the file pattern' })
|
|
expect(() =>
|
|
publishAgentStateRules({ repo: REPO, channel: 'next', text: at(2), target: 'abc', gh })
|
|
).toThrow('no assets match')
|
|
})
|
|
|
|
it('promotes the identical next bytes to stable', () => {
|
|
const nextText = JSON.stringify({ version: 3, engineVersion: 1, files: [] }, null, 2)
|
|
const fake = fakeGh({ [NEXT]: nextText, [STABLE]: at(2) })
|
|
promoteAgentStateRules({ repo: REPO, engineVersion: 1, target: 'abc', gh: fake.gh })
|
|
expect(fake.releases[STABLE]).toBe(nextText)
|
|
})
|
|
|
|
it('refuses to promote before next exists', () => {
|
|
const fake = fakeGh()
|
|
expect(() =>
|
|
promoteAgentStateRules({ repo: REPO, engineVersion: 1, target: 'abc', gh: fake.gh })
|
|
).toThrow('has not been published')
|
|
})
|
|
})
|