import { readFileSync } from "node:fs"; import { ciHelp } from "./src/ci"; function assertCondition(condition: unknown, message: string, detail: unknown = {}): void { if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`); } const source = readFileSync("scripts/src/ci.ts", "utf8"); const jobsSource = readFileSync("scripts/src/jobs.ts", "utf8"); const help = JSON.stringify(ciHelp()); assertCondition( source.includes("interface CiInstallOptions") && source.includes("skipPrewarm: boolFlag(args, \"--skip-prewarm\")") && source.includes("skipTektonInstall: boolFlag(args, \"--skip-tekton-install\")") && source.includes("wait: boolFlag(args, \"--wait\")") && source.includes("prewarm: options.skipPrewarm ? \"skipped\" : \"completed\"") && source.includes("tektonInstall: options.skipTektonInstall ? \"skipped\" : \"completed\""), "ci install must expose controlled manifest refresh skip modes", ); assertCondition( source.includes("function installAsync(options: CiInstallOptions)") && source.includes("\"ci_install\"") && source.includes("ciInstallCommand(options)") && source.includes("options.wait ? install(config, options) : installAsync(options)") && source.includes("if (action === \"install-status\") return installStatus(nameArg ?? \"latest\")"), "ci install must default to async job mode with status follow-up", ); assertCondition( source.includes("event: \"ci.install.progress\"") && source.includes("emitCiInstallProgress(\"apply-manifest\", \"started\"") && source.includes("emitCiInstallProgress(\"upload-manifest\", \"started\"") && source.includes("emitCiInstallProgress(\"kubectl-apply\", \"started\"") && source.includes("emitCiInstallProgress(\"install\", \"failed\"") && jobsSource.includes("summarizeCiInstallJobProgress") && jobsSource.includes("parseJsonLineEvents(stderrTail, \"ci.install.progress\")"), "ci install job status must expose stage progress events", ); assertCondition( source.includes("timeoutMs: Math.min(Math.max(waitMs, 15_000), 45_000)") && source.includes("maxResponseBytes: 3_000_000, timeoutMs: 15_000") && source.includes("backend-core-dispatch-timeout"), "ci dispatch submit must use bounded backend-core fetch timeout", ); assertCondition( source.includes("runSshCommandCapture(config, `${target.providerId}:k3s`, [\"script\"], script)") && source.includes("base64 -d > \\\"$tmp\\\" <<'UNIDESK_CI_MANIFEST_B64'") && source.includes("test -s \\\"$tmp\\\"") && source.includes("manifest_bytes="), "ci manifest apply must embed YAML through k3s route script with byte visibility", ); assertCondition( source.includes("ci_runtime_image_containerd_root_required=true") && source.includes("failureLines") && source.includes("rerun with: bun scripts/cli.ts ci install --skip-prewarm"), "ci prewarm failure must expose concise root/containerd visibility and recovery", ); assertCondition( help.includes("ci install --skip-prewarm") && help.includes("ci install --skip-prewarm --skip-tekton-install") && help.includes("ci install-status latest") && help.includes("ci install --wait --skip-prewarm --skip-tekton-install") && help.includes("async-job") && help.includes("Use --wait only for explicit synchronous debugging") && help.includes("Use --skip-prewarm only to refresh Tekton/CI manifests") && help.includes("Use --skip-tekton-install with --skip-prewarm only when Tekton is already installed"), "ci help must document manifest refresh boundaries", ciHelp(), ); console.log(JSON.stringify({ ok: true, checks: [ "ci install exposes controlled manifest refresh skip modes", "ci install defaults to async job mode with status follow-up", "ci install job status exposes stage progress events", "ci dispatch submit uses bounded backend-core fetch timeout", "ci manifest apply embeds YAML through k3s route script with byte visibility", "ci prewarm failure exposes concise root/containerd recovery", "ci help documents manifest refresh boundaries", ], }));