89 lines
4.0 KiB
TypeScript
89 lines
4.0 KiB
TypeScript
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",
|
|
],
|
|
}));
|