feat: add cicd branch follower
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: unidesk-cicd
|
||||
description: UniDesk CI/CD 控制面 — `hwlab g14` 和 `agentrun` 子命令,覆盖 PR 监控自动合并、Tekton/Argo 控制面、git-mirror、Secret、observability、CI tools image、PipelineRun 清理、AgentRun v0.1 部署和 AgentRun YAML-only lane 部署。用户提到 CI/CD、deploy、rollout、PipelineRun、trigger、git-mirror、control-plane、k3s 部署、agentrun 部署、hwlab g14、monitor-prs、trigger-current 时使用。任何需要把代码变更推送部署到 G14 k3s 的操作都必须走本 skill。
|
||||
description: UniDesk CI/CD 控制面 — `cicd branch-follower`、`hwlab g14`、`hwlab nodes control-plane` 和 `agentrun` 子命令,覆盖自动跟随 branch、PR 监控自动合并、Tekton/Argo 控制面、git-mirror、Secret、observability、CI tools image、PipelineRun 清理、AgentRun v0.1 部署和 AgentRun YAML-only lane 部署。用户提到 CI/CD、deploy、rollout、PipelineRun、trigger、git-mirror、control-plane、k8s/k3s 部署、branch follower、自动跟随、agentrun 部署、hwlab g14、monitor-prs、trigger-current 时使用。任何需要把代码变更推送部署到 G14 k3s 的操作都必须走本 skill。
|
||||
---
|
||||
|
||||
# UniDesk CI/CD
|
||||
@@ -15,6 +15,7 @@ bun scripts/cli.ts hwlab g14 control-plane status --lane v02
|
||||
bun scripts/cli.ts hwlab g14 control-plane trigger-current --lane v02 --confirm --wait
|
||||
bun scripts/cli.ts hwlab g14 git-mirror status --lane v02
|
||||
bun scripts/cli.ts agentrun control-plane status
|
||||
bun scripts/cli.ts cicd branch-follower status
|
||||
```
|
||||
|
||||
按职责读取拆分后的 reference:
|
||||
@@ -24,11 +25,13 @@ bun scripts/cli.ts agentrun control-plane status
|
||||
- HWLAB/AgentRun git-mirror source authority 与 flush: [references/git-mirror.md](references/git-mirror.md)。
|
||||
- Secret、observability、platform-infra、CI tools image、PipelineRun 清理和 rollout 补记: [references/platform-ops.md](references/platform-ops.md)。
|
||||
- AgentRun YAML-only lane、v0.1 兼容入口和 AgentRun git-mirror: [references/agentrun.md](references/agentrun.md)。
|
||||
- YAML-first K8s branch-follower 自动跟随、状态查询和 no-host-worktree 边界: [references/branch-follower.md](references/branch-follower.md)。
|
||||
|
||||
## P0 边界
|
||||
|
||||
- CI/CD、GitOps、rollout、PipelineRun、Argo、git-mirror 和 AgentRun 部署必须走受控 CLI;不要用裸 `kubectl`、`argo`、`tkn`、`curl` 当正式控制入口。
|
||||
- CI/CD source authority 只能来自 Kubernetes 托管的 git-mirror snapshot:受控命令先同步 GitHub refs 到 k8s git-mirror,再创建/读取不可变 `refs/unidesk/snapshots/.../<commit>` stage ref;build/status/publish 只消费该 snapshot,host worktree、本地 `git fetch/pull`、可变 branch ref 或 Pipeline 内直连 GitHub 都不能作为 authoritative source。
|
||||
- `cicd branch-follower` 的自动跟随全过程不得读取或挂载 host worktree、target dev dir、`.worktree/*` 或 local git checkout;controller pod 只能用 k8s git-mirror 和 EmptyDir 执行,状态以 K8s ConfigMap/Lease 和 adapter status 为准。
|
||||
- CI/CD、rollout、publish、image build 和部署链路禁止新引入 Docker 依赖;不得依赖 Docker socket、Docker daemon、host Docker、`docker build`、`docker push` 或等价 Docker-only 路径。
|
||||
- 正式 CI/CD、publish、image build 和 rollout 必须走 Tekton Task/Pipeline/PipelineRun 承担 CI,并通过 GitOps/Argo 承担部署收敛;普通 Kubernetes Job 只允许用于 bounded helper、source sync、diagnostic、cleanup 或 bootstrap,不得作为正式发布、镜像构建或 rollout 入口。
|
||||
- 正式 CI/CD 必须提供一键完成入口:同一受控命令应完成 source sync、构建、发布、GitOps/Argo 收敛、runtime provenance 校验和 `/health` 端点验证;不要要求操作者手动串联多个 publish/apply/status 命令才能完成一次交付。
|
||||
@@ -47,3 +50,4 @@ bun scripts/cli.ts agentrun control-plane status
|
||||
- git-mirror source authority 或 flush:读 [references/git-mirror.md](references/git-mirror.md)。
|
||||
- Secret、observability、CI tools image、PipelineRun/PV 清理:读 [references/platform-ops.md](references/platform-ops.md)。
|
||||
- AgentRun v0.1 或 YAML-only lane 部署:读 [references/agentrun.md](references/agentrun.md)。
|
||||
- 三运行面 branch follower 自动跟随、`apply/status/run-once/events/logs`:读 [references/branch-follower.md](references/branch-follower.md)。
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# CI/CD Branch Follower
|
||||
|
||||
SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower
|
||||
|
||||
## Entrypoints
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts cicd branch-follower plan
|
||||
bun scripts/cli.ts cicd branch-follower apply --confirm --wait
|
||||
bun scripts/cli.ts cicd branch-follower status
|
||||
bun scripts/cli.ts cicd branch-follower status --live
|
||||
bun scripts/cli.ts cicd branch-follower run-once --all --dry-run
|
||||
bun scripts/cli.ts cicd branch-follower run-once --follower <id> --confirm --wait
|
||||
bun scripts/cli.ts cicd branch-follower events --follower <id>
|
||||
bun scripts/cli.ts cicd branch-follower logs --follower <id>
|
||||
```
|
||||
|
||||
`apply --confirm --wait` is the one-command deploy/update entry for the K8s controller. `status` is the default intermediate-state query; add `--live` only when a fresh adapter status read is needed.
|
||||
|
||||
## Source Authority
|
||||
|
||||
- Follower decisions must not read host source worktrees, target dev directories, `.worktree/*`, local git state, or direct GitHub branch refs.
|
||||
- Controller pods use EmptyDir and clone UniDesk controller source from the YAML-declared k8s git-mirror read URL, then run the CLI with the mounted registry.
|
||||
- Runtime source commits, build contexts, publish inputs and closeout status remain owned by each adapter's k8s git-mirror snapshot and runtime objects.
|
||||
- Dirty, stale, or missing-dependency host worktrees are non-authoritative and must not change observed sha, trigger sha, PipelineRun, GitOps, or status output.
|
||||
|
||||
## YAML Ownership
|
||||
|
||||
`config/cicd-branch-followers.yaml` owns only controller settings and the follower registry: id, adapter, source/target configRefs, command argv, closeout check labels and budgets.
|
||||
|
||||
It must not copy runtime/GitOps/Secret details from owning configs:
|
||||
|
||||
- HWLAB node lanes: `config/hwlab-node-lanes.yaml`
|
||||
- AgentRun lanes: `config/agentrun.yaml`
|
||||
- Web sentinel profiles/scenarios/reports/secrets: `config/hwlab-web-probe-sentinel/*.yaml`
|
||||
|
||||
Use configRef summaries in plan/status; do not create a `full.md` or super Markdown index.
|
||||
|
||||
## First Followers
|
||||
|
||||
- `hwlab-jd01-v03`: follows `pikasTech/HWLAB@v0.3`, adapter `hwlab-node-runtime`, trigger `hwlab nodes control-plane trigger-current --node JD01 --lane v03 --confirm --wait`.
|
||||
- `agentrun-d601-v02`: follows `pikasTech/agentrun@v0.2`, adapter `agentrun-yaml-lane`, trigger `agentrun control-plane trigger-current --node D601 --lane v02 --confirm --wait`.
|
||||
- `web-probe-sentinel-master`: follows `pikasTech/unidesk@master`, adapter `web-probe-sentinel-cicd`, trigger `web-probe sentinel publish-current --node JD01 --lane v03 --sentinel jd01-web-probe-sentinel --confirm --wait`.
|
||||
|
||||
## Status Contract
|
||||
|
||||
Default `status` output must show follower id, phase, adapter, source branch + observed sha, target sha, last triggered sha, last succeeded sha, in-flight job/PipelineRun, budget source and next drill-down commands.
|
||||
|
||||
State machine phases are `Observed`, `Noop`, `PendingTrigger`, `Triggering`, `ClosingOut`, `Succeeded`, `Failed`, `Superseded`, `Blocked`, and `Skipped`.
|
||||
|
||||
`run-once --dry-run` is read-only: it may query K8s state and adapter status, but it must not write the state ConfigMap or trigger adapters.
|
||||
@@ -0,0 +1,180 @@
|
||||
# SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower
|
||||
apiVersion: unidesk.pikapython.com/v1alpha1
|
||||
kind: CicdBranchFollowerRegistry
|
||||
metadata:
|
||||
id: unidesk-cicd-branch-followers
|
||||
owner: UniDesk
|
||||
specRef: PJ2026-01060703
|
||||
version: draft-2026-07-03-p0-branch-follower
|
||||
|
||||
controller:
|
||||
namespace: devops-infra
|
||||
kubeRoute: D601:k3s
|
||||
fieldManager: unidesk-cicd-branch-follower
|
||||
serviceAccountName: unidesk-cicd-branch-follower
|
||||
deploymentName: unidesk-cicd-branch-follower
|
||||
configMapName: unidesk-cicd-branch-follower-config
|
||||
stateConfigMapName: unidesk-cicd-branch-follower-state
|
||||
leaseName: unidesk-cicd-branch-follower
|
||||
image: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-cicd-branch-follower
|
||||
app.kubernetes.io/component: cicd-control-plane
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
source:
|
||||
repository: pikasTech/unidesk
|
||||
branch: master
|
||||
gitMirrorReadUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
|
||||
sourceAuthority:
|
||||
mode: gitMirrorSnapshot
|
||||
resolver: k8s-git-mirror
|
||||
allowHostGit: false
|
||||
allowHostWorkspace: false
|
||||
allowGithubDirectInPipeline: false
|
||||
sourceSnapshot:
|
||||
stageRefPrefix: refs/unidesk/snapshots/unidesk-controller/{branch}
|
||||
missingObjectPolicy: fail-fast
|
||||
refreshPolicy: sync-before-snapshot
|
||||
loop:
|
||||
intervalSeconds: 30
|
||||
reconcileTimeoutSeconds: 110
|
||||
budgets:
|
||||
applyWaitSeconds: 120
|
||||
statusSeconds: 35
|
||||
runOnceSeconds: 120
|
||||
|
||||
followers:
|
||||
- id: hwlab-jd01-v03
|
||||
enabled: true
|
||||
adapter: hwlab-node-runtime
|
||||
description: Follow HWLAB v0.3 into the JD01 HWLAB node runtime.
|
||||
source:
|
||||
repository: pikasTech/HWLAB
|
||||
branch: v0.3
|
||||
branchRef: config/hwlab-node-lanes.yaml#lanes.v03.sourceBranch
|
||||
authorityRef: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.git.readUrl
|
||||
snapshotPrefix: refs/unidesk/snapshots/hwlab-node-runtime/v0.3
|
||||
snapshotRef: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.git.readUrl
|
||||
target:
|
||||
node: JD01
|
||||
lane: v03
|
||||
namespace: hwlab-v03
|
||||
configRefs:
|
||||
lane: config/hwlab-node-lanes.yaml#lanes.v03
|
||||
target: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01
|
||||
pipeline: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.pipeline
|
||||
pipelineRunPrefix: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.pipelineRunPrefix
|
||||
runtimeNamespace: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.runtime.namespace
|
||||
budgets:
|
||||
endToEndSeconds: 120
|
||||
statusSeconds: 35
|
||||
triggerSeconds: 120
|
||||
sourceSyncSeconds: 20
|
||||
commands:
|
||||
plan:
|
||||
argv: ["bun", "scripts/cli.ts", "hwlab", "nodes", "control-plane", "trigger-current", "--node", "JD01", "--lane", "v03", "--dry-run", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
status:
|
||||
argv: ["bun", "scripts/cli.ts", "hwlab", "nodes", "control-plane", "status", "--node", "JD01", "--lane", "v03", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
trigger:
|
||||
argv: ["bun", "scripts/cli.ts", "hwlab", "nodes", "control-plane", "trigger-current", "--node", "JD01", "--lane", "v03", "--confirm", "--wait", "--raw"]
|
||||
timeoutSeconds: 120
|
||||
events:
|
||||
argv: ["bun", "scripts/cli.ts", "hwlab", "nodes", "control-plane", "status", "--node", "JD01", "--lane", "v03", "--full"]
|
||||
timeoutSeconds: 35
|
||||
logs:
|
||||
argv: ["bun", "scripts/cli.ts", "hwlab", "nodes", "control-plane", "status", "--node", "JD01", "--lane", "v03", "--full"]
|
||||
timeoutSeconds: 35
|
||||
closeout:
|
||||
checks: ["sourceSnapshot", "pipelineRun", "gitMirrorPostFlush", "gitops", "argo", "runtime", "publicHealth"]
|
||||
|
||||
- id: agentrun-d601-v02
|
||||
enabled: true
|
||||
adapter: agentrun-yaml-lane
|
||||
description: Follow AgentRun v0.2 into the D601 YAML-only runtime lane.
|
||||
source:
|
||||
repository: pikasTech/agentrun
|
||||
branch: v0.2
|
||||
branchRef: config/agentrun.yaml#controlPlane.lanes.v02.source.branch
|
||||
authorityRef: config/agentrun.yaml#controlPlane.lanes.v02.source.sourceAuthority
|
||||
snapshotPrefix: refs/unidesk/snapshots/agentrun-yaml-lane/v0.2
|
||||
snapshotRef: config/agentrun.yaml#controlPlane.lanes.v02.source.sourceSnapshot.stageRefPrefix
|
||||
target:
|
||||
node: D601
|
||||
lane: v02
|
||||
namespace: agentrun-v02
|
||||
configRefs:
|
||||
lane: config/agentrun.yaml#controlPlane.lanes.v02
|
||||
source: config/agentrun.yaml#controlPlane.lanes.v02.source
|
||||
runtime: config/agentrun.yaml#controlPlane.lanes.v02.runtime
|
||||
pipeline: config/agentrun.yaml#controlPlane.lanes.v02.ci.pipeline
|
||||
pipelineRunPrefix: config/agentrun.yaml#controlPlane.lanes.v02.ci.pipelineRunPrefix
|
||||
argoApplication: config/agentrun.yaml#controlPlane.lanes.v02.gitops.argoApplication
|
||||
budgets:
|
||||
endToEndSeconds: 120
|
||||
statusSeconds: 35
|
||||
triggerSeconds: 120
|
||||
sourceSyncSeconds: 20
|
||||
commands:
|
||||
plan:
|
||||
argv: ["bun", "scripts/cli.ts", "agentrun", "control-plane", "trigger-current", "--node", "D601", "--lane", "v02", "--dry-run", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
status:
|
||||
argv: ["bun", "scripts/cli.ts", "agentrun", "control-plane", "status", "--node", "D601", "--lane", "v02", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
trigger:
|
||||
argv: ["bun", "scripts/cli.ts", "agentrun", "control-plane", "trigger-current", "--node", "D601", "--lane", "v02", "--confirm", "--wait", "--raw"]
|
||||
timeoutSeconds: 120
|
||||
events:
|
||||
argv: ["bun", "scripts/cli.ts", "agentrun", "control-plane", "status", "--node", "D601", "--lane", "v02", "--full"]
|
||||
timeoutSeconds: 35
|
||||
logs:
|
||||
argv: ["bun", "scripts/cli.ts", "agentrun", "control-plane", "status", "--node", "D601", "--lane", "v02", "--full"]
|
||||
timeoutSeconds: 35
|
||||
closeout:
|
||||
checks: ["sourceSnapshot", "pipelineRun", "gitops", "argo", "manager", "runtimeHealth"]
|
||||
|
||||
- id: web-probe-sentinel-master
|
||||
enabled: true
|
||||
adapter: web-probe-sentinel-cicd
|
||||
description: Follow UniDesk master into the selected HWLAB web-probe sentinel runtime.
|
||||
source:
|
||||
repository: pikasTech/unidesk
|
||||
branch: master
|
||||
branchRef: config/hwlab-web-probe-sentinel/profiles.yaml#nodes.JD01.sentinels.jd01-web-probe-sentinel.cicd.source.branch
|
||||
authorityRef: config/hwlab-web-probe-sentinel/profiles.yaml#nodes.JD01.sentinels.jd01-web-probe-sentinel.cicd.sourceAuthority
|
||||
snapshotPrefix: refs/unidesk/snapshots/web-probe-sentinel/master
|
||||
snapshotRef: config/hwlab-web-probe-sentinel/profiles.yaml#nodes.JD01.sentinels.jd01-web-probe-sentinel.cicd.sourceSnapshot.stageRefPrefix
|
||||
target:
|
||||
node: JD01
|
||||
lane: v03
|
||||
namespace: hwlab-v03
|
||||
sentinel: jd01-web-probe-sentinel
|
||||
configRefs:
|
||||
sentinel: config/hwlab-web-probe-sentinel/profiles.yaml#nodes.JD01.sentinels.jd01-web-probe-sentinel.sentinel
|
||||
cicd: config/hwlab-web-probe-sentinel/profiles.yaml#nodes.JD01.sentinels.jd01-web-probe-sentinel.cicd
|
||||
monitorRoot: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.observability.webProbe.monitorRoot
|
||||
budgets:
|
||||
endToEndSeconds: 120
|
||||
statusSeconds: 35
|
||||
triggerSeconds: 120
|
||||
sourceSyncSeconds: 20
|
||||
commands:
|
||||
plan:
|
||||
argv: ["bun", "scripts/cli.ts", "web-probe", "sentinel", "publish-current", "--node", "JD01", "--lane", "v03", "--sentinel", "jd01-web-probe-sentinel", "--dry-run", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
status:
|
||||
argv: ["bun", "scripts/cli.ts", "web-probe", "sentinel", "control-plane", "status", "--node", "JD01", "--lane", "v03", "--sentinel", "jd01-web-probe-sentinel", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
trigger:
|
||||
argv: ["bun", "scripts/cli.ts", "web-probe", "sentinel", "publish-current", "--node", "JD01", "--lane", "v03", "--sentinel", "jd01-web-probe-sentinel", "--confirm", "--wait", "--raw"]
|
||||
timeoutSeconds: 120
|
||||
events:
|
||||
argv: ["bun", "scripts/cli.ts", "web-probe", "sentinel", "control-plane", "status", "--node", "JD01", "--lane", "v03", "--sentinel", "jd01-web-probe-sentinel", "--full"]
|
||||
timeoutSeconds: 35
|
||||
logs:
|
||||
argv: ["bun", "scripts/cli.ts", "web-probe", "sentinel", "report", "--node", "JD01", "--lane", "v03", "--sentinel", "jd01-web-probe-sentinel", "--latest", "--view", "summary", "--raw"]
|
||||
timeoutSeconds: 35
|
||||
closeout:
|
||||
checks: ["sourceMirror", "imageRegistry", "gitops", "argo", "runtimeHealthEndpoint", "dashboard", "report"]
|
||||
@@ -0,0 +1,112 @@
|
||||
# PJ2026-01060703 CI/CD Branch Follower
|
||||
|
||||
SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower
|
||||
|
||||
## 1. 目标
|
||||
|
||||
为 UniDesk 建立一个 YAML-first、Kubernetes 原生的 CI/CD branch follower 组件,自动跟随三个首批运行面的上游 branch,并通过单一 CLI 完成部署、触发和中间状态查询。
|
||||
|
||||
首批 follower:
|
||||
|
||||
- `hwlab-jd01-v03`: 跟随 `pikasTech/HWLAB@v0.3`,触发 `hwlab-node-runtime` 控制面。
|
||||
- `agentrun-d601-v02`: 跟随 `pikasTech/agentrun@v0.2`,触发 `agentrun-yaml-lane` 控制面。
|
||||
- `web-probe-sentinel-master`: 跟随 `pikasTech/unidesk@master`,触发 YAML 选中的 web-probe sentinel CI/CD。
|
||||
|
||||
## 2. 强约束
|
||||
|
||||
- branch observation、source snapshot、build context、publish、closeout 的权威来源只能是 Kubernetes 管理的 git-mirror immutable snapshot 和运行面对象。
|
||||
- controller pod、Job、Pipeline、publish 流程不得挂载或读取 host source workspace、开发 worktree、`.worktree/*`、local git checkout 或 direct GitHub fallback。
|
||||
- host worktree 只能作为人工 debug 或 post-deploy 验证入口,不能影响 follower 的 sha 决策、PipelineRun、GitOps 或状态判断。
|
||||
- 所有可调项进入 YAML;代码只解析 configRef、selector、adapter id、预算和命令,不写隐藏默认。
|
||||
- registry 不承载运行面/GitOps/Secret 细节;HWLAB、AgentRun、web-probe sentinel 细节仍归属各自 YAML。
|
||||
- 默认 CLI 输出必须是简洁表格和 drill-down 命令;完整 JSON/YAML 只通过 `--json`、`--raw` 或 `-o json|yaml` 输出。
|
||||
- 端到端 closeout 预算以 YAML 声明,首批 follower 目标为 120s 内收敛;超预算必须可见,不做无限等待。
|
||||
|
||||
## 3. YAML 职责边界
|
||||
|
||||
`config/cicd-branch-followers.yaml` 只声明:
|
||||
|
||||
- controller 的 namespace、kube route、ServiceAccount、Lease、ConfigMap、镜像和循环预算。
|
||||
- follower registry:id、enabled、adapter、source ref、target ref、status/trigger/event/log drill-down 命令、closeout check 名称和预算。
|
||||
- 对拥有配置的引用:`config/hwlab-node-lanes.yaml`、`config/agentrun.yaml`、`config/hwlab-web-probe-sentinel/*.yaml`。
|
||||
|
||||
它不声明:
|
||||
|
||||
- HWLAB runtime workload、GitOps path、Secret sourceRef、registry image rewrite 细节。
|
||||
- AgentRun manager/runtime/secret/GitOps 细节。
|
||||
- Web sentinel scenario/prompt/report/runtime/publicExposure/secret 细节。
|
||||
|
||||
## 4. CLI
|
||||
|
||||
入口:
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts cicd branch-follower plan
|
||||
bun scripts/cli.ts cicd branch-follower apply --confirm --wait
|
||||
bun scripts/cli.ts cicd branch-follower status
|
||||
bun scripts/cli.ts cicd branch-follower run-once --all --dry-run
|
||||
bun scripts/cli.ts cicd branch-follower events --follower hwlab-jd01-v03
|
||||
bun scripts/cli.ts cicd branch-follower logs --follower hwlab-jd01-v03
|
||||
```
|
||||
|
||||
默认视图显示:
|
||||
|
||||
- follower id、adapter、source branch、observed sha、target sha、last triggered sha、last succeeded sha。
|
||||
- phase:`Observed`、`Noop`、`PendingTrigger`、`Triggering`、`ClosingOut`、`Succeeded`、`Failed`、`Superseded`。
|
||||
- in-flight job、budget source、controller/state age、next drill-down。
|
||||
|
||||
## 5. Controller
|
||||
|
||||
`apply` 渲染并下发:
|
||||
|
||||
- Namespace。
|
||||
- ServiceAccount。
|
||||
- Role/RoleBinding。
|
||||
- ConfigMap:registry YAML。
|
||||
- ConfigMap:follower state。
|
||||
- Lease:leader election anchor。
|
||||
- Deployment:controller loop。
|
||||
|
||||
Deployment 使用 EmptyDir 作为工作目录,只从 Kubernetes git-mirror clone UniDesk controller source,并把 mounted registry 覆盖到 cloned repo 的 `config/cicd-branch-followers.yaml` 后执行:
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts cicd branch-follower run-once --all --confirm --wait --controller
|
||||
```
|
||||
|
||||
该路径不挂载 host source,不读取 host worktree,不依赖 target dev directory。
|
||||
|
||||
## 6. Adapter 合同
|
||||
|
||||
每个 adapter 复用既有受控 CLI:
|
||||
|
||||
- `hwlab-node-runtime`: `hwlab nodes control-plane status|trigger-current --node JD01 --lane v03`
|
||||
- `agentrun-yaml-lane`: `agentrun control-plane status|trigger-current --node D601 --lane v02`
|
||||
- `web-probe-sentinel-cicd`: `web-probe sentinel publish-current|control-plane status --node JD01 --lane v03 --sentinel jd01-web-probe-sentinel`
|
||||
|
||||
branch follower 不直接操作 Tekton、Argo、kubectl 或 GitHub。它只通过 adapter 命令读取 compact status 或触发已存在的控制面。
|
||||
|
||||
## 7. 状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Observed
|
||||
Observed --> Noop: observed == target
|
||||
Observed --> PendingTrigger: observed != target
|
||||
PendingTrigger --> Triggering
|
||||
Triggering --> ClosingOut
|
||||
ClosingOut --> Succeeded
|
||||
ClosingOut --> Failed
|
||||
Triggering --> Superseded: branch advanced
|
||||
Failed --> PendingTrigger: retryable
|
||||
Succeeded --> Observed: next loop
|
||||
```
|
||||
|
||||
## 8. 验收
|
||||
|
||||
- `bun scripts/cli.ts cicd branch-follower apply --confirm --wait` 一条 CLI 可完成 controller 更新并等待 K8s 对象 ready。
|
||||
- `bun scripts/cli.ts cicd branch-follower status` 可查询 controller、state ConfigMap 和三个 follower 的中间状态。
|
||||
- `bun scripts/cli.ts cicd branch-follower run-once --all --dry-run` 对三个首批 follower 给出 Noop/PendingTrigger/Blocked 决策,不发生写操作。
|
||||
- 任一 source branch 新 sha 只触发一次;重复 sha 不重复触发;branch advance 时旧 in-flight sha 标记为 Superseded。
|
||||
- follower 决策和状态不读取 host worktree;故意弄脏/滞后/缺依赖的目标 dev dir 不影响 observed sha、trigger sha 和 closeout 状态。
|
||||
- Secret/API key 只显示对象名、key 名、presence、fingerprint 或 sourceRef,不打印值。
|
||||
- 不新增 `full.md` 或超级 Markdown;长期入口在 skill `SKILL.md` 引用拆分后的职责文档。
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPEC: PJ2026-01060509 出站诊断 draft-2026-06-26-p8-egress-job-friction.
|
||||
// SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower.
|
||||
// UniDesk CLI dispatcher with bounded server lifecycle and job drill-down output.
|
||||
import { readConfig } from "./src/config";
|
||||
import { debugDispatch, debugEgressProxy, debugHealth, debugSshPool, debugTask, isDebugDispatchCommand, type DebugDispatchCommand } from "./src/debug";
|
||||
@@ -267,6 +268,20 @@ async function main(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (top === "cicd") {
|
||||
const { runCicdCommand } = await import("./src/cicd");
|
||||
const result = await runCicdCommand(null, args.slice(1));
|
||||
const ok = (result as { ok?: unknown }).ok !== false;
|
||||
if (isRenderedCliResult(result)) {
|
||||
emitText(result.renderedText, result.command || commandName);
|
||||
if (!ok) process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
emitJson(commandName, result, ok);
|
||||
if (!ok) process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (top === "agentrun") {
|
||||
const { runAgentRunCommand } = await import("./src/agentrun");
|
||||
const agentRunArgs = args.slice(1);
|
||||
|
||||
+1586
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
// SPEC: PJ2026-01060509 出站诊断 draft-2026-06-26-p8-egress-job-friction.
|
||||
// SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower.
|
||||
// Static CLI help for job aliases and server lifecycle progressive disclosure.
|
||||
import { ghHelp, ghScopedHelp } from "./gh";
|
||||
import { authBrokerHelp } from "./auth-broker";
|
||||
@@ -57,6 +58,7 @@ export function rootHelp(): unknown {
|
||||
{ command: "decision requirement list|create|show|update|upsert [id|docNo] [--title text] [--body-file path] [--type external_goal|internal_goal|goal|decision|blocker|debt|experiment] [--doc-no DC-...] [--doc-type ...] [--doc-priority P0|P1|P2|P3] [--signer text] [--issued-at ISO]", description: "Manage productized requirement records over the PostgreSQL records model, excluding meeting records." },
|
||||
{ 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 branch-follower plan|apply|status|run-once|events|logs", description: "Deploy and inspect the YAML-first Kubernetes branch follower for HWLAB v0.3, AgentRun v0.2, and web-probe sentinel master without using host worktrees as source authority." },
|
||||
{ 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." },
|
||||
@@ -730,6 +732,20 @@ function webProbeHelpSummary(): unknown {
|
||||
};
|
||||
}
|
||||
|
||||
function cicdHelpSummary(): unknown {
|
||||
return {
|
||||
command: "cicd branch-follower plan|apply|status|run-once|events|logs",
|
||||
output: "text by default; use --json, --raw, or -o json|yaml for machine output",
|
||||
usage: [
|
||||
"bun scripts/cli.ts cicd branch-follower plan",
|
||||
"bun scripts/cli.ts cicd branch-follower apply --confirm --wait",
|
||||
"bun scripts/cli.ts cicd branch-follower status",
|
||||
"bun scripts/cli.ts cicd branch-follower run-once --all --dry-run",
|
||||
],
|
||||
description: "YAML-first Kubernetes branch follower for three CI/CD running planes, with K8s state and adapter drill-down visibility.",
|
||||
};
|
||||
}
|
||||
|
||||
function hwlabG14HelpSummary(): unknown {
|
||||
return {
|
||||
command: "hwlab g14 monitor-prs|control-plane|git-mirror|tools-image|retirement",
|
||||
@@ -795,6 +811,7 @@ export async function staticNamespaceHelp(args: string[]): Promise<unknown | nul
|
||||
if (top === "artifact-registry") return artifactRegistryHelp();
|
||||
if (top === "auth-broker") return authBrokerHelp();
|
||||
if (top === "gh") return ghScopedHelp(args.slice(1)) ?? ghHelp();
|
||||
if (top === "cicd") return loadHelp(async () => (await import("./cicd")).cicdHelp(), cicdHelpSummary());
|
||||
if (top === "agentrun") return loadHelp(async () => (await import("./agentrun")).agentRunHelp(), agentRunHelpSummary());
|
||||
if (top === "platform-infra") return loadHelp(async () => (await import("./platform-infra")).platformInfraHelp(), platformInfraHelpSummary());
|
||||
if (top === "platform-db") return platformDbHelp();
|
||||
|
||||
Reference in New Issue
Block a user