feat: 改进 PaC bootstrap 首发状态投影

This commit is contained in:
Codex
2026-07-13 20:50:58 +02:00
parent d8fd3ba920
commit 697b6933fe
6 changed files with 319 additions and 45 deletions
+22 -43
View File
@@ -28,9 +28,14 @@ import {
} from "./platform-infra-pipelines-as-code-source-artifact";
import { pacAdmissionDesiredIdentity } from "./platform-infra-pac-provenance";
import { pacConsumerRbacDesiredIdentity, renderPacConsumerRbacDesiredFragment } from "./platform-infra-pac-consumer-rbac";
import { runPlatformInfraGiteaCommand } from "./platform-infra-gitea";
import { runGiteaMirrorBootstrapPreflight, runPlatformInfraGiteaCommand } from "./platform-infra-gitea";
import { readGiteaConfig } from "./platform-infra-gitea-config";
import { resolvePacBootstrapMirrorRepository } from "./platform-infra-pipelines-as-code-bootstrap";
import {
pacBootstrapYamlMatchFailure,
projectPacBootstrapResult,
renderPacBootstrap,
resolvePacBootstrapMirrorRepository,
} from "./platform-infra-pipelines-as-code-bootstrap";
const configFile = rootPath("config", "platform-infra", "pipelines-as-code.yaml");
const configLabel = "config/platform-infra/pipelines-as-code.yaml";
@@ -255,7 +260,7 @@ export async function runPlatformInfraPipelinesAsCodeCommand(config: UniDeskConf
if (action === "bootstrap") {
const options = parseApplyOptions(args.slice(1));
const result = await bootstrap(config, options);
return options.json || options.full || options.raw ? result : renderBootstrap(result);
return options.full || options.raw ? result : options.json ? projectPacBootstrapResult(result) : renderPacBootstrap(result);
}
if (action === "status") {
const options = parseCommonOptions(args.slice(1));
@@ -974,11 +979,20 @@ async function bootstrap(config: UniDeskConfig, options: ApplyOptions): Promise<
throw new Error(`Pipelines-as-Code consumer ${consumer.id} belongs to ${consumer.node}, not target ${target.id}`);
}
const repository = resolveRepository(pac, consumer.repositoryRef);
const mirror = resolvePacBootstrapMirrorRepository(readGiteaConfig(), target.id, repository);
let mirror: ReturnType<typeof resolvePacBootstrapMirrorRepository>;
try {
mirror = resolvePacBootstrapMirrorRepository(readGiteaConfig(), target.id, repository);
} catch (error) {
return pacBootstrapYamlMatchFailure(target.id, consumer.id, error);
}
const githubPreflight = record(await runGiteaMirrorBootstrapPreflight(config, target.id, mirror.key));
if (githubPreflight.ok !== true) {
return bootstrapResult(target, consumer, repository, mirror, options, githubPreflight, { ok: false, mutation: false, mode: "skipped", githubPreflight, valuesPrinted: false }, { ok: false, mutation: false, mode: "skipped", valuesPrinted: false });
}
const giteaArgs = ["mirror", "bootstrap", "--target", target.id, "--repo", mirror.key, ...(options.confirm ? ["--confirm"] : []), "--full"];
const giteaBootstrap = record(await runPlatformInfraGiteaCommand(config, giteaArgs));
if (options.confirm && giteaBootstrap.ok !== true) {
return bootstrapResult(target, consumer, repository, mirror, options, giteaBootstrap, {
return bootstrapResult(target, consumer, repository, mirror, options, githubPreflight, giteaBootstrap, {
ok: false,
mutation: false,
mode: "skipped",
@@ -987,7 +1001,7 @@ async function bootstrap(config: UniDeskConfig, options: ApplyOptions): Promise<
});
}
const pacApply = await apply(config, options);
return bootstrapResult(target, consumer, repository, mirror, options, giteaBootstrap, pacApply);
return bootstrapResult(target, consumer, repository, mirror, options, githubPreflight, giteaBootstrap, pacApply);
}
function bootstrapResult(
@@ -996,6 +1010,7 @@ function bootstrapResult(
repository: PacRepository,
mirror: ReturnType<typeof resolvePacBootstrapMirrorRepository>,
options: ApplyOptions,
githubPreflight: Record<string, unknown>,
giteaBootstrap: Record<string, unknown>,
pacApply: Record<string, unknown>,
): Record<string, unknown> {
@@ -1020,6 +1035,7 @@ function bootstrapResult(
repo: mirror.gitea.name,
valuesPrinted: false,
},
githubPreflight,
steps: [
{ id: "gitea-repository", ok: giteaBootstrap.ok === true, mutation: giteaBootstrap.mutation === true, mode: giteaBootstrap.mode, valuesPrinted: false },
{ id: "pac-tekton-gitops", ok: pacReady, mutation: pacApply.mutation === true, mode: pacApply.mode, repositoryMissing, valuesPrinted: false },
@@ -2207,43 +2223,6 @@ function renderApply(result: Record<string, unknown>): RenderedCliResult {
return rendered(result, "platform-infra pipelines-as-code apply", lines);
}
function renderBootstrap(result: Record<string, unknown>): RenderedCliResult {
const target = record(result.target);
const consumer = record(result.consumer);
const mirror = record(result.mirrorRepository);
const steps = arrayRecords(result.steps);
const pacApply = record(result.pipelinesAsCodeApply);
const pacRemote = record(pacApply.remote);
const giteaBootstrap = record(result.giteaBootstrap);
const next = record(result.next);
const errorValue = [pacRemote.error, giteaBootstrap.error, pacApply.error]
.find((value): value is string => typeof value === "string" && value.length > 0) ?? "";
const error = errorValue.length === 0 ? "" : compactLine(errorValue);
const lines = [
"PLATFORM-INFRA PAC / TEKTON / GITOPS BOOTSTRAP",
...table(["TARGET", "CONSUMER", "MODE", "MUTATION", "OK"], [[stringValue(target.id), stringValue(consumer.id), stringValue(result.mode), boolText(result.mutation), boolText(result.ok)]]),
"",
"SOURCE AUTHORITY",
...table(["GITEA_KEY", "GITEA_REPOSITORY", "UPSTREAM", "BRANCH"], [[stringValue(mirror.key), `${stringValue(mirror.owner)}/${stringValue(mirror.repo)}`, stringValue(mirror.upstreamRepository), stringValue(mirror.upstreamBranch)]]),
"",
"STEPS",
...table(["STEP", "OK", "MODE", "MUTATION", "DETAIL"], steps.map((step) => [
stringValue(step.id),
boolText(step.ok),
stringValue(step.mode),
boolText(step.mutation),
step.repositoryMissing === true ? "repository-will-be-created-on-confirm" : "ready",
])),
...(error.length === 0 ? [] : ["", `ERROR ${error}`]),
"",
"NEXT",
...(result.mode === "dry-run"
? [` confirm: ${stringValue(next.confirm)}`, ` boundary: ${stringValue(next.boundary)}`]
: [` delivery: ${stringValue(next.deliveryTrigger)}`, ` investigate: ${stringValue(next.investigate)}`]),
];
return rendered(result, "platform-infra pipelines-as-code bootstrap", lines);
}
export function renderStatus(result: Record<string, unknown>): RenderedCliResult {
const summary = record(result.summary);
const consumer = record(result.consumer);