gitoria
All repositories: gitoria
3.9 KB
// tests/ticketskit.mjs — a throw-away tickets.worldapi.org for the gate (ticket gitoria#10): tickets' code// COPIED without .env / storage / sessions (never the live one, never its data), started on its own port and// storage, logged in through the gate's ident, with an API token for the tickets user "gitoria".// const t = await startTickets({ ticketsDir, workDir, port, ident, identAlice }) // → { base, token, stop(), api(path) }import { spawn } from 'node:child_process';import { cpSync, mkdirSync, rmSync, existsSync } from 'node:fs';import { join } from 'node:path';const sleep = (ms) => new Promise(r => setTimeout(r, ms));const J = JSON.stringify;const SKIP = new Set(['.env', 'storage', '.sessions', '.scratch', 'server.log', 'server.pid', 'testapp', '.git', 'tests', 'import']);export async function startTickets({ ticketsDir, workDir, port, ident, who, origins = '' }) {const code = join(workDir, 'tickets-code');const data = join(workDir, 'tickets-data');rmSync(workDir, { recursive: true, force: true });mkdirSync(code, { recursive: true });mkdirSync(data, { recursive: true });cpSync(ticketsDir, code, { recursive: true, filter: (src) => {const rel = src.slice(ticketsDir.length).replace(/^\/+/, '');return rel === '' || !SKIP.has(rel.split('/')[0]);} });if (existsSync(join(code, '.env'))) throw new Error('ticketskit: a .env was copied — refusing to start');const base = `http://127.0.0.1:${port}`;const app = await ident.registerApp(who, 'tickets (gitoria gate)', [base]);let log = '';const proc = spawn(join(code, 'bin/hybriel'), ['project.hl'], {cwd: code,env: { ...process.env, TICKETS_PORT: String(port), TICKETS_STORAGE: join(data, 'mpackdb'), TICKETS_SESSIONS: join(data, 'sessions') + '/', TICKETS_WATCH: '0',HL_HOST: '127.0.0.1', IDENT_URL: ident.base, IDENT_EXCHANGE_URL: ident.base, TICKETS_PUBLIC_URL: base, IDENT_API_KEY: app.key, IDENT_API_SECRET: app.secret, TICKETS_CREATOR_IDENTITY: '', TICKETS_CONNECT_ORIGINS: origins },stdio: ['ignore', 'pipe', 'pipe'],});proc.stdout.on('data', d => log += d); proc.stderr.on('data', d => log += d);let up = false;for (let i = 0; i < 80 && !up; i++) { try { up = (await fetch(base + '/api/projects')).ok; } catch {} if (!up) await sleep(250); }if (!up) throw new Error('tickets did not come up\n' + log);// the user "gitoria": the login button's server half, a display name, an API tokenconst first = await fetch(base + '/');const cookie = (first.headers.get('set-cookie') || '').split(';')[0];const cb = await fetch(base + '/login/callback?ident_code=' + await ident.selectorCode(who, app, base), { headers: { cookie }, redirect: 'manual' });if (cb.status !== 302) throw new Error('tickets login failed: ' + cb.status);let n = 0;const emit = async (event, payload) => {const r = await fetch(base + '/__hl/emit', { method: 'POST', headers: { 'content-type': 'application/json', cookie }, body: J({ t: 'emit', i: ++n, event, payload }) });const t = await r.text(); let j = null; try { j = JSON.parse(t); } catch {}return { raw: t, value: j && j.value };};const nm = await emit('saveDisplayName', ['gitoria']);if (!nm.value || nm.value.name !== 'gitoria') throw new Error('tickets name failed: ' + nm.raw);const tk = await emit('tokenCreate', ['gitoria gate']);const token = tk.value && tk.value.token;if (!/^tkt_[0-9a-f]{48}$/.test(token || '')) throw new Error('tickets token failed: ' + tk.raw);return {base, token, cookie, log: () => log,async api(path, headers = {}) { const r = await fetch(base + path, { headers }); const t = await r.text(); let j = null; try { j = JSON.parse(t); } catch {} return { status: r.status, json: j }; },async stop() {try { proc.kill('SIGTERM'); } catch {}await new Promise(r => { if (proc.exitCode !== null || proc.signalCode !== null) return r(); proc.once('exit', r); setTimeout(r, 3000); });},};}
Branches
- mainmain branch
Latest commits
- fdfb4b1bgitoria: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gates 200/0, 46/0, 44/0mre
- 5b46ac84antcolony#40: LOG.md — missions 069/072 are antcolony missions (report paths on Byrodin)mre
- 5602ff41gitoria: Hybriel master 190aa11d (fc838894 GC correctness, #127 mountKids by reference, #126, #48) — tracker README flat; gates 200/0, 46/0, 44/0mre
- e85eaf01gitoria: 069 round 2 — hybriel 1a096ad3 not adopted (Markdown SSR still grows); browser gate waits for the server-side logout before restartmre
- 09ce4f3fgitoria: mission 069 re-vendor hybriel 8efba065 stopped (big SSR pages grow + slow down); lambda audit clean; old vendor keptmre
- 3dc43108antcolony#40: mission references point to the moved missionsmre
- 8d9450fdantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- 205d5fe4gitoria: Hybriel master ff51cf46; ssh keys/tokens no double rows (session sync); gates follow #20mre
- 9b27cb26gitoria#21: installable app (manifest, service worker, offline start page), own iconmre
- 68dcb603deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- e2deed6dgitoria#20: "Add code" only on the Code page of an empty repository, no collapsiblemre
- 8bb97ffddeploy.sh: never send .git or .gitignore to Byrodinmre
- fd981932State of 2026-09-27; bin/ no longer tracked (Hybriel commit is in README)mre
- 4a2d7125initial commitmre