From 7a04f9fc7259eb539b76c6a0ec80ab07bcc5e548 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 20 May 2026 01:44:18 +0000 Subject: [PATCH] fix: complete artifact consumer help and todo note verification --- docs/reference/artifact-registry.md | 11 +++++-- docs/reference/deploy.md | 6 ++-- docs/reference/deployment.md | 2 +- docs/reference/microservices.md | 2 +- docs/reference/user-service-delivery.md | 8 +++-- scripts/src/artifact-registry.ts | 41 ++++++++++++++++--------- scripts/src/deploy.ts | 5 ++- scripts/src/help.ts | 11 +++++-- 8 files changed, 56 insertions(+), 30 deletions(-) diff --git a/docs/reference/artifact-registry.md b/docs/reference/artifact-registry.md index 0089fb90..5cdbc39f 100644 --- a/docs/reference/artifact-registry.md +++ b/docs/reference/artifact-registry.md @@ -63,6 +63,10 @@ bun scripts/cli.ts artifact-registry deploy-service --service baidu-netdisk --co bun scripts/cli.ts artifact-registry deploy-service --service frontend --env prod --commit bun scripts/cli.ts artifact-registry deploy-service --service frontend --env dev --commit bun scripts/cli.ts artifact-registry deploy-service --service decision-center --commit +bun scripts/cli.ts artifact-registry deploy-service --env prod --service project-manager --commit +bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit +bun scripts/cli.ts artifact-registry deploy-service --env prod --service code-queue-mgr --commit --dry-run +bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit ``` `plan` 输出架构边界、依赖项、默认路径和 backend-core artifact CD 流程。`render` 输出 systemd unit、Compose 文件和 registry config 的完整内容与 SHA-256。`install --dry-run` 只列出将要执行的远端动作,不写 D601 文件、不启动容器、不 reload systemd。 @@ -71,7 +75,7 @@ bun scripts/cli.ts artifact-registry deploy-service --service decision-center -- `deploy-backend-core` 是旧兼容入口,当前作为标准路径已禁用。Production backend-core CD 必须使用 `bun scripts/cli.ts deploy apply --env prod --service backend-core --commit `,由 deploy reconciler 先执行共同的 artifact-consumer guardrail,再调用通用 `deploy-service` consumer。旧入口只能返回 structured deprecated 结果,不得绕过 `deploy apply --env prod`。 -`deploy-service` 是标准化后的最小通用 artifact consumer。它目前只支持 `backend-core`、`baidu-netdisk`、prod/dev `frontend` 和 `decision-center`,并且必须先通过 D601 registry 的 commit-pinned manifest 校验,再执行拉取、导入/retag、部署和健康验证: +`deploy-service` 是标准化后的最小通用 artifact consumer。它目前支持 `backend-core`、`baidu-netdisk`、prod/dev `frontend`、`decision-center`、`project-manager`、`oa-event-flow`、`code-queue-mgr` 和 `todo-note`,并且必须先通过 D601 registry 的 commit-pinned manifest 校验,再执行拉取、导入/retag、部署和健康验证;`code-queue-mgr` 的 prod live apply 仍需 supervisor 单独确认: ```bash bun scripts/cli.ts artifact-registry deploy-service --service baidu-netdisk --commit --run-now @@ -79,6 +83,9 @@ bun scripts/cli.ts artifact-registry deploy-service --service frontend --env pro bun scripts/cli.ts artifact-registry deploy-service --service frontend --env dev --commit --run-now bun scripts/cli.ts artifact-registry deploy-service --env dev --service decision-center --commit --run-now bun scripts/cli.ts artifact-registry deploy-service --service decision-center --commit --run-now +bun scripts/cli.ts artifact-registry deploy-service --env prod --service project-manager --commit --run-now +bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit --run-now +bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit --run-now ``` dry-run 输出会暴露 registry probe URL、required labels、目标 image、部署形态和回滚信息。`baidu-netdisk` 的 Compose 路径会通过 provider-gateway Host SSH 把 `unidesk/baidu-netdisk:` 流式拉到 master server,retag 为 `baidu-netdisk` 和 `baidu-netdisk:`,写入 `UNIDESK_BAIDU_NETDISK_DEPLOY_*`,只 recreate `baidu-netdisk` service,并验证容器 image label 与 `/health.deploy.commit`。`frontend --env prod` 使用同一 Compose artifact consumer,流式拉取 `unidesk/frontend:`,retag 为 `unidesk-frontend` 和 `unidesk-frontend:`,写入 `UNIDESK_FRONTEND_DEPLOY_*`,只 recreate `frontend` service,并验证 image label 与 `/health.deploy.commit`。`frontend --env dev` 和 `decision-center` 的 k3s 路径会在 D601 上验证 commit image、导入 native k3s containerd、更新 Deployment image/env/annotations,并通过 Kubernetes API service proxy 验证 `/health` 中的 `deploy.commit` 和 `deploy.requestedCommit`;dev frontend 还会在 rollout 前把主 server `config.json.auth` 同步到 `unidesk-dev` Secret/ConfigMap。`decision-center --env dev` 落到 `unidesk-dev/decision-center-dev`,prod 落到 `unidesk/decision-center`。回滚信息通过同一 artifact consumer 的 `rollback` 字段暴露,提示操作者重新对一个旧 commit 运行相同命令,而不是切回 legacy maintenance-channel 构建。 @@ -125,7 +132,7 @@ docker compose -p unidesk-artifact-registry -f /home/ubuntu/.unidesk/artifact-re 6. Compose runtime retag 为 Compose 使用的镜像名,并执行 `docker compose up -d --no-build --no-deps --force-recreate `;k3s runtime 设置 Deployment image/env/annotations 并等待 rollout。 7. 部署后通过 image label、runtime env、health payload 验证 live commit。 -Baidu Netdisk is the first main-server direct user-service sample in this flow. Its dev validation command and prod CD command both consume `127.0.0.1:5000/unidesk/baidu-netdisk:` and must not build source on the master server. Frontend is the standard UniDesk UI artifact sample: CI publishes `127.0.0.1:5000/unidesk/frontend:`, production CD consumes that artifact into the master-server Compose `frontend` service, and dev CD consumes the same artifact into D601 native k3s `frontend-dev`. Project Manager and OA Event Flow use the same master-server Compose artifact-consumer shape as Baidu Netdisk, with `project-manager-backend` and `oa-event-flow-backend` as the runtime containers. Code Queue Manager is supported as an artifact consumer for validation, but prod live apply is supervisor-gated. Todo Note currently returns a structured runtime-verification block until the checked-in health contract proves `deploy.commit` and `deploy.requestedCommit`. Neither path may use `server rebuild frontend`, dirty source, mutable `latest`, or target-side frontend source builds as release truth. Decision Center follows the same artifact-consumer pattern in both dev and prod, except the runtime target is native k3s on D601 instead of the master-server Compose stack. The consumer must check the registry manifest, pull the commit-pinned image, import it into `/run/k3s/containerd/containerd.sock`, set the Deployment image to the commit tag, stamp `UNIDESK_DEPLOY_*` env/annotations, and reject an old healthy revision if the live commit or requested commit does not match. +Baidu Netdisk is the first main-server direct user-service sample in this flow. Its dev validation command and prod CD command both consume `127.0.0.1:5000/unidesk/baidu-netdisk:` and must not build source on the master server. Frontend is the standard UniDesk UI artifact sample: CI publishes `127.0.0.1:5000/unidesk/frontend:`, production CD consumes that artifact into the master-server Compose `frontend` service, and dev CD consumes the same artifact into D601 native k3s `frontend-dev`. Project Manager, OA Event Flow and Todo Note use the same master-server Compose artifact-consumer shape as Baidu Netdisk, with `project-manager-backend`, `oa-event-flow-backend` and `todo-note-backend` as the runtime containers; Todo Note keeps its external source repository and requires a pre-existing `127.0.0.1:5000/unidesk/todo-note:` artifact. Its consumer injects `UNIDESK_TODO_NOTE_DEPLOY_*` runtime metadata and the container health probe combines `/api/health` with that metadata before enforcing `deploy.commit` / `deploy.requestedCommit`. Code Queue Manager is supported as an artifact consumer for validation, but prod live apply is supervisor-gated. Neither path may use `server rebuild frontend`, dirty source, mutable `latest`, or target-side frontend source builds as release truth. Decision Center follows the same artifact-consumer pattern in both dev and prod, except the runtime target is native k3s on D601 instead of the master-server Compose stack. The consumer must check the registry manifest, pull the commit-pinned image, import it into `/run/k3s/containerd/containerd.sock`, set the Deployment image to the commit tag, stamp `UNIDESK_DEPLOY_*` env/annotations, and reject an old healthy revision if the live commit or requested commit does not match. 这个 CD 路径必须满足: diff --git a/docs/reference/deploy.md b/docs/reference/deploy.md index 62743c12..9a885dda 100644 --- a/docs/reference/deploy.md +++ b/docs/reference/deploy.md @@ -40,7 +40,7 @@ The root `deploy.json` is the single desired-state source for both prod and dev. The optional non-service execution declaration under `environments.dev` is intentionally not specified here. The only currently allowed declaration is `ci`, and its authoritative `repo`, `scriptPath`, `timeoutMs`, short launcher, host fetch boundary and no-CD rules are defined only in `docs/reference/dev-ci-runner.md`. -Environment mode never reads the local dirty working tree manifest. `deploy check --env ...`, `deploy plan --env ...` and `deploy apply --env ...` fetch `origin/master`, read `origin/master:deploy.json`, select `environments.`, and report the manifest commit/blob, service commit IDs, target namespace, database fingerprint and Provider identity. `deploy apply --env dev` is currently enabled for persistent D601 dev `backend-core` target-side rollout and for reviewed artifact consumers `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, `oa-event-flow`, and `code-queue-mgr`; `todo-note` remains dry-run only until runtime verification is proven. `deploy apply --env prod` exposes only reviewed registry artifact consumers (`backend-core`, `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, `oa-event-flow`), while `code-queue-mgr` remains supervisor-gated and `todo-note` stays blocked. Production backend-core artifact CD is a separate executor because its build target is D601 CI while its runtime target is the master server. The default user-service delivery policy, including CI build, registry publication, dev validation, production CD and manual acceptance, is documented in `docs/reference/user-service-delivery.md`. +Environment mode never reads the local dirty working tree manifest. `deploy check --env ...`, `deploy plan --env ...` and `deploy apply --env ...` fetch `origin/master`, read `origin/master:deploy.json`, select `environments.`, and report the manifest commit/blob, service commit IDs, target namespace, database fingerprint and Provider identity. `deploy apply --env dev` is currently enabled for persistent D601 dev `backend-core` target-side rollout and for reviewed artifact consumers `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, `oa-event-flow`, `code-queue-mgr`, and `todo-note`. `deploy apply --env prod` exposes reviewed registry artifact consumers (`backend-core`, `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, `oa-event-flow`, and `todo-note`), while `code-queue-mgr` remains supervisor-gated. Production backend-core artifact CD is a separate executor because its build target is D601 CI while its runtime target is the master server. The default user-service delivery policy, including CI build, registry publication, dev validation, production CD and manual acceptance, is documented in `docs/reference/user-service-delivery.md`. For services with reviewed production artifact consumers, local-manifest `deploy apply --file ...` is not a production fallback. The CLI blocks `backend-core`, `frontend`, `baidu-netdisk` and `decision-center` before source materialization or Docker build and directs operators to `deploy apply --env prod --service --commit `. This prevents a dirty worktree, local manifest or target-side source build from bypassing the pull-only artifact CD guardrails. The broader precheck and legacy-path classification live in `docs/reference/cicd-standardization.md`. @@ -85,7 +85,7 @@ Phase 3 introduces the dev backend/frontend manifest at `src/components/microser `backend-core-dev` must use `unidesk-dev-runtime-config` and `unidesk-dev-runtime-secrets`, connect to `postgres-dev.../unidesk_dev`, expose HTTP on 8080 and provider ingress on 8081, and write logs under `/var/log/unidesk-dev`. `frontend-dev` must set `CORE_INTERNAL_URL=http://backend-core-dev.unidesk-dev.svc.cluster.local:8080` and must not proxy to production backend-core. -The manifest keeps placeholder image tags and deploy commit values in source control. The controlled `deploy apply --env dev --service backend-core` path fetches `origin/master:deploy.json`, materializes the requested source commit on D601, narrows the dev core control manifest to the selected Service/Deployment pair, replaces placeholders with the requested commit and dev image tag, builds on D601, imports the image into native k3s containerd, applies only the `unidesk-dev` objects and stamps the Deployment. `deploy apply --env dev --service frontend`, `decision-center`, `project-manager` and `oa-event-flow` use the same selected dev manifest objects but consume the existing D601 registry artifact instead of building source on the target. `code-queue-mgr` uses the same dev manifest validation path for Compose artifact consumer checks; live prod apply remains supervisor-gated. `todo-note` currently returns a structured runtime-verification block until the checked-in health contract proves `deploy.commit` and `deploy.requestedCommit`. Client dry-run and static validation remain useful checks before controlled apply: +The manifest keeps placeholder image tags and deploy commit values in source control. The controlled `deploy apply --env dev --service backend-core` path fetches `origin/master:deploy.json`, materializes the requested source commit on D601, narrows the dev core control manifest to the selected Service/Deployment pair, replaces placeholders with the requested commit and dev image tag, builds on D601, imports the image into native k3s containerd, applies only the `unidesk-dev` objects and stamps the Deployment. `deploy apply --env dev --service frontend`, `decision-center`, `project-manager`, `oa-event-flow`, `code-queue-mgr`, and `todo-note` consume the existing D601 registry artifact instead of building source on the target. `code-queue-mgr` live prod apply remains supervisor-gated. Client dry-run and static validation remain useful checks before controlled apply: - `bun scripts/cli.ts dev-env validate --manifest src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-core.k8s.yaml` - `KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl apply --dry-run=client --validate=false -f src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-core.k8s.yaml` @@ -108,7 +108,7 @@ Maintenance-channel direct D601 apply must not deploy dev Code Queue; the CLI re `bun scripts/cli.ts deploy plan --env dev [--service ]` reads `origin/master:deploy.json#environments.dev` and prints a dry-run environment plan without checking or mutating live runtime resources. `deploy check --env dev` uses the same dry-run environment plan. `--env prod` is available for parity as a dry-run planning path; it reads `origin/master:deploy.json#environments.prod` and must not use a dirty local `deploy.json`. -`bun scripts/cli.ts deploy apply [--file deploy.json | --env dev|prod] [--service ] [--commit ] [--dry-run] [--force]` starts an asynchronous job only for supported targets. Use `bun scripts/cli.ts job status --tail-bytes 30000` to observe progress. `--dry-run` resolves the same plan but does not build or replace runtime objects. `--force` rebuilds even when the live commit matches. Environment apply is not the dev e2e trigger; use `bun scripts/cli.ts ci run-dev-e2e` for the Git-controlled temporary namespace smoke flow. `--env dev` apply is enabled for persistent D601 `backend-core` target-side rollout and for `frontend`/`baidu-netdisk`/`decision-center`/`project-manager`/`oa-event-flow`/`code-queue-mgr` artifact consumers, while `todo-note` remains dry-run only until runtime verification is proven. `--env prod` apply exposes the D601 registry artifact consumer for `backend-core`, `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, and `oa-event-flow`; `code-queue-mgr` prod live apply is supervisor-gated and `todo-note` remains blocked. Unsupported prod services return a structured `unsupported` payload instead of silently falling back to a maintenance-channel source build. +`bun scripts/cli.ts deploy apply [--file deploy.json | --env dev|prod] [--service ] [--commit ] [--dry-run] [--force]` starts an asynchronous job only for supported targets. Use `bun scripts/cli.ts job status --tail-bytes 30000` to observe progress. `--dry-run` resolves the same plan but does not build or replace runtime objects. `--force` rebuilds even when the live commit matches. Environment apply is not the dev e2e trigger; use `bun scripts/cli.ts ci run-dev-e2e` for the Git-controlled temporary namespace smoke flow. `--env dev` apply is enabled for persistent D601 `backend-core` target-side rollout and for `frontend`/`baidu-netdisk`/`decision-center`/`project-manager`/`oa-event-flow`/`code-queue-mgr`/`todo-note` artifact consumers. `--env prod` apply exposes the D601 registry artifact consumer for `backend-core`, `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, `oa-event-flow`, and `todo-note`; `code-queue-mgr` prod live apply is supervisor-gated. Unsupported prod services return a structured `unsupported` payload instead of silently falling back to a maintenance-channel source build. All deploy commands output JSON. Long operations must use `.state/jobs/` and bounded log tails; no deploy path may succeed with missing progress output. diff --git a/docs/reference/deployment.md b/docs/reference/deployment.md index 5a0d9690..f64c9ce9 100644 --- a/docs/reference/deployment.md +++ b/docs/reference/deployment.md @@ -30,7 +30,7 @@ CLI 会优先使用 `docker compose` v2 plugin;当 v2 plugin 不存在时才 Compose v2 安装后仍然必须遵守 UniDesk 的服务控制入口:全栈生命周期用 `server start` / `server stop`,单服务重建用 `server rebuild `。不要因为 v2 可用就直接在生产栈上手工执行未纳入 CLI 的 `up --build`、`down -v` 或跨项目清理命令;所有会影响容器的动作都应保持 job 可观测、Compose project 固定、database named volume 保留。主 server Compose 命令必须从 `providerGateway.upgrade.hostProjectRoot` 指定的 canonical UniDesk 根目录运行,临时 worktree、Code Queue 导出目录或实验分支不得复用生产 `-p unidesk` 和固定 `container_name` 去替换生产容器。 -版本化用户服务部署优先使用 `bun scripts/cli.ts deploy apply` 已支持的受控路径;D601 persistent dev apply 当前支持 `backend-core` target-side rollout,以及 `frontend`、`baidu-netdisk`、`decision-center`、`project-manager`、`oa-event-flow` 和 `code-queue-mgr` 的 artifact consumer validation,`todo-note` 仅能做 runtime-verification dry-run。`deploy.json` 只声明服务 `id`、`repo` 和 `commitId`;目标节点、Dockerfile、Compose、Kubernetes manifest、健康检查和代理路径继续来自 `config.json` 与现有 manifest。主 server 直管微服务和内部 sidecar,例如 `code-queue-mgr`,也必须支持这一路径:`deploy apply --service code-queue-mgr` 从 `deploy.json` 指定 commit 导出源码、构建镜像、替换固定 Compose service 并验证运行中镜像/健康信息的 commit,但 prod live apply 仍需 supervisor 确认。部署默认遵循 target-side build:服务部署到哪台 target,就在哪台 target 从 remote commit 导出源码、一次性代理构建镜像并部署;不得把中心构建镜像作为默认分发路径,也不得用 `docker commit` 或脏 worktree 作为部署输入。production backend-core 是明确例外;`frontend` 是用户服务 UI / 前端镜像化样板,`baidu-netdisk` 是主 server 直管微服务的镜像化样板:D601 CI 构建并推送 commit-pinned 镜像到 D601 artifact registry,dev/prod CD 只拉取、retag 或导入、recreate/rollout 和验证,不在 master server 或 dev target 执行 frontend Compose build。完整规则见 `docs/reference/deploy.md`,D601 dev/Rust 边界见 `docs/reference/dev-environment.md`,artifact registry 见 `docs/reference/artifact-registry.md`。 +版本化用户服务部署优先使用 `bun scripts/cli.ts deploy apply` 已支持的受控路径;D601 persistent dev apply 当前支持 `backend-core` target-side rollout,以及 `frontend`、`baidu-netdisk`、`decision-center`、`project-manager`、`oa-event-flow`、`code-queue-mgr` 和 `todo-note` 的 artifact consumer validation。`deploy.json` 只声明服务 `id`、`repo` 和 `commitId`;目标节点、Dockerfile、Compose、Kubernetes manifest、健康检查和代理路径继续来自 `config.json` 与现有 manifest。主 server 直管微服务和内部 sidecar,例如 `code-queue-mgr`,也必须支持这一路径:`deploy apply --service code-queue-mgr` 从 `deploy.json` 指定 commit 导出源码、构建镜像、替换固定 Compose service 并验证运行中镜像/健康信息的 commit,但 prod live apply 仍需 supervisor 确认。部署默认遵循 target-side build:服务部署到哪台 target,就在哪台 target 从 remote commit 导出源码、一次性代理构建镜像并部署;不得把中心构建镜像作为默认分发路径,也不得用 `docker commit` 或脏 worktree 作为部署输入。production backend-core 是明确例外;`frontend` 是用户服务 UI / 前端镜像化样板,`baidu-netdisk` 是主 server 直管微服务的镜像化样板:D601 CI 构建并推送 commit-pinned 镜像到 D601 artifact registry,dev/prod CD 只拉取、retag 或导入、recreate/rollout 和验证,不在 master server 或 dev target 执行 frontend Compose build。完整规则见 `docs/reference/deploy.md`,D601 dev/Rust 边界见 `docs/reference/dev-environment.md`,artifact registry 见 `docs/reference/artifact-registry.md`。 ## Main Server Swap diff --git a/docs/reference/microservices.md b/docs/reference/microservices.md index 927d0bad..1927694d 100644 --- a/docs/reference/microservices.md +++ b/docs/reference/microservices.md @@ -57,7 +57,7 @@ UniDesk 用户服务是挂载到 UniDesk 核心服务上的、面向用户使用 - 代理路径:只允许 `/api/` 前缀;允许方法为 `GET`、`HEAD`、`POST`、`DELETE`,用于保持 Todo Note 原有清单创建/删除、任务增删改、提醒、展开/收起、移动、撤销/重做等功能。 - UniDesk 前端:`用户服务 / Todo Note` React 页面负责展示清单列表、树形任务、筛选、提醒、拖放/上移下移、撤销/重做、字号控制和显式原始 JSON 按钮。 -Todo Note 在 UniDesk 语境中按纯后端服务管理:不得继续公开 Todo Note 自身 Vite/Web 前端,也不得把 `4211` 映射为公网端口。浏览器只能通过 UniDesk frontend 的 `/api/microservices/todo-note/...` 同源代理访问 Todo Note 后端;当前 live prod artifact CD 仍被阻塞,直到 checked-in health contract 能证明 `deploy.commit` 和 `deploy.requestedCommit`。 +Todo Note 在 UniDesk 语境中按纯后端服务管理:不得继续公开 Todo Note 自身 Vite/Web 前端,也不得把 `4211` 映射为公网端口。浏览器只能通过 UniDesk frontend 的 `/api/microservices/todo-note/...` 同源代理访问 Todo Note 后端。标准 artifact consumer 路径为 `bun scripts/cli.ts deploy apply --env dev|prod --service todo-note`;由于 Todo Note 源码仍在外部 Gitee 仓库,D601 registry 中必须先已有 `127.0.0.1:5000/unidesk/todo-note:`。Compose 在 recreate 时注入 `UNIDESK_TODO_NOTE_DEPLOY_*`,artifact consumer 的健康探针读取 `/api/health` 并合成 `deploy.commit` 和 `deploy.requestedCommit` 供强校验。 Todo Note 首次迁移或源 JSON 修复时,在主 server 通过 Docker 内网执行 `/root/todo_note/scripts/migrate-json-to-pg.ts`,并显式指向主 PostgreSQL:`docker run --rm --network unidesk_default -v /root/todo_note:/app -w /app -e DATABASE_URL='postgres://unidesk:unidesk_dev_password@database:5432/unidesk' oven/bun:1-alpine bun scripts/migrate-json-to-pg.ts`。迁移脚本必须输出 `importedInstances: 5`、`totalTodos: 100`、`completedTodos: 54` 这一类可审计摘要,不能只依赖前端页面观察。 diff --git a/docs/reference/user-service-delivery.md b/docs/reference/user-service-delivery.md index 3ad7fa1d..6c62c143 100644 --- a/docs/reference/user-service-delivery.md +++ b/docs/reference/user-service-delivery.md @@ -15,7 +15,7 @@ This policy does not apply to: - `release/v1` governance; - one-off infrastructure repair actions. -`todo-note` is a special-case main-server service: it can participate in deploy validation, but live prod artifact CD stays blocked until the checked-in health contract proves `deploy.commit` and `deploy.requestedCommit`. +`todo-note` is a special-case main-server service because its source repository remains external. Its master-server Compose artifact consumer still follows the runtime contract: `UNIDESK_TODO_NOTE_DEPLOY_*` is injected at recreate time, and the consumer health probe combines the service `/api/health` response with that runtime metadata before checking `deploy.commit` and `deploy.requestedCommit`. ## Default Release Flow @@ -112,10 +112,12 @@ OA Event Flow follows the same master-server Compose artifact flow as Project Ma ## Todo Note -Todo Note is the current blocker case. +Todo Note is an external-source main-server Compose service that follows the standard commit-pinned artifact consumer flow. - The expected source reference remains `https://gitee.com/Lyon1998/todo_note`. -- Validation may use `bun scripts/cli.ts deploy apply --env dev --service todo-note --dry-run` or the equivalent prod dry-run, but live artifact CD is blocked until the checked-in runtime contract proves `deploy.commit` and `deploy.requestedCommit`. +- The D601 registry artifact must already exist as `127.0.0.1:5000/unidesk/todo-note:`; the UniDesk `ci publish-user-service` allow-list does not yet build this external-source artifact. +- Dev CD consumes the same artifact with `bun scripts/cli.ts deploy apply --env dev --service todo-note`; prod CD consumes it with `bun scripts/cli.ts deploy apply --env prod --service todo-note`. +- The Compose runtime injects `UNIDESK_TODO_NOTE_DEPLOY_REF`, `UNIDESK_TODO_NOTE_DEPLOY_SERVICE_ID`, `UNIDESK_TODO_NOTE_DEPLOY_REPO`, `UNIDESK_TODO_NOTE_DEPLOY_COMMIT`, and `UNIDESK_TODO_NOTE_DEPLOY_REQUESTED_COMMIT`; the consumer health probe must return matching `deploy.commit` and `deploy.requestedCommit`. - `server rebuild todo-note` remains a maintenance/local rebuild path only. It is not the standard versioned release truth for Todo Note. ## Decision Center diff --git a/scripts/src/artifact-registry.ts b/scripts/src/artifact-registry.ts index d79e091b..e9f717fb 100644 --- a/scripts/src/artifact-registry.ts +++ b/scripts/src/artifact-registry.ts @@ -27,6 +27,7 @@ interface ArtifactRegistryOptions { targetImage: string | null; serviceId: string | null; sourceRepo: string; + sourceRepoExplicit: boolean; deployRef: string | null; } @@ -67,6 +68,7 @@ const defaultOptions: ArtifactRegistryOptions = { targetImage: null, serviceId: null, sourceRepo: "https://github.com/pikasTech/unidesk", + sourceRepoExplicit: false, deployRef: null, }; const supportedArtifactConsumerServices = ["backend-core", "baidu-netdisk", "code-queue-mgr", "decision-center", "frontend", "oa-event-flow", "project-manager", "todo-note"] as const; @@ -78,6 +80,7 @@ interface ArtifactConsumerSpec { environment?: ArtifactDeployEnvironment; kind: "compose" | "d601-k3s"; registryRepository: string; + sourceRepo?: string; dockerfile: string; targets: Partial>; prodLiveApply: "enabled" | "supervisor-only" | "unsupported"; @@ -110,6 +113,10 @@ interface ArtifactConsumerTarget { }; } +function todoNoteHealthProbeCommand(): string { + return "bun -e \"fetch('http://127.0.0.1:4211/api/health').then(async r=>{const text=await r.text(); let body; try{body=JSON.parse(text)}catch{body={ok:r.ok,raw:text}}; const deploy=body.deploy&&typeof body.deploy==='object'&&!Array.isArray(body.deploy)?body.deploy:{}; body.deploy={...deploy,serviceId:deploy.serviceId||process.env.UNIDESK_DEPLOY_SERVICE_ID||'todo-note',ref:deploy.ref||process.env.UNIDESK_DEPLOY_REF||'',repo:deploy.repo||process.env.UNIDESK_DEPLOY_REPO||'',commit:deploy.commit||process.env.UNIDESK_DEPLOY_COMMIT||'',requestedCommit:deploy.requestedCommit||process.env.UNIDESK_DEPLOY_REQUESTED_COMMIT||''}; console.log(JSON.stringify(body)); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\""; +} + const artifactConsumerSpecs: Record = { "backend-core": { serviceId: "backend-core", @@ -336,11 +343,9 @@ const artifactConsumerSpecs: Record = { environment: "prod", kind: "compose", registryRepository: "unidesk/todo-note", + sourceRepo: "https://gitee.com/Lyon1998/todo_note", dockerfile: "Dockerfile", - prodLiveApply: "unsupported", - prodLiveBlockReason: "todo-note source is external to this repository and the current checked-in contract cannot prove /api/health deploy.commit/deploy.requestedCommit support.", - runtimeVerification: "blocked", - runtimeVerificationBlockReason: "todo-note source is external to this repository and the current checked-in contract cannot prove /api/health deploy.commit/deploy.requestedCommit support.", + prodLiveApply: "enabled", targets: { dev: { targetImage: "todo-note", @@ -350,7 +355,7 @@ const artifactConsumerSpecs: Record = { serviceName: "todo-note", containerName: "todo-note-backend", deployEnvPrefix: "UNIDESK_TODO_NOTE_DEPLOY", - healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4211/api/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"", + healthProbeCommand: todoNoteHealthProbeCommand(), requireHealthCommit: true, }, }, @@ -362,7 +367,7 @@ const artifactConsumerSpecs: Record = { serviceName: "todo-note", containerName: "todo-note-backend", deployEnvPrefix: "UNIDESK_TODO_NOTE_DEPLOY", - healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4211/api/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"", + healthProbeCommand: todoNoteHealthProbeCommand(), requireHealthCommit: true, }, }, @@ -474,6 +479,7 @@ function parseOptions(args: string[]): ArtifactRegistryOptions { index += 1; } else if (arg === "--source-repo") { options.sourceRepo = requireValue(args, index, arg); + options.sourceRepoExplicit = true; index += 1; } else if (arg === "--deploy-ref") { options.deployRef = requireValue(args, index, arg); @@ -866,6 +872,10 @@ function artifactImageRef(options: ArtifactRegistryOptions, spec: ArtifactConsum return `127.0.0.1:${options.port}/${spec.registryRepository}:${commit}`; } +function sourceRepoFor(options: ArtifactRegistryOptions, spec: ArtifactConsumerSpec): string { + return options.sourceRepoExplicit ? options.sourceRepo : spec.sourceRepo ?? options.sourceRepo; +} + function deployRefFor(options: ArtifactRegistryOptions, spec: ArtifactConsumerSpec): string { const target = artifactConsumerTarget(spec, options.environment); return options.deployRef ?? target?.deployRef ?? `deploy.json#environments.${options.environment ?? "prod"}.services.${spec.serviceId}`; @@ -1166,7 +1176,7 @@ function composeArtifactEnvValues(spec: ArtifactConsumerSpec, target: ArtifactCo return { [`${prefix}_SERVICE_ID`]: spec.serviceId, [`${prefix}_REF`]: deployRefFor(options, spec), - [`${prefix}_REPO`]: options.sourceRepo, + [`${prefix}_REPO`]: sourceRepoFor(options, spec), [`${prefix}_COMMIT`]: commit, [`${prefix}_REQUESTED_COMMIT`]: commit, }; @@ -1354,7 +1364,7 @@ function dryRunArtifactConsumerPlan(options: ArtifactRegistryOptions, spec: Arti providerId: options.providerId, serviceId: spec.serviceId, commit, - sourceRepo: options.sourceRepo, + sourceRepo: sourceRepoFor(options, spec), deployRef: deployRefFor(options, spec), sourceImage, requiredLabels: { @@ -1393,7 +1403,7 @@ function dryRunArtifactConsumerPlan(options: ArtifactRegistryOptions, spec: Arti verificationBlocked ? `blocked: ${spec.runtimeVerificationBlockReason}` : target.compose.requireHealthCommit - ? `${spec.serviceId} /health succeeds and reports deploy.commit matching the artifact commit` + ? `${spec.serviceId} runtime health probe succeeds and reports deploy.commit/deploy.requestedCommit matching the artifact commit` : `${spec.serviceId} /health succeeds for the recreated container`, ], rollback: rollbackInfo(spec, target, environment, commit), @@ -1450,12 +1460,13 @@ function d601K3sArtifactDeployScript(options: ArtifactRegistryOptions, spec: Art const manifestText = readFileSync(rootPath(target.k3s.manifestRepoPath), "utf8"); const manifestBase64 = Buffer.from(manifestText, "utf8").toString("base64"); const sourceImage = artifactImageRef(options, spec, commit); + const sourceRepo = sourceRepoFor(options, spec); const commitImage = target.targetCommitImage(commit); const k3s = target.k3s; const labels = [ `unidesk.ai/deploy-service-id=${spec.serviceId}`, `unidesk.ai/deploy-ref=${deployRefFor(options, spec)}`, - `unidesk.ai/deploy-repo=${options.sourceRepo}`, + `unidesk.ai/deploy-repo=${sourceRepo}`, `unidesk.ai/deploy-commit=${commit}`, `unidesk.ai/deploy-requested-commit=${commit}`, `unidesk.ai/image-source=${sourceImage}`, @@ -1469,7 +1480,7 @@ function d601K3sArtifactDeployScript(options: ArtifactRegistryOptions, spec: Art `commit_image=${shellQuote(commitImage)}`, `environment=${shellQuote(environment)}`, `service_id=${shellQuote(spec.serviceId)}`, - `source_repo=${shellQuote(options.sourceRepo)}`, + `source_repo=${shellQuote(sourceRepo)}`, `deploy_ref=${shellQuote(deployRefFor(options, spec))}`, `commit=${shellQuote(commit)}`, `dockerfile=${shellQuote(spec.dockerfile)}`, @@ -1628,7 +1639,7 @@ async function deployD601K3sArtifactNow(options: ArtifactRegistryOptions, spec: environment, commit, providerId: options.providerId, - sourceRepo: options.sourceRepo, + sourceRepo: sourceRepoFor(options, spec), deployRef: deployRefFor(options, spec), sourceImage, stableImage: target.targetImage, @@ -1711,7 +1722,8 @@ function localHelp(): Record { "bun scripts/cli.ts artifact-registry deploy-service --env prod --service project-manager --commit [--dry-run] [--run-now] [--provider-id D601]", "bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit [--dry-run] [--run-now] [--provider-id D601]", "bun scripts/cli.ts artifact-registry deploy-service --env prod --service code-queue-mgr --commit --dry-run [--provider-id D601]", - "bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit --dry-run [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit [--dry-run] [--run-now] [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env dev --service todo-note --commit [--dry-run] [--run-now] [--provider-id D601]", ], firstStage: "install now writes the rendered systemd/Compose/config files and starts the registry", artifactConsumers: { @@ -1726,6 +1738,7 @@ function localHelp(): Record { "bun scripts/cli.ts deploy apply --env prod --service project-manager", "bun scripts/cli.ts deploy apply --env prod --service oa-event-flow", "bun scripts/cli.ts deploy apply --env prod --service code-queue-mgr --dry-run", + "bun scripts/cli.ts deploy apply --env prod --service todo-note", ], devCommands: [ "bun scripts/cli.ts deploy apply --env dev --service frontend", @@ -1733,7 +1746,7 @@ function localHelp(): Record { "bun scripts/cli.ts deploy apply --env dev --service project-manager --dry-run", "bun scripts/cli.ts deploy apply --env dev --service oa-event-flow --dry-run", "bun scripts/cli.ts deploy apply --env dev --service code-queue-mgr --dry-run", - "bun scripts/cli.ts deploy apply --env dev --service todo-note --dry-run", + "bun scripts/cli.ts deploy apply --env dev --service todo-note", ], rollbackShape: "rerun the same artifact consumer with a previous commit-pinned image", }, diff --git a/scripts/src/deploy.ts b/scripts/src/deploy.ts index 237357a3..027de7bb 100644 --- a/scripts/src/deploy.ts +++ b/scripts/src/deploy.ts @@ -142,7 +142,6 @@ const prodArtifactConsumerServiceIds = new Set(["backend-core", "baidu-n const prodForbiddenTargetSideBuildServiceIds = new Set(["backend-core", "baidu-netdisk", "decision-center", "frontend"]); const prodArtifactLiveApplyBlockedServiceIds = new Map([ ["code-queue-mgr", "code-queue-mgr is the main-server Code Queue control-plane sidecar; live production apply requires explicit supervisor confirmation."], - ["todo-note", "todo-note source is external to this repository and the current checked-in contract cannot prove /api/health deploy.commit/deploy.requestedCommit support."], ]); const deployEnvironmentTargets: Record = { dev: { @@ -206,7 +205,7 @@ export function deployHelp(action: string | undefined = undefined): Record", default: defaultDeployFile, description: "Desired-state manifest path relative to the repo root. JSON and ESM JS manifests are supported, for example deploy.json or develop.js. Local manifest apply allows k3sctl-adapter and explicit production code-queue controlled rollout on D601." }, - { name: "--env ", description: "Read the named environment from origin/master:deploy.json. Dev apply supports backend-core target-side rollout plus reviewed artifact consumers for frontend, baidu-netdisk, decision-center, project-manager, oa-event-flow, code-queue-mgr validation, while todo-note remains dry-run only. Prod apply uses the D601 registry artifact consumer for reviewed services; code-queue-mgr live apply is supervisor-gated and todo-note remains blocked." }, + { name: "--env ", description: "Read the named environment from origin/master:deploy.json. Dev apply supports backend-core target-side rollout plus reviewed artifact consumers for frontend, baidu-netdisk, decision-center, project-manager, oa-event-flow, code-queue-mgr, and todo-note. Prod apply uses the D601 registry artifact consumer for reviewed services; code-queue-mgr live apply is supervisor-gated." }, { name: "--service ", description: "Limit reconcile to one service from the manifest." }, { name: "--commit ", description: "Prod artifact rollback/apply override for a selected service; the image must already exist in D601 registry." }, { name: "--dry-run", description: "Prepare and validate without mutating the target service." }, @@ -2886,7 +2885,7 @@ export async function runDeployCommand(config: UniDeskConfig | null, args: strin } const unsupported = unsupportedDevApplyServices(manifest, options.serviceId); if (unsupported.length > 0) { - throw new Error(`deploy apply --env dev currently supports backend-core target-side rollout plus frontend/baidu-netdisk/decision-center/project-manager/oa-event-flow/code-queue-mgr artifact consumers; unsupported selected services: ${unsupported.join(", ")}. todo-note is dry-run only until runtime verification is proven. Use ci run-dev-e2e for smoke verification.`); + throw new Error(`deploy apply --env dev currently supports backend-core target-side rollout plus frontend/baidu-netdisk/decision-center/project-manager/oa-event-flow/code-queue-mgr/todo-note artifact consumers; unsupported selected services: ${unsupported.join(", ")}. Use ci run-dev-e2e for smoke verification.`); } const devArtifactServices = selectedDevArtifactServicesWithProdFallback(manifest, options.serviceId); const devTargetServices = selectedDevTargetServices(manifest, options.serviceId); diff --git a/scripts/src/help.ts b/scripts/src/help.ts index a04a631b..ba54e6e1 100644 --- a/scripts/src/help.ts +++ b/scripts/src/help.ts @@ -36,7 +36,7 @@ export function rootHelp(): unknown { { command: "decision list [--type ...] [--status ...] [--level ...] [--linked-goal-id id] [--limit N]", description: "List Decision Center records through the user-service proxy." }, { command: "decision requirement list|upsert [--id id] [--title text] [--body-file path] [--type goal|decision|blocker|debt|experiment]", description: "Manage requirement records over the existing records model, excluding meeting records." }, { command: "decision show ", 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 a repo+commit manifest; --env reads origin/master:deploy.json environments and can apply supported dev target-side builds plus decision-center's dev artifact consumer, or supported prod artifact consumers." }, + { command: "deploy check|plan|apply [--file deploy.json|--env dev|prod] [--service id] [--commit full-sha] [--dry-run] [--force]", description: "Reconcile services from a repo+commit manifest; --env reads origin/master:deploy.json environments and applies supported dev target-side rollouts or reviewed D601 registry artifact consumers." }, { 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; deploy-backend-core is a deprecated compatibility name." }, { command: "schedule list|get|runs|run|delete", description: "Manage backend-core scheduled tasks and run history; schedule run supports --wait-ms N." }, @@ -263,7 +263,12 @@ function artifactRegistryHelp(): unknown { "bun scripts/cli.ts artifact-registry deploy-service --service baidu-netdisk --commit [--dry-run] [--run-now] [--provider-id D601]", "bun scripts/cli.ts artifact-registry deploy-service --service frontend --env prod --commit [--dry-run] [--run-now] [--provider-id D601]", "bun scripts/cli.ts artifact-registry deploy-service --service frontend --env dev --commit [--dry-run] [--run-now] [--provider-id D601]", - "bun scripts/cli.ts artifact-registry deploy-service --service decision-center --commit [--dry-run] [--run-now] [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env dev --service decision-center --commit [--dry-run] [--run-now] [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env prod --service decision-center --commit [--dry-run] [--run-now] [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env prod --service project-manager --commit [--dry-run] [--run-now] [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit [--dry-run] [--run-now] [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env prod --service code-queue-mgr --commit --dry-run [--provider-id D601]", + "bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit [--dry-run] [--run-now] [--provider-id D601]", ], description: "Manage the declaration, rendered files and readonly checks for the D601 host-managed CNCF Distribution artifact registry.", boundary: [ @@ -271,7 +276,7 @@ function artifactRegistryHelp(): unknown { "service is host-managed by systemd + Docker Compose, not k3s-managed", "install writes the rendered host unit/config and starts the registry", "deploy-backend-core only pulls commit-pinned backend-core artifacts and does not build backend-core on the master server", - "deploy-service currently supports backend-core, baidu-netdisk, prod/dev frontend, decision-center, project-manager, oa-event-flow, and code-queue-mgr as standardized consumers; todo-note is runtime-verification blocked", + "deploy-service currently supports backend-core, baidu-netdisk, prod/dev frontend, decision-center, project-manager, oa-event-flow, code-queue-mgr, and todo-note as standardized consumers; code-queue-mgr prod live apply remains supervisor-gated", "status and health use provider-gateway Host SSH readonly checks", ], legacyEntrypoints: {