#!/usr/bin/env node import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; import { verifyHistory } from './gate-history.mjs'; const root = await mkdtemp(path.join(os.tmpdir(), 'gate-delayed-introduction-')); function git(...args) { const result = spawnSync( 'git', ['-c', 'user.name=gate-control', '-c', 'user.email=gate-control@example.invalid', ...args], { cwd: root, encoding: 'utf8' }, ); if (result.status !== 0) throw new Error(result.stderr || result.stdout); return result.stdout.trim(); } try { git('init', '-q'); await writeFile(path.join(root, 'baseline.txt'), 'baseline\n'); git('add', '.'); git('commit', '-m', 'provider target baseline'); const baseline = git('rev-parse', 'HEAD'); git('update-ref', 'refs/remotes/origin/main', baseline); await mkdir(path.join(root, 'scripts'), { recursive: true }); await writeFile(path.join(root, 'scripts', 'preflight.mjs'), 'process.exit(0);\n'); git('add', '.'); git('commit', '-m', 'gate change before registry'); const unregisteredCommit = git('rev-parse', 'HEAD'); await mkdir(path.join(root, 'gates'), { recursive: true }); await writeFile(path.join(root, 'gates', 'gates.manifest.json'), '{"schemaVersion":1}\n'); git('add', '.'); git('commit', '-m', 'delayed registry introduction'); const previousBranch = process.env.CI_COMMIT_BRANCH; process.env.CI_COMMIT_BRANCH = 'feature/delayed-introduction-control'; let result; try { result = await verifyHistory({ root, manifest: { schemaVersion: 1 } }); } finally { if (previousBranch === undefined) delete process.env.CI_COMMIT_BRANCH; else process.env.CI_COMMIT_BRANCH = previousBranch; } const detail = result.failures.join('\n'); if (detail.includes(unregisteredCommit) && /own-tree registry cannot be read/i.test(detail)) { process.stderr.write(`delayed registry introduction rejected: ${detail}\n`); process.exitCode = 1; } else { process.stdout.write('delayed registry introduction was not rejected\n'); } } finally { await rm(root, { recursive: true, force: true }); }