ci: finalize pac status and gh heredoc guard
This commit is contained in:
@@ -10,6 +10,7 @@ import { spawnSync } from "node:child_process";
|
||||
import { rootPath, type UniDeskConfig } from "../config";
|
||||
import type { RenderedCliResult } from "../output";
|
||||
import { applyLocalCaddyManagedSite } from "../pk01-caddy";
|
||||
import { runPlatformInfraPipelinesAsCodeCommand } from "../platform-infra-pipelines-as-code";
|
||||
import { runSshCommandCapture, type SshCaptureResult } from "../ssh";
|
||||
import { runRemoteSshCommandCapture } from "../remote";
|
||||
import { startJob } from "../jobs";
|
||||
@@ -325,8 +326,188 @@ export async function status(config: UniDeskConfig, options: StatusOptions): Pro
|
||||
return await statusYamlLane(config, options, resolveAgentRunLaneTarget(options));
|
||||
}
|
||||
|
||||
function isPipelinesAsCodeMigratedLane(spec: AgentRunLaneSpec): boolean {
|
||||
return spec.gitMirror.readUrl.includes("gitea-http.")
|
||||
|| spec.gitops.repoURL.includes("gitea-http.")
|
||||
|| spec.gitMirror.readUrl.includes("/mirrors/");
|
||||
}
|
||||
|
||||
function pacStatusCommand(spec: AgentRunLaneSpec, full = false): string {
|
||||
return `bun scripts/cli.ts platform-infra pipelines-as-code status --target ${spec.nodeId}${full ? " --full" : ""}`;
|
||||
}
|
||||
|
||||
function giteaMirrorStatusCommand(spec: AgentRunLaneSpec): string {
|
||||
return `bun scripts/cli.ts platform-infra gitea mirror status --target ${spec.nodeId}`;
|
||||
}
|
||||
|
||||
export async function statusPipelinesAsCodeLane(config: UniDeskConfig, options: StatusOptions, target: { configPath: string; spec: AgentRunLaneSpec }): Promise<Record<string, unknown>> {
|
||||
const spec = target.spec;
|
||||
const pacStatus = record(await runPlatformInfraPipelinesAsCodeCommand(config, ["status", "--target", spec.nodeId, "--full"]));
|
||||
const pacSummary = record(pacStatus.summary);
|
||||
const latestPipelineRun = record(pacSummary.latestPipelineRun);
|
||||
const artifact = record(pacSummary.artifact);
|
||||
const pacArgo = record(pacSummary.argo);
|
||||
const pipelineRunName = options.pipelineRun ?? stringOrNull(latestPipelineRun.name);
|
||||
const runtimeProbe = await timedStatusStage("runtime", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneRuntimeStatusScript(spec, pipelineRunName)]));
|
||||
const runtimePayload = captureJsonPayload(runtimeProbe.value);
|
||||
const manager = record(runtimePayload.manager);
|
||||
const database = record(runtimePayload.database);
|
||||
const secrets = record(runtimePayload.secrets);
|
||||
const localPostgres = record(runtimePayload.localPostgres);
|
||||
const sourceCommit = options.sourceCommit ?? stringOrNull(artifact.sourceCommit) ?? stringOrNull(latestPipelineRun.sourceCommit);
|
||||
const expectedGitopsRevision = stringOrNull(artifact.gitopsCommit);
|
||||
const argoRevision = stringOrNull(pacArgo.revision);
|
||||
const argoSyncedToGitops = Boolean(expectedGitopsRevision && argoRevision === expectedGitopsRevision);
|
||||
const managerSourceMatchesExpected = Boolean(sourceCommit && manager.sourceCommit === sourceCommit);
|
||||
const pipelineSucceeded = latestPipelineRun.status === "True";
|
||||
const pacReady = pacStatus.ok === true && pacSummary.ready === true;
|
||||
const blockers = [
|
||||
...(pacReady ? [] : ["pac-not-ready"]),
|
||||
...(pipelineRunName !== null ? [] : ["pac-pipelinerun-missing"]),
|
||||
...(pipelineRunName === null || pipelineSucceeded ? [] : ["pac-pipelinerun-not-succeeded"]),
|
||||
...(expectedGitopsRevision !== null ? [] : ["pac-gitops-revision-unresolved"]),
|
||||
...(expectedGitopsRevision === null || argoSyncedToGitops ? [] : ["argo-revision-stale"]),
|
||||
...(runtimePayload.runtimeNamespaceExists === true ? [] : ["runtime-namespace-missing"]),
|
||||
...(manager.deploymentExists === true ? [] : ["manager-deployment-missing"]),
|
||||
...(manager.deploymentExists !== true || sourceCommit === null || managerSourceMatchesExpected ? [] : ["manager-source-stale"]),
|
||||
...(manager.serviceExists === true ? [] : ["manager-service-missing"]),
|
||||
...(spec.database.mode === "external-postgres" && database.secretPresent !== true ? ["database-secret-missing"] : []),
|
||||
...(secrets.ready === true ? [] : ["lane-secret-missing"]),
|
||||
...(spec.database.localPostgresExpectedAbsent && localPostgres.absent !== true ? ["local-postgres-present"] : []),
|
||||
];
|
||||
const aligned = blockers.length === 0 && pipelineSucceeded && argoSyncedToGitops && managerSourceMatchesExpected;
|
||||
const runtimeAlignment = {
|
||||
pipelineSucceeded,
|
||||
argoRevision,
|
||||
argoSyncedToGitops,
|
||||
managerSourceCommit: stringOrNull(manager.sourceCommit),
|
||||
managerSourceMatchesExpected,
|
||||
runtimeAligned: blockers.every((blocker) => blocker.startsWith("pac-") || blocker === "argo-revision-stale"),
|
||||
};
|
||||
const nextAction = aligned
|
||||
? { code: "none", summary: "PaC/Gitea migrated lane aligned; no action required", command: null }
|
||||
: blockers.includes("argo-revision-stale")
|
||||
? { code: "argo-refresh", summary: "GitOps commit is published but Argo has not observed it yet", command: `bun scripts/cli.ts agentrun control-plane refresh --node ${spec.nodeId} --lane ${spec.lane} --confirm` }
|
||||
: { code: "inspect-pac-status", summary: `PaC/Gitea closeout blocked: ${blockers.join(", ")}`, command: pacStatusCommand(spec, true) };
|
||||
const migration = {
|
||||
migrated: true,
|
||||
sourceAuthority: "gitea-pipelines-as-code",
|
||||
triggerPath: "Gitea webhook -> Pipelines-as-Code -> Tekton -> GitOps/Argo -> k8s runtime",
|
||||
legacyGitMirrorDisposition: "migration-readonly",
|
||||
legacyTriggerCurrentDisabled: true,
|
||||
valuesPrinted: false,
|
||||
};
|
||||
const summary = {
|
||||
aligned,
|
||||
runtimeAligned: runtimeAlignment.runtimeAligned,
|
||||
blockers,
|
||||
warnings: [],
|
||||
sourceCommit,
|
||||
expectedPipelineRun: pipelineRunName,
|
||||
expectedGitopsRevision,
|
||||
runtimeAlignment,
|
||||
migration,
|
||||
pac: {
|
||||
ready: pacSummary.ready ?? false,
|
||||
webhookCount: pacSummary.webhookCount ?? null,
|
||||
latestPipelineRun: {
|
||||
name: pipelineRunName,
|
||||
status: latestPipelineRun.status ?? null,
|
||||
reason: latestPipelineRun.reason ?? null,
|
||||
durationSeconds: latestPipelineRun.durationSeconds ?? null,
|
||||
sourceCommit: stringOrNull(latestPipelineRun.sourceCommit),
|
||||
},
|
||||
taskRuns: pacSummary.taskRuns ?? [],
|
||||
artifact: {
|
||||
imageStatus: artifact.imageStatus ?? null,
|
||||
envIdentity: artifact.envIdentity ?? null,
|
||||
digest: artifact.digest ?? null,
|
||||
gitopsCommit: expectedGitopsRevision,
|
||||
sourceCommit,
|
||||
valuesPrinted: false,
|
||||
},
|
||||
},
|
||||
argo: {
|
||||
syncStatus: pacArgo.sync ?? null,
|
||||
healthStatus: pacArgo.health ?? null,
|
||||
revision: argoRevision,
|
||||
syncedToGitops: argoSyncedToGitops,
|
||||
},
|
||||
runtime: {
|
||||
namespaceExists: runtimePayload.runtimeNamespaceExists ?? false,
|
||||
manager: {
|
||||
deploymentExists: manager.deploymentExists ?? false,
|
||||
serviceExists: manager.serviceExists ?? false,
|
||||
sourceCommit: stringOrNull(manager.sourceCommit),
|
||||
sourceMatchesExpected: managerSourceMatchesExpected,
|
||||
envIdentity: manager.envIdentity ?? null,
|
||||
},
|
||||
databaseSecretPresent: database.secretPresent ?? null,
|
||||
secretsReady: secrets.ready ?? null,
|
||||
localPostgresAbsent: localPostgres.absent ?? null,
|
||||
},
|
||||
nextAction,
|
||||
};
|
||||
const result: Record<string, unknown> = {
|
||||
ok: runtimeProbe.value.exitCode === 0 && pacStatus.ok === true && blockers.length === 0,
|
||||
command: "agentrun control-plane status",
|
||||
mode: "pipelines-as-code-migrated-lane",
|
||||
configPath: target.configPath,
|
||||
target: options.full || options.raw ? agentRunLaneSummary(spec) : compactAgentRunLaneStatusTarget(spec),
|
||||
summary,
|
||||
alignment: {
|
||||
aligned,
|
||||
blockers,
|
||||
warnings: [],
|
||||
sourceCommit,
|
||||
expectedPipelineRun: pipelineRunName,
|
||||
expectedGitopsRevision,
|
||||
runtimeAlignment,
|
||||
migration,
|
||||
},
|
||||
timings: {
|
||||
runtimeMs: runtimeProbe.elapsedMs,
|
||||
totalMs: runtimeProbe.elapsedMs,
|
||||
},
|
||||
disclosure: {
|
||||
output: options.full || options.raw ? "full" : "compact-summary",
|
||||
full: options.full,
|
||||
raw: options.raw,
|
||||
legacyGitMirror: "migration-readonly",
|
||||
fullCommand: agentRunControlPlaneStatusCommand(spec, options, true),
|
||||
pacStatusCommand: pacStatusCommand(spec, true),
|
||||
},
|
||||
next: {
|
||||
action: nextAction,
|
||||
pacStatus: pacStatusCommand(spec),
|
||||
giteaMirrorStatus: giteaMirrorStatusCommand(spec),
|
||||
refresh: `bun scripts/cli.ts agentrun control-plane refresh --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
|
||||
triggerCurrent: null,
|
||||
},
|
||||
valuesPrinted: false,
|
||||
};
|
||||
if (options.full || options.raw || runtimeProbe.value.exitCode !== 0) {
|
||||
result.captures = {
|
||||
runtime: compactCapture(runtimeProbe.value, { full: options.full || options.raw || runtimeProbe.value.exitCode !== 0 }),
|
||||
};
|
||||
}
|
||||
if (options.full || options.raw) {
|
||||
result.pipelinesAsCode = pacStatus;
|
||||
result.runtime = runtimePayload;
|
||||
result.legacy = {
|
||||
gitMirror: {
|
||||
disposition: "migration-readonly",
|
||||
readUrl: spec.gitMirror.readUrl,
|
||||
note: "Legacy git-mirror status is not used as a closeout blocker for PaC/Gitea migrated lanes.",
|
||||
},
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, target: { configPath: string; spec: AgentRunLaneSpec }): Promise<Record<string, unknown>> {
|
||||
const spec = target.spec;
|
||||
if (isPipelinesAsCodeMigratedLane(spec)) return await statusPipelinesAsCodeLane(config, options, target);
|
||||
const sourceProbe = await timedStatusStage("source", () => spec.source.statusMode === "k3s-git-mirror"
|
||||
? capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneK3sSourceStatusScript(spec)])
|
||||
: capture(config, `${spec.nodeRoute}:${spec.source.workspace}`, ["sh", "--", yamlLaneSourceStatusScript(spec)]));
|
||||
|
||||
Reference in New Issue
Block a user