Merge pull request #1609 from pikasTech/fix/issue-1607-cicd-cleanup
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success

fix(cicd): isolate NC01 PaC target triggers
This commit is contained in:
Lyon
2026-07-09 11:42:41 +08:00
committed by GitHub
9 changed files with 24 additions and 20 deletions
+1 -3
View File
@@ -19,14 +19,11 @@ bun scripts/cli.ts hwlab g14 git-mirror status --lane v02
bun scripts/cli.ts agentrun control-plane status
bun scripts/cli.ts platform-infra gitea mirror status --target JD01
bun scripts/cli.ts platform-infra gitea mirror webhook status --target JD01
bun scripts/cli.ts platform-infra gitea mirror webhook test --target JD01 --repo unidesk-master --confirm
bun scripts/cli.ts platform-infra pipelines-as-code status --target JD01
bun scripts/cli.ts platform-infra pipelines-as-code status --target JD01 --consumer hwlab-jd01-v03
bun scripts/cli.ts platform-infra pipelines-as-code closeout --target JD01 --consumer <consumer> --source-commit <sha> --wait
bun scripts/cli.ts platform-infra pipelines-as-code history --target JD01 --limit 10
bun scripts/cli.ts platform-infra pipelines-as-code history --target JD01 --id <pipelinerun>
bun scripts/cli.ts cicd branch-follower status
bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step state-read
```
节点级只读状态必须优先用 `cicd status --node <NODE>`。它从 `config/platform-infra/pipelines-as-code.yaml` 找到该 node 的所有当前 PaC consumer,一次性汇总 PipelineRun、Argo/GitOps、runtime readiness 和诊断;不要再靠阅读源码或手动拼三条 consumer 命令来回答 “NC01 的 CI/CD 流水线情况”。`platform-infra pipelines-as-code status --target <NODE> --consumer <id>` 只作为单 consumer drill-down。
@@ -47,6 +44,7 @@ bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel
- CI/CD、GitOps、rollout、PipelineRun、Argo、git-mirror 和 AgentRun 部署必须走受控 CLI;不要用裸 `kubectl``argo``tkn``curl` 当正式控制入口。
- CI/CD source authority 只能来自 YAML 声明的 Kubernetes 托管 source authoritylegacy lane 使用 k8s git-mirror snapshotGitea/PaC migrated lane 使用 GitHub PR merge -> GitHub webhook bridge -> Gitea controlled mirror + immutable snapshot ref -> Pipelines-as-Code。受控命令先在 k8s 内同步/创建不可变 `refs/unidesk/snapshots/.../<commit>` stage refbuild/status/publish 只消费该 snapshothost worktree、本地 `git fetch/pull`、可变 branch ref 或 Pipeline 内直连 GitHub 都不能作为 authoritative source。
- JD01/NC01 `agentrun-<node>-v02``sentinel-<node>-v03``hwlab-<node>-v03` 的正式 CI/CD closeout 入口是 `cicd status --node <NODE>``platform-infra pipelines-as-code closeout|status|history --target <NODE> --consumer <id>``closeout` 是通用 consumer 引导入口,只读取/等待 PaC、Tekton、GitOps、Argo 和 runtime 对齐,不触发旧手动发布。`cicd branch-follower``cicd gitea-actions-poc` 对这些 consumer 只保留历史/迁移只读用途,不得作为当前交付判断入口。
- PaC `.tekton` 文件必须用 Repository CR 的 target/node 参数隔离 JD01/NC01,避免同一个 Gitea push 在一个 target cluster 内额外创建另一个 target 的 PipelineRunhistory/detail 必须按实际 PipelineRun prefix/pipeline 归属 consumer。
- GitHub/Git 相关 egress 必须走 YAML-first host proxy/sourceRefbranch-follower controller 读 `config/cicd-branch-followers.yaml#controller.source.githubSsh`runtime legacy git-mirror 读 owning lane/control-plane YAML 的 host proxy 和 `githubTransport`Gitea/PaC 迁移 lane 读 `config/platform-infra/gitea.yaml``config/platform-infra/pipelines-as-code.yaml`;禁止依赖未声明 host env、trans proxy、裸直连 GitHub 或 CLI 输出解析。
- Gitea/PaC lane 的 GitHub -> Gitea 自动同步必须用 `platform-infra gitea mirror webhook apply|status|test`。该路径是单向同步,只更新 Gitea branch 和 immutable snapshot ref;不得引入 Gitea -> GitHub 回写、轮询 fallback、Gitea Actions/act_runner fallback 或第二套状态存储。
- Gitea webhook/FRPC/Caddy 变更的 closeout 必须看受控 CLI 的 rollout/status/test 证据;Secret 或 ConfigMap apply 成功不等于 connector Pod 已加载新 proxy/path。
@@ -16,6 +16,7 @@ GitHub remains the upstream write authority. A delivery should be triggered by m
- Node-level status for these consumers is `bun scripts/cli.ts cicd status --node <NODE>`. Consumer drill-down is `platform-infra pipelines-as-code status|history|closeout --target <NODE> --consumer <id>`.
- Multi-node PaC consumers that share a GitHub upstream must not share a webhook bridge URL. Each target node declares its own GitHub webhook public path and FRP remote port in `config/platform-infra/gitea.yaml#targets[].webhookSync`, then `platform-infra gitea apply --target <NODE> --confirm` renders the node-local bridge, FRPC proxy and PK01 Caddy path.
- PaC Repository CR `spec.url` matches the URL in Gitea webhook payloads. Keep `config/platform-infra/pipelines-as-code.yaml#repositories[].url` on the public Gitea repository URL, and keep k8s-internal service URLs only in `cloneUrl` or `params.git_read_url`; otherwise PaC logs `cannot find a repository match` and no PipelineRun is created.
- Repositories shared by JD01 and NC01 must pass a target-specific `node` Repository param, and each `.tekton` PipelineRun must filter on that param with `pipelinesascode.tekton.dev/on-cel-expression`. A push for one target must not create the other target's PipelineRun in the same target cluster.
## Coverage Matrix
@@ -29,6 +30,7 @@ GitHub remains the upstream write authority. A delivery should be triggered by m
| `hwlab-nc01-v03` | `pikasTech/HWLAB@v0.3` | `hwlab-ci` | `hwlab-nc01-v03-ci-image-publish` | `hwlab-node-v03` | `platform-infra pipelines-as-code closeout --target NC01 --consumer hwlab-nc01-v03 --source-commit <sha> --wait` |
Use `bun scripts/cli.ts platform-infra pipelines-as-code history --target <NODE> --limit 10` for all-consumer trigger, timing and reuse audit. It must read live Gitea Repository CR plus Tekton PipelineRun/TaskRun objects on the target node, aggregate on the target side, and print `READ_ERRORS`.
`history --id <pipelinerun>` must still apply the consumer's actual PipelineRun prefix or Tekton pipeline match, so a PipelineRun in a shared namespace cannot be attributed to both JD01 and NC01 consumers.
## Closeout Order
+1
View File
@@ -5,6 +5,7 @@ metadata:
annotations:
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/on-target-branch: "[master]"
pipelinesascode.tekton.dev/on-cel-expression: "event == 'push' && target_branch == 'master' && node == 'JD01'"
labels:
app.kubernetes.io/name: hwlab-web-probe-sentinel-jd01-pac
app.kubernetes.io/part-of: hwlab-web-probe-sentinel
+1
View File
@@ -5,6 +5,7 @@ metadata:
annotations:
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/on-target-branch: "[master]"
pipelinesascode.tekton.dev/on-cel-expression: "event == 'push' && target_branch == 'master' && node == 'NC01'"
labels:
app.kubernetes.io/name: hwlab-web-probe-sentinel-nc01-pac
app.kubernetes.io/part-of: hwlab-web-probe-sentinel
@@ -127,6 +127,7 @@ templates:
git_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-agentrun.git
git_write_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-agentrun.git
source_branch: v0.2
node: "${NODE}"
gitops_branch: "${nodeLower}-v0.2-gitops"
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/agentrun-v0.2
pipeline_name: "agentrun-${nodeLower}-v02-ci-image-publish"
+1
View File
@@ -25,6 +25,7 @@
- PaC history is the trigger/timing audit surface for Gitea/PaC-managed lanes. It must query Gitea Repository CR and Tekton PipelineRun/TaskRun live objects on the target node, aggregate there, return Beijing-time display by YAML timezone, expose a detail id for drill-down, and report read errors explicitly; a large namespace or unreadable target object must never be rendered as a successful empty table.
- Formal delivery for a PaC-migrated consumer starts with merging the GitHub PR into that consumer's YAML-declared upstream branch. The GitHub webhook bridge then syncs GitHub to the controlled Gitea mirror and immutable snapshot refs; the Gitea repository push webhook triggers Pipelines-as-Code, which creates the Tekton PipelineRun. Operators must not replace this with `trigger-current`, `webhook-test`, a direct Gitea push, raw PipelineRun creation, or a local Git mirror edit. `webhook-test` is only a connectivity diagnostic.
- `config/platform-infra/pipelines-as-code.yaml` may declare multiple repositories and consumers. JD01 and NC01 both declare AgentRun, Web sentinel and HWLAB consumers; use `cicd status --node <NODE>` for node-level status, `history --target <NODE>` for all-consumer audit, and `status --target <NODE> --consumer <id>` for consumer-scoped closeout. Consumer-scoped status must not mix PipelineRuns or env reuse evidence across repositories.
- Shared upstream repositories must isolate target-specific `.tekton` files with Repository CR params, currently `node`, and `pipelinesascode.tekton.dev/on-cel-expression`. A NC01 webhook delivery must not create JD01 PipelineRuns in the NC01 cluster, and history drill-down must not attribute the same PipelineRun to multiple consumers.
- Public Gitea UI may use the YAML-declared HTTPS hostname, but k8s-internal consumers must use the ClusterIP service URL from YAML. Internal CI/Argo/runtime reads must not loop through public DNS/Caddy/FRP, and migrated lanes must not fall back to legacy git-mirror read URLs when the commit exists only in Gitea.
- A PaC-migrated lane must keep a single trigger path: Gitea webhook -> Pipelines-as-Code -> Tekton -> GitOps/Argo -> k8s runtime. Do not add Gitea Actions, `act_runner`, branch-follower or custom script fallback unless a later issue explicitly changes the architecture. `config/cicd-gitea-actions-poc.yaml` is archived POC context only; snapshot refs that still contain `gitea-actions` are historical names retained for compatibility, not evidence that Gitea Actions is active.
- k8s runtime remains Docker-free from the point it pulls already built images. CI build steps may use YAML-declared native build tooling, but Docker socket/daemon access must not become part of the runtime plane.
+4 -8
View File
@@ -59,8 +59,8 @@ export function rootHelp(): unknown {
{ command: "decision show <id|docNo>", description: "Show one Decision Center record." },
{ command: "deploy check|plan|apply [--file deploy.json|--env dev|prod] [--service id] [--commit full-sha] [--dry-run] [--force]", description: "Reconcile services from origin/master:deploy.json environments; --commit overrides one reviewed artifact consumer such as frontend for release/v1 validation or rollback. code-queue artifact consumption is dev-only." },
{ command: "cicd status --node <NODE>", description: "Show one node's CI/CD closeout summary across current Pipelines-as-Code consumers, including PipelineRun, Argo and runtime readiness." },
{ command: "cicd gitea-actions-poc plan|status", description: "Historical CI/CD migration path for GH-1548/GH-1549; current node status should use cicd status --node <NODE>." },
{ command: "cicd branch-follower plan|apply|status|run-once|events|logs", description: "Deprecated migration-only Kubernetes branch follower controller; keep existing production status/debug during cutover, but do not add new self-maintained branch-following features." },
{ command: "cicd gitea-actions-poc plan|status", description: "Archived read-only CI/CD migration evidence for GH-1548/GH-1549; never use as a delivery or closeout path." },
{ command: "cicd branch-follower status|events|logs", description: "Archived migration diagnostics only; PaC-migrated JD01/NC01 lanes must use cicd status and platform-infra pipelines-as-code closeout/status/history." },
{ command: "dev-env validate|prewarm-images", description: "Validate D601 unidesk-dev guardrails or prewarm dev foundation images into native k3s containerd through a bounded async job." },
{ command: "artifact-registry plan|render|status|health|install|deploy-backend-core|deploy-service", description: "Manage the D601 host-managed CNCF Distribution registry and run pull-only artifact CD for supported services, including D601 direct, k3s-managed, and code-queue dev-only consumers." },
{ command: "auth-broker contract|health --dry-run|credential-request --dry-run|pr-preflight --dry-run", description: "Inspect the P0 Rust auth broker and CLI adapter contract without reading token values, writing GitHub, or starting services." },
@@ -750,17 +750,13 @@ function webProbeHelpSummary(): unknown {
function cicdHelpSummary(): unknown {
return {
command: "cicd status --node <NODE> | gitea-actions-poc ... | branch-follower ...",
command: "cicd status --node <NODE>",
output: "text by default; use --json, --raw, or -o json|yaml for machine output",
usage: [
"bun scripts/cli.ts cicd status --node NC01",
"bun scripts/cli.ts cicd status --node NC01 --full",
"bun scripts/cli.ts cicd gitea-actions-poc plan",
"bun scripts/cli.ts cicd gitea-actions-poc status",
"bun scripts/cli.ts cicd branch-follower plan",
"bun scripts/cli.ts cicd branch-follower status",
],
description: "Node-level CI/CD status is the primary read path. Gitea Actions and branch-follower remain deprecated migration-only diagnostics.",
description: "Node-level CI/CD status is the primary read path for PaC-migrated consumers. Gitea Actions and branch-follower are archived diagnostics and are not delivery or closeout paths.",
};
}
@@ -567,18 +567,23 @@ function rowFor(consumer, item, taskRuns) {
};
}
function pipelineRunMatchesConsumer(consumer, item) {
const labels = item.metadata?.labels || {};
const name = item.metadata?.name || '';
return name.startsWith(consumer.pipelineRunPrefix)
|| labels['tekton.dev/pipeline'] === consumer.pipeline
|| labels['tekton.dev/pipelineName'] === consumer.pipeline;
}
const rows = [];
const consumerSummaries = [];
for (const consumer of consumers) {
const pipelineRuns = kubectlJson(['-n', consumer.namespace, 'get', 'pipelinerun', '-o', 'json'], { items: [] }, `${consumer.id}:pipelinerun`);
const taskRuns = kubectlJson(['-n', consumer.namespace, 'get', 'taskrun', '-o', 'json'], { items: [] }, `${consumer.id}:taskrun`);
let matches = (pipelineRuns.items || []).filter((item) => {
const labels = item.metadata?.labels || {};
const name = item.metadata?.name || '';
if (detailId) return name === detailId;
return name.startsWith(consumer.pipelineRunPrefix)
|| labels['tekton.dev/pipeline'] === consumer.pipeline
|| labels['tekton.dev/pipelineName'] === consumer.pipeline;
if (detailId) return name === detailId && pipelineRunMatchesConsumer(consumer, item);
return pipelineRunMatchesConsumer(consumer, item);
});
matches = matches.sort((a, b) => Date.parse(b.metadata?.creationTimestamp || 0) - Date.parse(a.metadata?.creationTimestamp || 0));
if (!detailId) matches = matches.slice(0, limit);
@@ -204,7 +204,7 @@ export async function runPlatformInfraPipelinesAsCodeCommand(config: UniDeskConf
function help(): Record<string, unknown> {
return {
command: "platform-infra pipelines-as-code plan|apply|status|closeout|history|webhook-test",
command: "platform-infra pipelines-as-code plan|apply|status|closeout|history",
configTruth: configLabel,
usage: [
"bun scripts/cli.ts platform-infra pipelines-as-code plan --target JD01",
@@ -214,9 +214,9 @@ function help(): Record<string, unknown> {
"bun scripts/cli.ts platform-infra pipelines-as-code closeout --target JD01 --consumer <consumer> --source-commit <sha> --wait",
"bun scripts/cli.ts platform-infra pipelines-as-code history --target JD01 [--consumer hwlab-jd01-v03] [--limit 10]",
"bun scripts/cli.ts platform-infra pipelines-as-code history --target JD01 --id <pipelinerun>",
"bun scripts/cli.ts platform-infra pipelines-as-code webhook-test --target JD01 --confirm",
],
boundary: "Sole CI trigger path for GH-1552: Gitea webhook -> Pipelines-as-Code -> Tekton -> Argo/k8s runtime.",
diagnostics: "webhook-test exists only for bounded connectivity diagnosis and must not be used as delivery evidence.",
boundary: "Sole CI trigger path for GH-1552/GH-1607: GitHub PR merge -> GitHub webhook bridge -> Gitea mirror/snapshot -> Pipelines-as-Code -> Tekton -> GitOps/Argo/k8s runtime.",
};
}
@@ -969,7 +969,6 @@ function nextCommands(targetId: string, consumerId: string, defaultConsumerId: s
closeout: `bun scripts/cli.ts platform-infra pipelines-as-code closeout --target ${targetId}${suffix} --wait`,
status: `bun scripts/cli.ts platform-infra pipelines-as-code status --target ${targetId}${suffix}`,
history: `bun scripts/cli.ts platform-infra pipelines-as-code history --target ${targetId}${suffix}`,
webhookTest: `bun scripts/cli.ts platform-infra pipelines-as-code webhook-test --target ${targetId}${suffix} --confirm`,
};
}