Files
pikasTech-unidesk/docs/reference/cicd-standardization.md
T
2026-05-20 01:31:03 +00:00

14 KiB

CI/CD Standardization

This document defines the stable split between CI artifact producers, artifact catalog data, legacy guardrails and CD consumers. Detailed Tekton rules remain in docs/reference/ci.md; registry runtime and consumers remain in docs/reference/artifact-registry.md; user-service delivery order remains in docs/reference/user-service-delivery.md.

Target Shape

The standard release shape is:

  1. CI builds or locks the artifact from a pushed commit or verified upstream digest.
  2. The artifact is published to the D601 artifact registry or a controlled mirror.
  3. Dev validation consumes that same artifact.
  4. Production CD is pull-only and verifies live commit or upstream digest.
  5. Runtime metadata can be traced back to a live Git commit or upstream image digest.

backend-core and D601 code-queue may be validated only in dev in this phase. This document must not be used to introduce production deploy validation for either service.

Artifact Catalog

Root CI.json is the CI producer catalog. It is not a deployment manifest.

Allowed catalog data:

  • stable serviceId;
  • artifact kind: source-build or upstream-image;
  • producer command: ci publish-backend-core or ci publish-user-service;
  • source repository URL, optional repo root and repo-relative Dockerfile path;
  • image repository naming and commit tag policy;
  • upstream image digest, upstream source revision and D601 mirror intent for image-only services;
  • the required success summary contract.

Forbidden catalog data:

  • provider IDs;
  • runtime namespace, Compose service, Kubernetes Service or health path;
  • ports, environment variables, replicas or volumes;
  • desired deployment commits or rollout targets.

Runtime topology belongs to config.json, deploy.json, existing Kubernetes manifests and the artifact-registry executor.

Producer Contract

bun scripts/cli.ts ci publish-user-service --service <id> --commit <full-sha> reads source.repo, source.dockerfile and image repository naming from CI.json. It rejects command-line repo overrides. Successful source-build producers must label the image with:

  • unidesk.ai/service-id;
  • unidesk.ai/source-commit;
  • unidesk.ai/source-repo;
  • unidesk.ai/dockerfile.

The successful artifactSummary must contain serviceId, sourceCommit, sourceRepo, dockerfile, imageRef, tag, digest and digestRef.

blocked catalog entries must return a structured blocked result. They must not silently skip, build from a dirty worktree, fall back to target-side maintenance deployment, or mutate production.

Current Coverage

Supported source-build artifact producers:

  • backend-core through ci publish-backend-core;
  • frontend, baidu-netdisk, decision-center, project-manager, oa-event-flow, todo-note, code-queue-mgr, findjob, pipeline, met-nonlinear, k3sctl-adapter, mdtodo, claudeqq through ci publish-user-service.

Cataloged but blocked:

  • code-queue: source input is known, but this phase allows only dev image validation and not prod-oriented artifact publication.
  • filebrowser and filebrowser-d601: upstream image-only services pinned to docker.io/filebrowser/filebrowser@sha256:289c5dd677c56662440f26eeb44266ed9746fe563d2e9100f546bff558534d70; they need a future upstream mirror producer before CI can publish them.

code-queue-mgr is a supported CI producer because the source-build input is known and the remote consumer commit already added a reviewed artifact consumer shape. Its production live apply remains supervisor-gated by deploy/artifact-registry and is not authorized by CI.json.

Upstream Image Consumers

filebrowser and filebrowser-d601 are upstream-image consumers, not source-built UniDesk services.

Service Upstream image Source revision Catalog home CI Dockerfile build Digest / mirror strategy CD validation
filebrowser docker.io/filebrowser/filebrowser:v2.63.3 ca5e249e3c0c94159c2136a0cd431a424eb18472 CI.json.artifacts[] with kind=upstream-image plus config.json.microservices[].repository.artifactSource forbidden resolve tag to docker.io/filebrowser/filebrowser@sha256:<manifest-digest>, then optionally mirror to 127.0.0.1:5000/upstream/filebrowser/filebrowser@sha256:<manifest-digest> pull by digest or mirror digest, verify OCI labels, container image id/digest, and private proxy health
filebrowser-d601 docker.io/filebrowser/filebrowser:v2.63.3 ca5e249e3c0c94159c2136a0cd431a424eb18472 CI.json.artifacts[] with kind=upstream-image plus config.json.microservices[].repository.artifactSource forbidden same as filebrowser same as filebrowser

The catalog records the resolved upstream digest for the current image. If a future tag refresh cannot resolve the registry manifest digest, rollout must remain blocked until a reachable registry path resolves the manifest digest and records the mirror digest. A local Docker image id is supporting evidence only and not a registry digest pin.

Upstream Image Evidence

The catalog expression is intentionally minimal and parseable:

Evidence command Required result shape
`jq '.artifacts[] select(.kind=="upstream-image")
bun scripts/cli.ts config show with the File Browser artifactSource projection both services parse as kind=upstream-image, digestPinRequired=true, mirrorRepository=127.0.0.1:5000/upstream/filebrowser/filebrowser, ciDockerfileBuild=false, and pullOnlyCd=true
docker manifest inspect --verbose docker.io/filebrowser/filebrowser:v2.63.3 must resolve the upstream manifest digest before rollout; if the registry request times out, rollout remains blocked
bun scripts/cli.ts ci publish-user-service --service filebrowser --commit <full-sha> --dry-run returns ok=false with status=blocked, upstream digest/mirror metadata, and no Dockerfile source build

The digest/mirror dry-run contract is:

  1. Resolve docker.io/filebrowser/filebrowser:v2.63.3 to docker.io/filebrowser/filebrowser@sha256:<manifest-digest>.
  2. Mirror only that resolved digest to 127.0.0.1:5000/upstream/filebrowser/filebrowser@sha256:<manifest-digest>.
  3. Record the digest ref used by CD; do not promote a mutable tag as release truth.
  4. Refuse pull-only CD while the digest is unknown or the mirror digest differs from the upstream digest.

Pull-only CD validation must be expressed as concrete checks:

Check Form
Pull source docker pull docker.io/filebrowser/filebrowser@sha256:<manifest-digest> or docker pull 127.0.0.1:5000/upstream/filebrowser/filebrowser@sha256:<manifest-digest>
Runtime identity docker inspect reports the expected image id/digest and OCI labels org.opencontainers.image.version=2.63.3 and org.opencontainers.image.revision=ca5e249e3c0c94159c2136a0cd431a424eb18472
Service health UniDesk private proxy health succeeds for filebrowser and filebrowser-d601; direct public exposure remains forbidden
Build absence no docker build, docker compose up --build, CI Dockerfile producer, or source checkout is used for these services

Legacy Path Classification

Path Classification Current guardrail Cleanup condition
deploy apply --env prod for services without a reviewed artifact consumer Must stay disabled/degraded returns structured unsupported and refuses maintenance-channel fallback enable only after each service has a documented artifact producer, dev consumer, prod consumer and live verification
Local-manifest deploy apply for prod artifact consumers (backend-core, frontend, baidu-netdisk, decision-center) Must stay disabled/degraded as a standard prod path blocked before source build; operator is pointed to deploy apply --env prod remove only after all production deploys use env-ref artifact consumers and no recovery runbook depends on local manifests
artifact-registry deploy-backend-core Legacy compatibility entry returns structured deprecated result; replacement is deploy apply --env prod --service backend-core remove after callers and docs use only deploy apply --env prod
server rebuild frontend and server rebuild baidu-netdisk Maintenance / non-standard docs classify as maintenance-only; standard release requires CI artifact plus dev/prod artifact consumer keep until recovery runbooks have equivalent pull-only repair commands
server rebuild backend-core Diagnostic/recovery only; not Rust iteration or prod CD docs forbid Rust iteration and prod backend-core artifact CD through this command keep for bootstrap/recovery until backend-core artifact CD and rollback are proven under outage conditions
server rebuild dev-frontend-proxy, code-queue-mgr, project-manager, oa-event-flow, todo-note, provider-gateway on main-server Compose Bootstrap / recovery / diagnostic still serialized through Compose lock and post-up validation reassess service by service after artifact consumers exist
provider.upgrade mode=schedule for provider-gateway Must be retained protected upgrade path with validation; Host SSH self-rebuild remains forbidden do not delete; it is the provider-gateway recovery path
D601 direct docker build, kubectl apply, docker compose up --build used by deploy executor for allowed dev/backend bootstrap and native k3s setup Bootstrap / recovery / controlled dev limited to allowed target-side executor, native k3s initialization, and dev backend-core; Code Queue prod is not enabled convert only after artifact consumers or native bootstrap replacements exist
D601 direct Code Queue / old codex deploy Must stay disabled/degraded compatibility command throws; docs classify direct deployment as forbidden wait for controlled Code Queue dev/prod CD worker
File Browser docker run image-only path Needs later worker now cataloged as upstream-image consumer; no CI Dockerfile build allowed implement digest-resolved pull-only/mirror CD before treating it as standard deployment

Guardrails Added

  • Upstream-image services are represented in CI.json.artifacts[] with kind=upstream-image and in config.json.microservices[].repository.artifactSource; they are explicitly outside source-build producers.
  • ci publish-user-service returns a structured blocked result for registered upstream-image services instead of trying to interpret repository.dockerfile as a source Dockerfile.
  • Local-manifest production deploy for reviewed artifact consumers is blocked before source materialization/build, so prod cannot silently fall back to target-side source build or a dirty worktree.
  • artifact-registry deploy-backend-core is demoted to a structured deprecated result; backend-core production CD must enter through deploy apply --env prod.

Guardrail Evidence Matrix

Guardrail name / result key Command evidence Legacy path covered Deletion status
upstream-image CI publish rejection bun scripts/cli.ts ci publish-user-service --service filebrowser --commit <full-sha> --dry-run returns ok=false, status=blocked, and upstream metadata File Browser accidentally entering Dockerfile CI keep; deletion of docker-run repair waits for digest/mirror CD
prod-artifact-consumer-local-manifest-blocked bun scripts/cli.ts deploy apply --file deploy.json --service frontend --dry-run returns ok=false, this error key, and points to deploy apply --env prod --service <service-id> --commit <full-sha> prod source-build fallback for reviewed artifact consumers keep; local manifest mode may still be needed for non-prod/recovery until runbooks are replaced
artifact-registry deploy-backend-core deprecated result bun scripts/cli.ts artifact-registry deploy-backend-core --commit <full-sha> returns ok=false, deprecated=true, and replacement deploy apply --env prod --service backend-core --commit <full-sha> backend-core prod CD bypassing deploy reconciler guardrails keep name only as compatibility until all callers stop using it
prod unsupported result for services without artifact consumers deploy apply --env prod --service <unsupported-service> --dry-run must return unsupported instead of falling back to source build target-side source build/maintenance-channel prod deploy keep disabled until service-specific artifact consumers exist
backend-core/code-queue prod boundary docs and deploy support matrix allow backend-core and D601 Code Queue only in dev validation for this phase accidental prod validation entrypoints for backend-core or Code Queue do not add executable prod test/deploy validation in this precheck

The guarded-but-not-deletable paths are: server rebuild backend-core, server rebuild frontend, server rebuild baidu-netdisk, provider-gateway protected upgrade, native k3s bootstrap, k3sctl-adapter bridge repair, File Browser provider-local docker-run repair, and D601 dev/backend target-side rollout. They remain because they are bootstrap, recovery, diagnostic, or controlled dev paths; deleting them requires replacement runbooks or reviewed artifact consumers.

Safety Boundary

CI may build images, push to the D601 loopback registry and report immutable digests. CI must not run production CD, call deploy apply for production, mutate production namespaces, recreate production Compose services or update deploy.json.

backend-core and D601 code-queue remain restricted to dev image validation in this phase. Any future production rollout for them must be implemented as an explicit CD consumer change, not as a CI producer side effect.

Validation Boundary

This precheck uses lightweight parsing and dry-run evidence only. It intentionally does not run full check, e2e, Playwright, or other broad browser/runtime test suites on the master server because those are outside the precheck scope and may exceed master-server resource limits. backend-core and D601 code-queue production validation are also out of scope; backend-core dev rollout can be attempted only through the existing D601 dev path, and a provider-offline result is an infrastructure blocker rather than permission to validate production.