Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103import { test } from 'node:test'import assert from 'node:assert/strict'import { mkdtemp, mkdir, readFile, writeFile, chmod, rm } from 'node:fs/promises'import { tmpdir } from 'node:os'import { join } from 'node:path'import { execFileSync, spawnSync } from 'node:child_process'
const tag = 'a'.repeat(32)const expectedDigest = `registry.fly.io/test-reams@sha256:${'a'.repeat(64)}`
test('publishing authenticates, loads the Nix image, pushes its content-derived tag and reports the matching registry digest', async () => { const fixture = await setup() try { const result = run(fixture, ['test-reams']) assert.equal(result.status, 0, result.stderr) assert.match(result.stdout, new RegExp(expectedDigest)) const calls = await fixture.calls() assert.deepEqual(calls.map(call => [call.tool, call.args[0]]), [ ['docker', 'info'], ['flyctl', 'auth'], ['flyctl', 'auth'], ['nix', '--extra-experimental-features'], ['docker', 'load'], ['docker', 'tag'], ['docker', 'push'], ['docker', 'image'], ]) const remote = `registry.fly.io/test-reams:${tag}` assert.deepEqual(calls.find(call => call.tool === 'docker' && call.args[0] === 'tag').args, ['tag', `reams-atmosphere:${tag}`, remote]) assert.deepEqual(calls.find(call => call.tool === 'docker' && call.args[0] === 'push').args, ['push', remote]) assert.equal(calls.some(call => call.tool === 'flyctl' && call.args[0] === 'deploy'), false) } finally { await fixture.close() }})
test('invalid app names and absent build inputs fail before contacting Docker or Fly', async () => { const fixture = await setup() try { assert.equal(run(fixture, ['../wrong-app']).status, 2) assert.notEqual(run(fixture, ['test-reams'], { VITE_HAPPYVIEW_CLIENT_KEY: '' }).status, 0) assert.deepEqual(await fixture.calls(), []) } finally { await fixture.close() }})
test('auth publishes its own package without web build configuration', async () => { const fixture = await setup(tag, 'reams-auth') try { const result = run(fixture, ['test-reams', 'auth'], { REAMS_PUBLIC_ORIGIN: '', VITE_HAPPYVIEW_URL: '', VITE_HAPPYVIEW_CLIENT_KEY: '', VITE_ATPROTO_OAUTH_SCOPE: '' }) assert.equal(result.status, 0, result.stderr) assert.ok((await fixture.calls()).find(call => call.tool === 'nix').args.some(arg => arg.endsWith('#auth-container'))) assert.match(result.stdout, /deploy\/fly-auth.toml/) } finally { await fixture.close() }})
test('credential or push failures stop the flow and never report a successful publication', async () => { for (const failure of ['whoami', 'push']) { const fixture = await setup() try { const result = run(fixture, ['test-reams'], { FAIL_STAGE: failure }) assert.notEqual(result.status, 0) assert.doesNotMatch(result.stdout, /Published /) const calls = await fixture.calls() assert.equal(calls.some(call => call.tool === 'docker' && call.args[0] === 'image'), false) if (failure === 'whoami') assert.equal(calls.some(call => call.tool === 'nix'), false) } finally { await fixture.close() } }})
test('an unexpected mutable tag or unrelated registry digest is not presented as deployable', async () => { for (const scenario of ['mutable', 'unrelated-digest']) { const fixture = await setup(scenario === 'mutable' ? 'latest' : tag) try { const result = run(fixture, ['test-reams'], scenario === 'unrelated-digest' ? { UNRELATED_DIGEST: '1' } : {}) assert.notEqual(result.status, 0) assert.doesNotMatch(result.stdout, /Published /) if (scenario === 'mutable') assert.equal((await fixture.calls()).some(call => call.tool === 'docker' && call.args[0] === 'push'), false) } finally { await fixture.close() } }})
function run(fixture, args, extra = {}) { return spawnSync('bash', ['scripts/publish-container.sh', ...args], { encoding: 'utf8', timeout: 10_000, env: { ...process.env, PATH: `${fixture.bin}:${process.env.PATH}`, PUBLISH_LOG: fixture.log, TEST_ARCHIVE: fixture.archive, REAMS_PUBLIC_ORIGIN: 'https://reams.example.test', VITE_HAPPYVIEW_URL: 'https://spaces.example.test', VITE_HAPPYVIEW_CLIENT_KEY: 'public-test-key', VITE_ATPROTO_OAUTH_SCOPE: 'atproto', ...extra, } })}async function setup(imageTag = tag, imageName = 'reams-atmosphere') { const dir = await mkdtemp(join(tmpdir(), 'reams-publish-')) const bin = join(dir, 'bin'), log = join(dir, 'calls.jsonl'), archive = join(dir, 'image archive.tar.gz') await mkdir(bin) await writeFile(log, '') await writeFile(join(dir, 'manifest.json'), JSON.stringify([{ RepoTags: [`${imageName}:${imageTag}`] }])) execFileSync('tar', ['-czf', archive, '-C', dir, 'manifest.json']) // Only external build/cloud operations are stubbed. Real Bash/tar/jq perform // argument handling and artifact/digest extraction; no image is pushed. for (const tool of ['nix', 'flyctl', 'docker']) { const file = join(bin, tool) await writeFile(file, `#!${process.execPath} const fs = require('node:fs'); const args = process.argv.slice(2); const tool = ${JSON.stringify(tool)}; fs.appendFileSync(process.env.PUBLISH_LOG, JSON.stringify({tool,args})+'\\n'); if (process.env.FAIL_STAGE && args.includes(process.env.FAIL_STAGE)) process.exit(1); if (tool === 'nix') console.log(process.env.TEST_ARCHIVE); if (tool === 'docker' && args[0] === 'image') console.log(JSON.stringify(process.env.UNRELATED_DIGEST ? ['other.example/app@sha256:wrong'] : ['other.example/app@sha256:wrong', ${JSON.stringify(expectedDigest)}])); `) await chmod(file, 0o755) } return { bin, log, archive, calls: async () => (await readFile(log, 'utf8')).trim().split('\n').filter(Boolean).map(line => JSON.parse(line)), close: () => rm(dir, { recursive: true, force: true }) }}