fix: 使用 PaC 仓库 authority 渲染 AgentRun SecretRef

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
pikastech
2026-07-21 20:51:45 +02:00
parent b0a9e56220
commit 64f3f359c5
3 changed files with 28 additions and 19 deletions
+18 -19
View File
@@ -2,7 +2,7 @@
// Renders AgentRun YAML lane policy into runtime manager environment.
import { createHash } from "node:crypto";
import type { AgentRunLaneSpec } from "./agentrun-lanes";
import { gitRepositoryIdentity, resolveCicdDeliveryAuthority } from "./cicd-delivery-authority";
import { gitRepositoryIdentity, resolveCicdDeliveryAuthority, type PacDeliveryConsumerAuthority } from "./cicd-delivery-authority";
import { renderPacFeatureConfigSchemaStage } from "./pac-feature-config-schema-stage";
import { stableJsonSha256 } from "./stable-json";
@@ -177,6 +177,7 @@ export function renderedObjectsDigest(objects: readonly Record<string, unknown>[
export function renderAgentRunPipelineManifest(spec: AgentRunLaneSpec): Record<string, unknown> {
const build = spec.deployment.manager.imageBuild;
const deliveryAuthority = agentRunPacDeliveryAuthority(spec);
if (spec.ci.buildkitImage === null) throw new Error(`config/agentrun.yaml controlPlane.lanes.${spec.lane}.ci.buildkitImage is required for AgentRun Tekton image build`);
return {
apiVersion: "tekton.dev/v1",
@@ -220,12 +221,12 @@ export function renderAgentRunPipelineManifest(spec: AgentRunLaneSpec): Record<s
{ name: "artifact-catalog", type: "string", default: spec.deployment.artifactCatalogPath },
],
workspaces: [{ name: "source" }],
tasks: agentRunBuildPublishTasks(spec),
tasks: agentRunBuildPublishTasks(spec, deliveryAuthority),
},
};
}
function agentRunBuildPublishTasks(spec: AgentRunLaneSpec): readonly Record<string, unknown>[] {
function agentRunBuildPublishTasks(spec: AgentRunLaneSpec, deliveryAuthority: PacDeliveryConsumerAuthority): readonly Record<string, unknown>[] {
const params = [
{ name: "git-read-url", value: "$(params.git-read-url)" },
{ name: "git-write-url", value: "$(params.git-write-url)" },
@@ -287,9 +288,9 @@ function agentRunBuildPublishTasks(spec: AgentRunLaneSpec): readonly Record<stri
image: "$(params.tools-image)",
env: [
{ name: "BUILD_RESULT_JSON", value: "$(params.build-result-json)" },
{ name: "GITEA_TOKEN", valueFrom: { secretKeyRef: { name: agentRunPacGiteaSecretName(spec), key: "token", optional: true } } },
{ name: "GITEA_TOKEN", valueFrom: { secretKeyRef: { name: deliveryAuthority.repositorySecretName, key: deliveryAuthority.repositoryTokenKey, optional: true } } },
],
script: agentRunTektonGitopsPublishScript(spec),
script: agentRunTektonGitopsPublishScript(spec, deliveryAuthority),
}], ["collect-artifacts"]);
(promoteTask.taskSpec as Record<string, unknown>).params = [...taskParams, { name: "build-result-json" }];
promoteTask.params = [...params, { name: "build-result-json", value: "$(tasks.collect-artifacts.results.build-result)" }];
@@ -408,7 +409,7 @@ function agentRunTektonBuildImageScript(): string {
].join("\n");
}
function agentRunTektonGitopsPublishScript(spec: AgentRunLaneSpec): string {
function agentRunTektonGitopsPublishScript(spec: AgentRunLaneSpec, authority: PacDeliveryConsumerAuthority): string {
const sourcePlaceholder = "__AGENTRUN_SOURCE_COMMIT__";
const envPlaceholder = "__AGENTRUN_ENV_IDENTITY__";
const digestPlaceholder = "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
@@ -416,16 +417,9 @@ function agentRunTektonGitopsPublishScript(spec: AgentRunLaneSpec): string {
const templateImage = agentRunImageArtifact(spec, { sourceCommit: sourcePlaceholder, envIdentity: envPlaceholder, digest: digestPlaceholder, status: statusPlaceholder });
const templateFiles = renderAgentRunGitopsFiles(spec, { sourceCommit: sourcePlaceholder, image: templateImage });
const templateB64 = Buffer.from(JSON.stringify(templateFiles), "utf8").toString("base64");
const authority = resolveCicdDeliveryAuthority({
node: spec.nodeId,
lane: spec.lane,
sourceRepository: gitRepositoryIdentity(spec.source.repository),
sourceBranch: spec.source.branch,
});
if (authority.kind !== "pac-pr-merge") throw new Error(`AgentRun ${spec.nodeId}/${spec.lane} requires exact PaC consumer authority for feature config validation`);
const featureConfigSchemaStage = renderPacFeatureConfigSchemaStage({
repositoryId: authority.consumer.repositoryRef,
consumer: authority.consumer.consumerId,
repositoryId: authority.repositoryRef,
consumer: authority.consumerId,
repoDirExpression: '"$root"',
renderedRootExpression: '"$PWD/$(params.gitops-root)"',
});
@@ -794,10 +788,15 @@ function agentRunLabels(spec: AgentRunLaneSpec): Record<string, string> {
};
}
function agentRunPacGiteaSecretName(spec: AgentRunLaneSpec): string {
const consumerId = spec.ci.pipelineRunPrefix.replace(/-ci$/u, "");
if (consumerId === spec.ci.pipelineRunPrefix) throw new Error(`config/agentrun.yaml controlPlane.lanes.${spec.lane}.ci.pipelineRunPrefix must end with -ci`);
return `pac-gitea-${consumerId}`;
function agentRunPacDeliveryAuthority(spec: AgentRunLaneSpec): PacDeliveryConsumerAuthority {
const authority = resolveCicdDeliveryAuthority({
node: spec.nodeId,
lane: spec.lane,
sourceRepository: gitRepositoryIdentity(spec.source.repository),
sourceBranch: spec.source.branch,
});
if (authority.kind !== "pac-pr-merge") throw new Error(`AgentRun ${spec.nodeId}/${spec.lane} requires exact Pipelines-as-Code repository authority`);
return authority.consumer;
}
function yaml(value: unknown): string {
@@ -119,6 +119,8 @@ describe("YAML 组合的 CI/CD delivery authority", () => {
namespace: "ci-a",
pipelineRunPrefix: "widgets-a-",
repositoryRef: "repo-a",
repositorySecretName: "pac-gitea-repo-a",
repositoryTokenKey: "token",
sourceRepository: "acme/widgets",
sourceBranch: "main",
sourceSnapshotPrefix: "refs/unidesk/snapshots/widgets/main",
+8
View File
@@ -14,6 +14,8 @@ export interface PacDeliveryConsumerAuthority {
readonly namespace: string;
readonly pipelineRunPrefix: string;
readonly repositoryRef: string;
readonly repositorySecretName: string;
readonly repositoryTokenKey: string;
readonly sourceRepository: string;
readonly sourceBranch: string;
readonly sourceSnapshotPrefix: string;
@@ -95,6 +97,8 @@ interface PacRepositoryRow {
readonly sourceBranch: string;
readonly sourceSnapshotPrefix: string;
readonly url: string;
readonly secretName: string;
readonly tokenKey: string;
}
interface GiteaRepositoryRow {
@@ -122,6 +126,8 @@ export function readCicdDeliveryAuthorityCatalog(): CicdDeliveryAuthorityCatalog
sourceBranch: requiredString(params.source_branch, `${path}.params.source_branch`),
sourceSnapshotPrefix: requiredString(params.source_snapshot_prefix, `${path}.params.source_snapshot_prefix`),
url: requiredString(item.url, `${path}.url`),
secretName: requiredString(item.secretName, `${path}.secretName`),
tokenKey: requiredString(item.tokenKey, `${path}.tokenKey`),
} satisfies PacRepositoryRow;
});
const sourceAuthority = record(giteaRoot.sourceAuthority, `${giteaConfigPath}#sourceAuthority`);
@@ -172,6 +178,8 @@ export function readCicdDeliveryAuthorityCatalog(): CicdDeliveryAuthorityCatalog
namespace,
pipelineRunPrefix,
repositoryRef,
repositorySecretName: pacRepository.secretName,
repositoryTokenKey: pacRepository.tokenKey,
sourceRepository: authorityRepository.sourceRepository,
sourceBranch,
sourceSnapshotPrefix,