const assert = require('node:assert/strict') const test = require('node:test') const fs = require('node:fs') const os = require('node:os') const path = require('node:path') const vm = require('node:vm') const { stagePublicAPIContext } = require('./stage_public_api_context.cjs') const release = 'public-20260921-040700' function publisher(t, action, failBuild = false) { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'public-api-publisher-')) t.after(() => fs.rmSync(root, { recursive: true, force: true })) const source = path.join(root, 'src') for (const directory of ['scripts', 'migrations', 'frontend/dist']) fs.mkdirSync(path.join(source, directory), { recursive: true }) fs.mkdirSync(path.join(root, 'acceptance')) fs.writeFileSync(path.join(source, 'scripts/Dockerfile.public-api'), fs.readFileSync(path.join(__dirname, 'Dockerfile.public-api'))) fs.writeFileSync(path.join(source, 'WeKnora-native-acceptance-next'), 'reviewed-api', { mode: 0o755 }) fs.writeFileSync(path.join(source, 'migrations/001.sql'), 'SELECT 1;\n') fs.writeFileSync(path.join(root, 'acceptance/runtime.env'), 'DB_NAME=yawan_native_acceptance_20260915\n') const directory = path.join(root, 'releases', release) if (action === 'refreshAPI') { fs.mkdirSync(directory, { recursive: true }) fs.writeFileSync(path.join(directory, 'manifest.json'), JSON.stringify({ release, stage: 'origin-ready', api_image: 'yawan-api:previous', api_image_id: 'sha256:previous' })) } const calls = [] const module = { exports: {} } const injectedRequire = name => { if (name === 'node:fs') return { ...fs, copyFileSync(from, to, flags) { if (from === '/Users/macclaw/.cloudflared/config.yml') { calls.push({ kind: 'tunnel-backup', to }) return fs.writeFileSync(to, 'previous tunnel configuration\n') } return fs.copyFileSync(from, to, flags) } } if (name === 'node:child_process') return { execFileSync(binary, args) { assert.equal(binary, 'docker') assert.deepEqual(Array.from(args.slice(0, 2)), ['--context', 'colima-yawan']) const command = Array.from(args.slice(2)) calls.push({ kind: 'docker', command }) if (command[0] === 'build' && command[2].startsWith('yawan-api:')) { if (failBuild) throw new Error('stubbed API build failure') assert.deepEqual(fs.readdirSync(command.at(-1)).sort(), ['Dockerfile', 'WeKnora-native-acceptance-next', 'migrations']) } return command[0] === 'image' ? 'sha256:built-image\n' : '' } } if (name === './preserve_frontend_assets.cjs') return { preserveFrontendAssets() { calls.push({ kind: 'retain-assets' }); return { retained: 7 } } } if (name === './stage_public_api_context.cjs') return { stagePublicAPIContext } return require(name) } const context = { require: injectedRequire, module, __dirname: path.join(source, 'scripts'), URL, AbortSignal, fetch: async () => ({ ok: true }), console: { log() {} }, recordIdle: () => calls.push({ kind: 'idle' }) } vm.runInNewContext(fs.readFileSync(path.join(__dirname, 'publish_public_runtime.cjs'), 'utf8') + '\n;idle = recordIdle; globalThis.actions = { prepare, refreshAPI };', context) return { root, source, directory, calls, run: () => context.actions[action](release) } } test('prepare builds its API from the release snapshot after backups and retains frontend behavior', t => { const value = publisher(t, 'prepare') value.run() const builds = value.calls.filter(call => call.kind === 'docker' && call.command[0] === 'build') assert.deepEqual(builds.map(call => call.command), [ ['build', '-t', `yawan-api:${release}`, path.join(value.directory, 'api-context')], ['build', '-t', `yawan-frontend:${release}`, path.join(value.source, 'frontend')], ]) const firstBuild = value.calls.indexOf(builds[0]) const backups = value.calls.filter(call => call.kind === 'docker' && call.command.includes('pg_dump')) assert.equal(backups.length, 2) assert.ok(backups.every(call => value.calls.indexOf(call) < firstBuild)) assert.ok(value.calls.find(call => call.kind === 'tunnel-backup')) assert.ok(value.calls.find(call => call.kind === 'retain-assets')) const manifest = JSON.parse(fs.readFileSync(path.join(value.directory, 'manifest.json'))) assert.equal(manifest.stage, 'prepared') assert.equal(manifest.api_image_id, 'sha256:built-image') assert.equal(manifest.frontend_image_id, 'sha256:built-image') assert.equal(manifest.retained_assets.retained, 7) }) test('refresh-api uses its immutable revision snapshot and preserves idle and image identity checks', async t => { const value = publisher(t, 'refreshAPI') await value.run() const buildIndex = value.calls.findIndex(call => call.kind === 'docker' && call.command[0] === 'build') const build = value.calls[buildIndex].command const revision = build[2].match(/-api-(\d{17})$/)[1] assert.deepEqual(build, ['build', '-t', `yawan-api:${release}-api-${revision}`, path.join(value.directory, `api-context-${revision}`)]) const idleIndexes = value.calls.flatMap((call, index) => call.kind === 'idle' ? [index] : []) const stopIndex = value.calls.findIndex(call => call.kind === 'docker' && call.command[0] === 'stop') assert.equal(idleIndexes.length, 2) assert.ok(idleIndexes[0] < buildIndex && buildIndex < idleIndexes[1] && idleIndexes[1] < stopIndex) const start = value.calls.find(call => call.kind === 'docker' && call.command[0] === 'run').command assert.equal(start.at(-1), 'sha256:built-image') assert.ok(start.includes('WEKNORA_REVIEWED_API_IMAGE=sha256:built-image')) const manifest = JSON.parse(fs.readFileSync(path.join(value.directory, 'manifest.json'))) assert.equal(manifest.api_image_id, 'sha256:built-image') assert.deepEqual(manifest.previous_apis, [{ image: 'yawan-api:previous', image_id: 'sha256:previous', container: `yawan-native-acceptance-before-${revision}` }]) }) test('an API build failure retains the staged context and never stops the running API', async t => { const value = publisher(t, 'refreshAPI', true) await assert.rejects(value.run(), /stubbed API build failure/) assert.equal(value.calls.some(call => call.kind === 'docker' && ['stop', 'rename', 'run'].includes(call.command[0])), false) const build = value.calls.find(call => call.kind === 'docker' && call.command[0] === 'build').command assert.equal(fs.readFileSync(path.join(build.at(-1), 'WeKnora-native-acceptance-next'), 'utf8'), 'reviewed-api') const manifest = JSON.parse(fs.readFileSync(path.join(value.directory, 'manifest.json'))) assert.equal(manifest.api_image_id, 'sha256:previous') assert.equal(manifest.stage, 'origin-ready') })