mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
* feat(orcad): ship the mobile web page so phones paired to orcad get it orcad never carried out/mobile-web, so it did not advertise mobileWeb.bundle.v1 and phones paired directly to an orcad server fell back to the app's built-in native screens. The built page now ships in every orcad package at out/mobile-web, the path getBundledMobileWebBundleRoot already probes under the install root. Its manifest is a fixed artifact; its content-addressed assets join the hashed artifact list from that manifest, as one shared copy in the template's common files. build-orcad fails when the page is missing or stale, and CI lanes that build orcad now build the page first. * ci(orcad): check out mobile/ for the Windows host template build * refactor(orcad): copy the page tree whole and build it once per CI run The guard already refuses unlisted files, so staging copies the bundle directory as native-chat-visuals is copied. The shipped template takes the page the qualification lanes tested, the e2e build artifact carries it, and the PR smoke builds it through install-mobile-dependencies behind its own scope step. Drops tests that duplicated the guard's own. * fix(orcad): refuse a template page asset name that escapes the slot
93 lines
4.0 KiB
JavaScript
93 lines
4.0 KiB
JavaScript
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { dirname, join } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import {
|
|
ORCAD_MOBILE_WEB_MANIFEST,
|
|
ORCAD_NODE_RUNTIME_MARKER_FILENAME,
|
|
ORCAD_SERVER_TARGET_FILENAME,
|
|
orcadArtifactFilenames,
|
|
orcadRipgrepArtifact
|
|
} from '../../src/shared/orcad-artifacts.ts'
|
|
import { SERVER_TARGETS } from '../../src/shared/node-runtime-pin.ts'
|
|
import { orcadAgentBrowserNativeName } from '../../src/shared/orcad-agent-browser-name.ts'
|
|
import { readOrcadArtifactIdentity } from '../../src/main/orcad/orcad-artifact-identity.ts'
|
|
import { computeOrcadFullVersion } from './orcad-artifact-version.mjs'
|
|
|
|
const directories = []
|
|
afterEach(() => {
|
|
for (const directory of directories.splice(0)) {
|
|
rmSync(directory, { recursive: true, force: true })
|
|
}
|
|
})
|
|
|
|
const PAGE_ASSET = 'out/mobile-web/index.html'
|
|
const PAGE_MANIFEST = JSON.stringify({ assets: [{ path: 'index.html' }] })
|
|
|
|
function createArtifactDirectory(target = 'linux-x64-glibc') {
|
|
const directory = mkdtempSync(join(tmpdir(), 'orcad-version-'))
|
|
directories.push(directory)
|
|
for (const filename of orcadArtifactFilenames(target, [PAGE_ASSET])) {
|
|
const path = join(directory, filename)
|
|
mkdirSync(dirname(path), { recursive: true })
|
|
writeFileSync(path, filename === ORCAD_MOBILE_WEB_MANIFEST ? PAGE_MANIFEST : filename)
|
|
}
|
|
writeFileSync(join(directory, ORCAD_SERVER_TARGET_FILENAME), `${target}\n`)
|
|
return directory
|
|
}
|
|
|
|
describe('standalone runtime version', () => {
|
|
it('changes when a shipped search binary changes and rejects a missing binary', () => {
|
|
const target = 'linux-x64-glibc'
|
|
const dir = createArtifactDirectory(target)
|
|
const before = computeOrcadFullVersion(dir, { target })
|
|
const binary = join(dir, orcadRipgrepArtifact(target))
|
|
writeFileSync(binary, 'updated binary')
|
|
expect(computeOrcadFullVersion(dir, { target })).not.toBe(before)
|
|
rmSync(binary)
|
|
expect(() => computeOrcadFullVersion(dir, { target })).toThrow(orcadRipgrepArtifact(target))
|
|
})
|
|
|
|
it('changes when a page asset changes and rejects a missing one', () => {
|
|
const target = 'linux-x64-glibc'
|
|
const dir = createArtifactDirectory(target)
|
|
const before = computeOrcadFullVersion(dir, { target })
|
|
writeFileSync(join(dir, PAGE_ASSET), 'updated page')
|
|
expect(computeOrcadFullVersion(dir, { target })).not.toBe(before)
|
|
rmSync(join(dir, PAGE_ASSET))
|
|
expect(() => computeOrcadFullVersion(dir, { target })).toThrow(PAGE_ASSET)
|
|
})
|
|
|
|
it('keys the version on the referenced runtime digest rather than its bytes', () => {
|
|
const target = 'darwin-arm64'
|
|
const dir = createArtifactDirectory(target)
|
|
writeFileSync(join(dir, ORCAD_NODE_RUNTIME_MARKER_FILENAME), `${'a'.repeat(64)}\n`)
|
|
const before = computeOrcadFullVersion(dir, { target })
|
|
writeFileSync(join(dir, ORCAD_NODE_RUNTIME_MARKER_FILENAME), `${'b'.repeat(64)}\n`)
|
|
expect(computeOrcadFullVersion(dir, { target })).not.toBe(before)
|
|
})
|
|
|
|
it.each(SERVER_TARGETS)(
|
|
'matches the installed %s identity with and without its optional browser',
|
|
async (target) => {
|
|
const dir = createArtifactDirectory(target)
|
|
const [platform, arch] = target.split('-')
|
|
const agentBrowserFilename = orcadAgentBrowserNativeName(
|
|
platform,
|
|
arch,
|
|
target.endsWith('-musl') ? 'musl' : 'glibc'
|
|
)
|
|
const options = { target, agentBrowserFilename }
|
|
const withoutBrowser = computeOrcadFullVersion(dir, options)
|
|
expect(withoutBrowser).toBe(await readOrcadArtifactIdentity(dir))
|
|
writeFileSync(join(dir, agentBrowserFilename), 'browser')
|
|
const withBrowser = computeOrcadFullVersion(dir, options)
|
|
expect(withBrowser).not.toBe(withoutBrowser)
|
|
expect(withBrowser).toBe(await readOrcadArtifactIdentity(dir))
|
|
writeFileSync(join(dir, agentBrowserFilename), 'updated-browser')
|
|
expect(computeOrcadFullVersion(dir, options)).not.toBe(withBrowser)
|
|
expect(computeOrcadFullVersion(dir, options)).toBe(await readOrcadArtifactIdentity(dir))
|
|
}
|
|
)
|
|
})
|