ship-app: the fork commit comparison is a prefix match (short in the state, full in the inputs manifest); the manifest read bypasses the CDN cache

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-06 19:29:28 +00:00
parent b041f9a052
commit 9f135dfaee

View file

@ -158,7 +158,10 @@ async function gh(args, { quiet = true } = {}) {
async function ghJson(args) { const r = await gh(args); if (r.code !== 0) throw new Error(`gh ${args.slice(0, 2).join(' ')} failed: ${r.out.trim()}`); return JSON.parse(r.out); }
const sleep = ms => new Promise(r => setTimeout(r, ms));
async function head(url) { const r = await fetch(url, { method: 'HEAD' }); return { status: r.status, length: r.headers.get('content-length') ? Number(r.headers.get('content-length')) : null }; }
async function getJson(url) { const r = await fetch(url); if (!r.ok) return null; return r.json().catch(() => null); }
async function getJson(url) { const r = await fetch(`${url}${url.includes('?') ? '&' : '?'}t=${Date.now()}`, { headers: { 'Cache-Control': 'no-cache' } }); if (!r.ok) return null; return r.json().catch(() => null); }
// the state keeps the fork commit as the preflight read it (short with --branch, full with --node-commit); the inputs
// manifest carries the full one (6 October 2026, 0.3.15: `!==` on short against full re-pushed the inputs twice and failed)
const sameCommit = (a, b) => !!a && !!b && (String(a).startsWith(String(b)) || String(b).startsWith(String(a)));
// ---- arguments -----------------------------------------------------------------------------------------------------
const argv = process.argv.slice(2);
@ -363,14 +366,14 @@ async function inputs() {
if (!WIN) return done('inputs', 'skipped', '--skip-windows');
const files = [...WIN_INPUTS, ...WORKERS.filter(existsSync)];
const live = await getJson(`${BASE}/payload-inputs.json`);
const same = live && live.node_source_commit === state.forkCommit && files.every(p => live.files && live.files[basename(p)] && live.files[basename(p)].sha256 === sha256(p));
const same = live && sameCommit(live.node_source_commit, state.forkCommit) && files.every(p => live.files && live.files[basename(p)] && live.files[basename(p)].sha256 === sha256(p));
if (same) return done('inputs', 'already', `payload-inputs.zip carries these files from fork ${state.forkCommit} (built ${live.built_at})`);
const cmd = `IGNEUM_WIN_RELEASE=${WIN_RELEASE} IGNEUM_NODE_SRC=${NODE_DIR} packaging/windows/push-inputs.sh`;
if (DRY) return done('inputs', 'would', `run ${cmd} (deploys the downloads folder)`);
const r = await run('bash', [join(ROOT, 'packaging', 'windows', 'push-inputs.sh')], { env: { IGNEUM_WIN_RELEASE: WIN_RELEASE, IGNEUM_NODE_SRC: NODE_DIR } });
if (r.code !== 0) throw new Error(`push-inputs.sh exited ${r.code}; retry by hand: ${cmd}`);
const after = await getJson(`${BASE}/payload-inputs.json`);
if (!after || after.node_source_commit !== state.forkCommit) throw new Error(`the live payload-inputs.json does not name fork ${state.forkCommit} after the push`);
if (!after || !sameCommit(after.node_source_commit, state.forkCommit)) throw new Error(`the live payload-inputs.json does not name fork ${state.forkCommit} after the push`);
done('inputs', 'ok', `payload-inputs.zip live, fork ${state.forkCommit}`);
}