Files
pikasTech-HWLAB/scripts/ci/restore-artifact-catalog.mjs
T

78 lines
2.6 KiB
JavaScript

#!/usr/bin/env node
// Restore the node/lane artifact catalog from the GitOps branch before CI planning.
import { execFileSync } from "node:child_process";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname } from "node:path";
const startedAt = Date.now();
function env(name) {
const value = process.env[name];
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
}
function emit(payload) {
process.stderr.write(JSON.stringify({
event: "artifact-catalog-restore",
source: "scripts/ci/restore-artifact-catalog.mjs",
at: new Date().toISOString(),
durationMs: Date.now() - startedAt,
catalogPath,
gitopsBranch,
...payload
}) + "\n");
}
function catalogHasServices(filePath) {
if (!existsSync(filePath)) return false;
try {
const parsed = JSON.parse(readFileSync(filePath, "utf8"));
return Array.isArray(parsed?.services) && parsed.services.length > 0;
} catch {
return false;
}
}
function git(args, options = {}) {
return execFileSync("git", args, {
cwd: process.cwd(),
encoding: "utf8",
stdio: options.capture === false ? ["ignore", "ignore", "pipe"] : ["ignore", "pipe", "pipe"],
timeout: options.timeoutMs ?? 45_000
});
}
const catalogPath = env("HWLAB_CATALOG_PATH");
const gitopsBranch = env("HWLAB_GITOPS_BRANCH");
const remote = env("HWLAB_GIT_READ_URL") ?? env("HWLAB_GIT_URL");
if (!catalogPath || !gitopsBranch || !remote) {
emit({ status: "skipped", reason: "required-input-missing", hasCatalogPath: Boolean(catalogPath), hasGitopsBranch: Boolean(gitopsBranch), hasRemote: Boolean(remote) });
process.exit(0);
}
if (catalogHasServices(catalogPath)) {
emit({ status: "source-present", reason: "catalog-already-present" });
process.exit(0);
}
try {
git(["fetch", "--depth=1", remote, `refs/heads/${gitopsBranch}`], { capture: false, timeoutMs: 60_000 });
const content = git(["show", `FETCH_HEAD:${catalogPath}`], { timeoutMs: 30_000 });
const parsed = JSON.parse(content);
if (!Array.isArray(parsed?.services) || parsed.services.length === 0) {
emit({ status: "skipped", reason: "gitops-catalog-has-no-services" });
process.exit(0);
}
mkdirSync(dirname(catalogPath), { recursive: true });
writeFileSync(catalogPath, JSON.stringify(parsed, null, 2) + "\n");
emit({ status: "restored", reason: "gitops-catalog", serviceCount: parsed.services.length, bytes: Buffer.byteLength(content) });
} catch (error) {
emit({
status: "skipped",
reason: "gitops-catalog-unavailable",
error: error instanceof Error ? error.message.slice(0, 500) : String(error).slice(0, 500)
});
}