feat: extend k3s artifact consumers
This commit is contained in:
@@ -74,11 +74,14 @@ const defaultOptions: ArtifactRegistryOptions = {
|
||||
const supportedArtifactConsumerServices = [
|
||||
"backend-core",
|
||||
"baidu-netdisk",
|
||||
"claudeqq",
|
||||
"code-queue",
|
||||
"code-queue-mgr",
|
||||
"decision-center",
|
||||
"findjob",
|
||||
"frontend",
|
||||
"k3sctl-adapter",
|
||||
"mdtodo",
|
||||
"met-nonlinear",
|
||||
"oa-event-flow",
|
||||
"pipeline",
|
||||
@@ -124,6 +127,7 @@ interface ArtifactConsumerTarget {
|
||||
servicePort: number;
|
||||
containerName: string;
|
||||
healthPath: string;
|
||||
extraDeployments?: Array<string | { name: string; containerName?: string }>;
|
||||
applySelector?: string;
|
||||
podLabelSelector?: string;
|
||||
};
|
||||
@@ -264,6 +268,116 @@ const artifactConsumerSpecs: Record<string, ArtifactConsumerSpec> = {
|
||||
},
|
||||
},
|
||||
},
|
||||
"mdtodo": {
|
||||
serviceId: "mdtodo",
|
||||
environment: "prod",
|
||||
kind: "d601-k3s",
|
||||
registryRepository: "unidesk/mdtodo",
|
||||
dockerfile: "src/components/microservices/mdtodo/Dockerfile",
|
||||
prodLiveApply: "enabled",
|
||||
targets: {
|
||||
dev: {
|
||||
targetImage: "unidesk-mdtodo:dev",
|
||||
targetCommitImage: (commit: string) => `unidesk-mdtodo:${commit}`,
|
||||
deployRef: "deploy.json#environments.dev.services.mdtodo",
|
||||
k3s: {
|
||||
namespace: "unidesk-dev",
|
||||
manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-mdtodo.k8s.yaml",
|
||||
deploymentName: "mdtodo-dev",
|
||||
serviceName: "mdtodo-dev",
|
||||
servicePort: 4267,
|
||||
containerName: "mdtodo",
|
||||
healthPath: "/health",
|
||||
podLabelSelector: "app.kubernetes.io/name=mdtodo,unidesk.ai/environment=dev",
|
||||
},
|
||||
},
|
||||
prod: {
|
||||
targetImage: "unidesk-mdtodo:d601",
|
||||
targetCommitImage: (commit: string) => `unidesk-mdtodo:${commit}`,
|
||||
deployRef: "deploy.json#environments.prod.services.mdtodo",
|
||||
k3s: {
|
||||
namespace: "unidesk",
|
||||
manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/mdtodo.k8s.yaml",
|
||||
deploymentName: "mdtodo",
|
||||
serviceName: "mdtodo",
|
||||
servicePort: 4267,
|
||||
containerName: "mdtodo",
|
||||
healthPath: "/health",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"claudeqq": {
|
||||
serviceId: "claudeqq",
|
||||
environment: "prod",
|
||||
kind: "d601-k3s",
|
||||
registryRepository: "unidesk/claudeqq",
|
||||
dockerfile: "claudeqq/Dockerfile",
|
||||
sourceRepo: "https://gitee.com/lyon1998/agent_skills",
|
||||
prodLiveApply: "enabled",
|
||||
targets: {
|
||||
dev: {
|
||||
targetImage: "unidesk-claudeqq:dev",
|
||||
targetCommitImage: (commit: string) => `unidesk-claudeqq:${commit}`,
|
||||
deployRef: "deploy.json#environments.dev.services.claudeqq",
|
||||
k3s: {
|
||||
namespace: "unidesk-dev",
|
||||
manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-claudeqq.k8s.yaml",
|
||||
deploymentName: "claudeqq-dev",
|
||||
serviceName: "claudeqq-dev",
|
||||
servicePort: 3290,
|
||||
containerName: "claudeqq",
|
||||
healthPath: "/health",
|
||||
podLabelSelector: "app.kubernetes.io/name=claudeqq,unidesk.ai/environment=dev",
|
||||
},
|
||||
},
|
||||
prod: {
|
||||
targetImage: "unidesk-claudeqq:d601",
|
||||
targetCommitImage: (commit: string) => `unidesk-claudeqq:${commit}`,
|
||||
deployRef: "deploy.json#environments.prod.services.claudeqq",
|
||||
k3s: {
|
||||
namespace: "unidesk",
|
||||
manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/claudeqq.k8s.yaml",
|
||||
deploymentName: "claudeqq",
|
||||
serviceName: "claudeqq",
|
||||
servicePort: 3290,
|
||||
containerName: "claudeqq",
|
||||
healthPath: "/health",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"code-queue": {
|
||||
serviceId: "code-queue",
|
||||
environment: "dev",
|
||||
kind: "d601-k3s",
|
||||
registryRepository: "unidesk/code-queue",
|
||||
dockerfile: "src/components/microservices/code-queue/Dockerfile",
|
||||
prodLiveApply: "unsupported",
|
||||
prodLiveBlockReason: "code-queue is dev-only for artifact consumer validation and has no prod artifact deploy, rollout, or manifest mutation target.",
|
||||
targets: {
|
||||
dev: {
|
||||
targetImage: "unidesk-code-queue:dev",
|
||||
targetCommitImage: (commit: string) => `unidesk-code-queue:${commit}`,
|
||||
deployRef: "deploy.json#environments.dev.services.code-queue",
|
||||
k3s: {
|
||||
namespace: "unidesk-dev",
|
||||
manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-code-queue.k8s.yaml",
|
||||
deploymentName: "code-queue-scheduler-dev",
|
||||
extraDeployments: [
|
||||
{ name: "d601-dev-provider-egress-proxy", containerName: "provider-egress-proxy" },
|
||||
"code-queue-read-dev",
|
||||
"code-queue-write-dev",
|
||||
],
|
||||
serviceName: "code-queue-scheduler-dev",
|
||||
servicePort: 4222,
|
||||
containerName: "code-queue",
|
||||
healthPath: "/health",
|
||||
podLabelSelector: "app.kubernetes.io/name=code-queue,app.kubernetes.io/component=scheduler,unidesk.ai/environment=dev",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"frontend": {
|
||||
serviceId: "frontend",
|
||||
environment: "prod",
|
||||
@@ -809,6 +923,7 @@ function plan(options: ArtifactRegistryOptions): Record<string, unknown> {
|
||||
"CI builds and publishes backend-core, frontend, and reviewed user-service artifacts on D601",
|
||||
"CD only pulls, retags, recreates/imports artifacts, and verifies live commit",
|
||||
"master server CD must not compile Rust or run docker compose build for artifact consumers",
|
||||
"code-queue is dev-only for artifact consumer validation and has no prod artifact deploy target",
|
||||
],
|
||||
renderedPaths: bundle.paths,
|
||||
artifactConsumerFlow: [
|
||||
@@ -939,7 +1054,7 @@ function artifactConsumerSpec(serviceId: string, environment: ArtifactDeployEnvi
|
||||
const explicit = artifactConsumerSpecs[key];
|
||||
if (explicit !== undefined) return explicit;
|
||||
const shared = artifactConsumerSpecs[serviceId];
|
||||
return environment !== null && shared?.targets[environment] !== undefined ? shared : null;
|
||||
return shared ?? null;
|
||||
}
|
||||
|
||||
function supportedArtifactConsumers(): Array<{ environment: ArtifactDeployEnvironment; serviceId: SupportedArtifactConsumerService; kind: ArtifactConsumerSpec["kind"] }> {
|
||||
@@ -1682,7 +1797,16 @@ function legacyDeployBackendCoreResult(options: ArtifactRegistryOptions): Record
|
||||
function dryRunArtifactConsumerPlan(options: ArtifactRegistryOptions, spec: ArtifactConsumerSpec, target: ArtifactConsumerTarget, commit: string): Record<string, unknown> {
|
||||
const environment = options.environment ?? "prod";
|
||||
const verificationBlocked = spec.runtimeVerification === "blocked";
|
||||
const livePolicy = environment === "prod" ? spec.prodLiveApply : "enabled";
|
||||
const sourceImage = artifactImageRef(options, spec, commit);
|
||||
const k3sDeployments = target.k3s === undefined
|
||||
? []
|
||||
: [
|
||||
{ name: target.k3s.deploymentName, containerName: target.k3s.containerName },
|
||||
...(target.k3s.extraDeployments ?? []).map((deployment) => typeof deployment === "string"
|
||||
? { name: deployment, containerName: target.k3s!.containerName }
|
||||
: { name: deployment.name, containerName: deployment.containerName ?? target.k3s!.containerName }),
|
||||
];
|
||||
const common = {
|
||||
ok: !verificationBlocked,
|
||||
supported: !verificationBlocked,
|
||||
@@ -1707,9 +1831,9 @@ function dryRunArtifactConsumerPlan(options: ArtifactRegistryOptions, spec: Arti
|
||||
},
|
||||
boundary: `${environment} CD is artifact-consumer only: verify commit-pinned registry image, pull/import, deploy, then verify live commit/image/health; it never builds source on the runtime target`,
|
||||
liveApply: {
|
||||
policy: spec.prodLiveApply,
|
||||
policy: livePolicy,
|
||||
allowed: !verificationBlocked && (environment !== "prod" || spec.prodLiveApply === "enabled"),
|
||||
reason: spec.runtimeVerificationBlockReason ?? spec.prodLiveBlockReason ?? null,
|
||||
reason: spec.runtimeVerificationBlockReason ?? (environment === "prod" ? spec.prodLiveBlockReason ?? null : null),
|
||||
},
|
||||
};
|
||||
if (spec.kind === "compose" || spec.kind === "d601-compose") {
|
||||
@@ -1752,6 +1876,7 @@ function dryRunArtifactConsumerPlan(options: ArtifactRegistryOptions, spec: Arti
|
||||
kind: "d601-k3s",
|
||||
namespace: target.k3s?.namespace,
|
||||
deployment: target.k3s?.deploymentName,
|
||||
deployments: k3sDeployments,
|
||||
service: target.k3s?.serviceName,
|
||||
stableImage: target.targetImage,
|
||||
runtimeImage: target.targetCommitImage(commit),
|
||||
@@ -1803,6 +1928,13 @@ function d601K3sArtifactDeployScript(options: ArtifactRegistryOptions, spec: Art
|
||||
const sourceRepo = sourceRepoFor(options, spec);
|
||||
const commitImage = target.targetCommitImage(commit);
|
||||
const k3s = target.k3s;
|
||||
const deploymentSpecs = [
|
||||
{ name: k3s.deploymentName, containerName: k3s.containerName },
|
||||
...(k3s.extraDeployments ?? []).map((deployment) => typeof deployment === "string"
|
||||
? { name: deployment, containerName: k3s.containerName }
|
||||
: { name: deployment.name, containerName: deployment.containerName ?? k3s.containerName }),
|
||||
];
|
||||
const deploymentSpecsBase64 = Buffer.from(JSON.stringify(deploymentSpecs), "utf8").toString("base64");
|
||||
const labels = [
|
||||
`unidesk.ai/deploy-service-id=${spec.serviceId}`,
|
||||
`unidesk.ai/deploy-ref=${deployRefFor(options, spec)}`,
|
||||
@@ -1827,6 +1959,7 @@ function d601K3sArtifactDeployScript(options: ArtifactRegistryOptions, spec: Art
|
||||
`namespace=${shellQuote(k3s.namespace)}`,
|
||||
`deployment=${shellQuote(k3s.deploymentName)}`,
|
||||
`container_name=${shellQuote(k3s.containerName)}`,
|
||||
`deployment_specs_b64=${shellQuote(deploymentSpecsBase64)}`,
|
||||
`service_name=${shellQuote(k3s.serviceName)}`,
|
||||
`service_port=${shellQuote(String(k3s.servicePort))}`,
|
||||
`health_path=${shellQuote(k3s.healthPath)}`,
|
||||
@@ -1858,15 +1991,37 @@ function d601K3sArtifactDeployScript(options: ArtifactRegistryOptions, spec: Art
|
||||
"root_exec ctr --address /run/k3s/containerd/containerd.sock -n k8s.io images ls | grep -F \"$stable_image\" >/dev/null",
|
||||
"root_exec ctr --address /run/k3s/containerd/containerd.sock -n k8s.io images ls | grep -F \"$commit_image\" >/dev/null",
|
||||
"printf '%s' \"$manifest_b64\" | base64 -d > \"$manifest\"",
|
||||
"grep -F \"name: $deployment\" \"$manifest\" >/dev/null",
|
||||
"deployment_specs=$(mktemp /tmp/unidesk-artifact-k3s-deployments.XXXXXX.json)",
|
||||
"printf '%s' \"$deployment_specs_b64\" | base64 -d > \"$deployment_specs\"",
|
||||
"trap 'rm -f \"$archive\" \"$manifest\" \"$deployment_specs\" \"$health_tmp\"' EXIT",
|
||||
"python3 - \"$deployment_specs\" \"$manifest\" <<'PY'",
|
||||
"import json, sys",
|
||||
"specs = json.load(open(sys.argv[1], encoding='utf-8'))",
|
||||
"manifest = open(sys.argv[2], encoding='utf-8').read()",
|
||||
"missing = [item['name'] for item in specs if f\"name: {item['name']}\" not in manifest]",
|
||||
"if missing:",
|
||||
" raise SystemExit('manifest missing deployment(s): ' + ','.join(missing))",
|
||||
"PY",
|
||||
"if [ -n \"$apply_selector\" ]; then kubectl apply -f \"$manifest\" -l \"$apply_selector\"; else kubectl apply -f \"$manifest\"; fi",
|
||||
...(environment === "dev" && spec.serviceId === "frontend" ? [d601DevFrontendAuthPatchScript(readConfig())] : []),
|
||||
"previous_commit=$(kubectl -n \"$namespace\" get deployment \"$deployment\" -o jsonpath='{.metadata.annotations.unidesk\\.ai/deploy-commit}' 2>/dev/null || true)",
|
||||
"kubectl -n \"$namespace\" set image \"deployment/$deployment\" \"$container_name=$commit_image\"",
|
||||
"kubectl -n \"$namespace\" set env \"deployment/$deployment\" \"UNIDESK_DEPLOY_SERVICE_ID=$service_id\" \"UNIDESK_DEPLOY_REF=$deploy_ref\" \"UNIDESK_DEPLOY_REPO=$source_repo\" \"UNIDESK_DEPLOY_COMMIT=$commit\" \"UNIDESK_DEPLOY_REQUESTED_COMMIT=$commit\"",
|
||||
`kubectl -n "$namespace" annotate "deployment/$deployment" ${labels.map(shellQuote).join(" ")} --overwrite`,
|
||||
"if [ -n \"$previous_commit\" ] && [ \"$previous_commit\" != \"$commit\" ]; then kubectl -n \"$namespace\" annotate \"deployment/$deployment\" \"unidesk.ai/deploy-previous-commit=$previous_commit\" --overwrite; fi",
|
||||
"kubectl -n \"$namespace\" rollout status \"deployment/$deployment\" --timeout=180s",
|
||||
"python3 - \"$deployment_specs\" <<'PY' | while IFS=$'\\t' read -r rollout_deployment rollout_container; do",
|
||||
"import json, sys",
|
||||
"for item in json.load(open(sys.argv[1], encoding='utf-8')):",
|
||||
" print(f\"{item['name']}\\t{item['containerName']}\")",
|
||||
"PY",
|
||||
" kubectl -n \"$namespace\" set image \"deployment/$rollout_deployment\" \"$rollout_container=$commit_image\"",
|
||||
" kubectl -n \"$namespace\" set env \"deployment/$rollout_deployment\" \"UNIDESK_DEPLOY_SERVICE_ID=$service_id\" \"UNIDESK_DEPLOY_REF=$deploy_ref\" \"UNIDESK_DEPLOY_REPO=$source_repo\" \"UNIDESK_DEPLOY_COMMIT=$commit\" \"UNIDESK_DEPLOY_REQUESTED_COMMIT=$commit\" \"CODE_QUEUE_DEPLOY_COMMIT=$commit\" \"CODE_QUEUE_DEPLOY_REQUESTED_COMMIT=$commit\"",
|
||||
` kubectl -n "$namespace" annotate "deployment/$rollout_deployment" ${labels.map(shellQuote).join(" ")} --overwrite`,
|
||||
" if [ -n \"$previous_commit\" ] && [ \"$previous_commit\" != \"$commit\" ]; then kubectl -n \"$namespace\" annotate \"deployment/$rollout_deployment\" \"unidesk.ai/deploy-previous-commit=$previous_commit\" --overwrite; fi",
|
||||
"done",
|
||||
"python3 - \"$deployment_specs\" <<'PY' | while IFS= read -r rollout_deployment; do",
|
||||
"import json, sys",
|
||||
"for item in json.load(open(sys.argv[1], encoding='utf-8')):",
|
||||
" print(item['name'])",
|
||||
"PY",
|
||||
" kubectl -n \"$namespace\" rollout status \"deployment/$rollout_deployment\" --timeout=180s",
|
||||
"done",
|
||||
"deployment_commit=$(kubectl -n \"$namespace\" get deployment \"$deployment\" -o jsonpath='{.metadata.annotations.unidesk\\.ai/deploy-commit}')",
|
||||
"deployment_requested_commit=$(kubectl -n \"$namespace\" get deployment \"$deployment\" -o jsonpath='{.metadata.annotations.unidesk\\.ai/deploy-requested-commit}')",
|
||||
"test \"$deployment_commit\" = \"$commit\"",
|
||||
@@ -2069,6 +2224,11 @@ function localHelp(): Record<string, unknown> {
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service pipeline --commit <full-sha> --dry-run [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service met-nonlinear --commit <full-sha> --dry-run [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service k3sctl-adapter --commit <full-sha> --dry-run [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service code-queue --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
],
|
||||
firstStage: "install now writes the rendered systemd/Compose/config files and starts the registry",
|
||||
artifactConsumers: {
|
||||
@@ -2088,6 +2248,8 @@ function localHelp(): Record<string, unknown> {
|
||||
"bun scripts/cli.ts deploy apply --env prod --service pipeline --dry-run",
|
||||
"bun scripts/cli.ts deploy apply --env prod --service met-nonlinear --dry-run",
|
||||
"bun scripts/cli.ts deploy apply --env prod --service k3sctl-adapter --dry-run",
|
||||
"bun scripts/cli.ts deploy apply --env prod --service mdtodo",
|
||||
"bun scripts/cli.ts deploy apply --env prod --service claudeqq",
|
||||
],
|
||||
devCommands: [
|
||||
"bun scripts/cli.ts deploy apply --env dev --service frontend",
|
||||
@@ -2099,7 +2261,11 @@ function localHelp(): Record<string, unknown> {
|
||||
"bun scripts/cli.ts deploy apply --env dev --service findjob --dry-run",
|
||||
"bun scripts/cli.ts deploy apply --env dev --service pipeline --dry-run",
|
||||
"bun scripts/cli.ts deploy apply --env dev --service met-nonlinear --dry-run",
|
||||
"bun scripts/cli.ts deploy apply --env dev --service mdtodo",
|
||||
"bun scripts/cli.ts deploy apply --env dev --service claudeqq",
|
||||
"bun scripts/cli.ts deploy apply --env dev --service code-queue",
|
||||
],
|
||||
devOnlyConsumers: ["code-queue"],
|
||||
rollbackShape: "rerun the same artifact consumer with a previous commit-pinned image",
|
||||
},
|
||||
legacyEntrypoints: {
|
||||
|
||||
+92
-2
@@ -30,7 +30,6 @@ const ciRuntimeImages = [
|
||||
"alpine/git:2.45.2",
|
||||
ciCodeQueueImage,
|
||||
];
|
||||
|
||||
interface CiOptions {
|
||||
repoUrl: string;
|
||||
revision: string;
|
||||
@@ -836,6 +835,91 @@ async function prepareUserServiceArtifactSource(config: UniDeskConfig, options:
|
||||
};
|
||||
}
|
||||
|
||||
async function prepareClaudeqqArtifactSource(config: UniDeskConfig, options: CiPublishUserServiceArtifactOptions): Promise<Record<string, unknown>> {
|
||||
const sourceRoot = `/home/ubuntu/.unidesk/ci/user-service-artifacts/${options.serviceId}`;
|
||||
const sourceHostPath = options.sourceHostPath;
|
||||
const repoCache = "/home/ubuntu/.unidesk/ci/git/claudeqq-agent-skills.git";
|
||||
const repoFetchUrl = options.repoUrl;
|
||||
const assets = [
|
||||
{
|
||||
relativePath: "claudeqq/Dockerfile",
|
||||
sourcePath: rootPath("src/components/microservices/claudeqq/Dockerfile"),
|
||||
label: "Dockerfile",
|
||||
},
|
||||
{
|
||||
relativePath: "claudeqq/unidesk-adapter.cjs",
|
||||
sourcePath: rootPath("src/components/microservices/claudeqq/adapter.js"),
|
||||
label: "unidesk-adapter.cjs",
|
||||
},
|
||||
];
|
||||
for (const asset of assets) {
|
||||
if (!existsSync(asset.sourcePath)) throw new Error(`claudeqq artifact asset missing: ${asset.sourcePath}`);
|
||||
}
|
||||
const overlayCommands = assets.flatMap((asset) => {
|
||||
const encoded = Buffer.from(readFileSync(asset.sourcePath, "utf8"), "utf8").toString("base64");
|
||||
return [
|
||||
`mkdir -p "$tmp_dir/$(dirname ${shellQuote(asset.relativePath)})"`,
|
||||
`printf %s ${shellQuote(encoded)} | base64 -d > "$tmp_dir/${asset.relativePath}"`,
|
||||
`printf 'user_service_artifact_overlay=%s\\n' ${shellQuote(asset.label)}`,
|
||||
];
|
||||
});
|
||||
const script = [
|
||||
"set -euo pipefail",
|
||||
`service_id=${shellQuote(options.serviceId)}`,
|
||||
`commit=${shellQuote(options.commit)}`,
|
||||
`repo_url=${shellQuote(options.repoUrl)}`,
|
||||
`repo_fetch_url=${shellQuote(repoFetchUrl)}`,
|
||||
`dockerfile=${shellQuote(options.dockerfile)}`,
|
||||
`source_root=${shellQuote(sourceRoot)}`,
|
||||
`source_dir=${shellQuote(sourceHostPath)}`,
|
||||
`repo_cache=${shellQuote(repoCache)}`,
|
||||
`proxy_url=${shellQuote(providerGatewayWsEgressProxyUrl)}`,
|
||||
"mkdir -p \"$(dirname \"$repo_cache\")\" \"$source_root\"",
|
||||
"export HTTP_PROXY=\"$proxy_url\" HTTPS_PROXY=\"$proxy_url\" ALL_PROXY=\"$proxy_url\"",
|
||||
"export NO_PROXY=\"localhost,127.0.0.1,::1,host.docker.internal,.svc,.cluster.local,kubernetes.default.svc\"",
|
||||
"curl -fsSI --max-time 20 -x \"$proxy_url\" https://gitee.com >/dev/null",
|
||||
"echo user_service_artifact_source_proxy=provider-gateway-ws-egress:$proxy_url",
|
||||
"echo user_service_artifact_repo_fetch_url=$repo_fetch_url",
|
||||
"echo user_service_artifact_service_id=$service_id",
|
||||
"if [ ! -d \"$repo_cache\" ]; then git clone --mirror \"$repo_fetch_url\" \"$repo_cache\"; fi",
|
||||
"git -C \"$repo_cache\" remote set-url origin \"$repo_fetch_url\"",
|
||||
"git -C \"$repo_cache\" fetch --no-tags origin \"$commit\" || git -C \"$repo_cache\" fetch --no-tags origin '+refs/heads/*:refs/remotes/origin/*'",
|
||||
"resolved=$(git -C \"$repo_cache\" rev-parse --verify \"$commit^{commit}\")",
|
||||
"test \"$resolved\" = \"$commit\" || { echo \"user_service_artifact_resolved_commit_mismatch=$resolved expected=$commit\" >&2; exit 1; }",
|
||||
"git -C \"$repo_cache\" cat-file -e \"$commit:claudeqq/scripts/src/server_ts/package.json\"",
|
||||
"git -C \"$repo_cache\" cat-file -e \"$commit:claudeqq/scripts/src/server_ts/src\"",
|
||||
"tmp_dir=\"$source_root/.tmp-$commit-$$\"",
|
||||
"rm -rf \"$tmp_dir\"",
|
||||
"mkdir -p \"$tmp_dir\"",
|
||||
"git -C \"$repo_cache\" archive \"$commit\" claudeqq | tar -x -C \"$tmp_dir\"",
|
||||
...overlayCommands,
|
||||
"printf '%s\\n' \"$commit\" > \"$tmp_dir/.unidesk-source-commit\"",
|
||||
"printf '%s\\n' \"$repo_url\" > \"$tmp_dir/.unidesk-source-repo\"",
|
||||
"printf '%s\\n' \"$service_id\" > \"$tmp_dir/.unidesk-service-id\"",
|
||||
"printf '%s\\n' \"$dockerfile\" > \"$tmp_dir/.unidesk-dockerfile\"",
|
||||
"rm -rf \"$source_dir\"",
|
||||
"mv \"$tmp_dir\" \"$source_dir\"",
|
||||
"test -f \"$source_dir/$dockerfile\"",
|
||||
"test -f \"$source_dir/claudeqq/unidesk-adapter.cjs\"",
|
||||
"test -d \"$source_dir/claudeqq/scripts/src/server_ts/src\"",
|
||||
"echo user_service_artifact_source_host_path=$source_dir",
|
||||
].join("\n");
|
||||
const result = await runRemoteBackground(`prepare-${options.serviceId}-source`, script, 300_000);
|
||||
if (!result.ok) throw new Error(`failed to prepare ${options.serviceId} source on D601: ${result.stderr || result.stdout || JSON.stringify(result.raw)}`);
|
||||
return {
|
||||
ok: true,
|
||||
mode: "d601-host-gitee-https-export-with-unidesk-overlay",
|
||||
providerId: d601ProviderId,
|
||||
repoUrl: options.repoUrl,
|
||||
repoFetchUrl,
|
||||
commit: options.commit,
|
||||
serviceId: options.serviceId,
|
||||
dockerfile: options.dockerfile,
|
||||
sourceHostPath,
|
||||
stdoutTail: result.stdout.slice(-4000),
|
||||
};
|
||||
}
|
||||
|
||||
async function remoteCreatePipelineRun(manifest: string): Promise<string> {
|
||||
const encoded = Buffer.from(manifest, "utf8").toString("base64");
|
||||
const token = randomUUID().replace(/-/gu, "").slice(0, 12);
|
||||
@@ -1194,6 +1278,7 @@ async function publishUserServiceArtifact(config: UniDeskConfig, options: CiPubl
|
||||
dockerfile: options.dockerfile,
|
||||
imageRepository: options.imageRepository,
|
||||
sourceHostPath: options.sourceHostPath,
|
||||
...(options.serviceId === "claudeqq" ? { overlay: "UniDesk claudeqq Dockerfile and unidesk-adapter.cjs are injected before Tekton build" } : {}),
|
||||
},
|
||||
artifact: plannedArtifact.imageRef,
|
||||
artifactSummary: plannedArtifact,
|
||||
@@ -1203,7 +1288,9 @@ async function publishUserServiceArtifact(config: UniDeskConfig, options: CiPubl
|
||||
],
|
||||
};
|
||||
}
|
||||
const source = await prepareUserServiceArtifactSource(config, options);
|
||||
const source = options.serviceId === "claudeqq"
|
||||
? await prepareClaudeqqArtifactSource(config, options)
|
||||
: await prepareUserServiceArtifactSource(config, options);
|
||||
const name = await remoteCreatePipelineRun(userServiceArtifactPipelineRunManifest(options));
|
||||
const wait = await waitForPipelineRun(name, options.waitMs);
|
||||
const condition = wait === null ? null : await readPipelineRunCondition(name);
|
||||
@@ -1519,6 +1606,9 @@ export function ciHelp(): Record<string, unknown> {
|
||||
"bun scripts/cli.ts ci run --revision <commit>",
|
||||
"bun scripts/cli.ts ci publish-backend-core --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci publish-user-service --service baidu-netdisk --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci publish-user-service --service mdtodo --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci publish-user-service --service claudeqq --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci publish-user-service --service code-queue --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci publish-user-service --service decision-center --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci publish-user-service --service frontend --commit <full-sha>",
|
||||
"bun scripts/cli.ts ci run-dev-e2e --wait-ms 600000",
|
||||
|
||||
+49
-19
@@ -134,12 +134,12 @@ const nativeK3sInstallVersion = "v1.34.1+k3s1";
|
||||
const nativeK3sImage = "rancher/k3s:v1.34.1-k3s1";
|
||||
const nativeK3sCtrAddress = "/run/k3s/containerd/containerd.sock";
|
||||
const unideskRepoUrl = "https://github.com/pikasTech/unidesk";
|
||||
const d601MaintenanceDeployAllowedServiceIds = new Set<string>(["backend-core", "k3sctl-adapter", "code-queue"]);
|
||||
const d601MaintenanceDeployAllowedServiceIds = new Set<string>(["backend-core", "k3sctl-adapter"]);
|
||||
const devApplySupportedServiceIds = new Set<string>(["backend-core"]);
|
||||
const devArtifactConsumerServiceIds = new Set<string>(["baidu-netdisk", "code-queue-mgr", "decision-center", "findjob", "frontend", "met-nonlinear", "oa-event-flow", "pipeline", "project-manager", "todo-note"]);
|
||||
const devArtifactConsumerServiceIds = new Set<string>(["baidu-netdisk", "claudeqq", "code-queue", "code-queue-mgr", "decision-center", "findjob", "frontend", "mdtodo", "met-nonlinear", "oa-event-flow", "pipeline", "project-manager", "todo-note"]);
|
||||
const devArtifactConsumerProdDesiredFallbackServiceIds = new Set<string>(["code-queue-mgr", "oa-event-flow", "project-manager", "todo-note"]);
|
||||
const prodArtifactConsumerServiceIds = new Set<string>(["backend-core", "baidu-netdisk", "code-queue-mgr", "decision-center", "findjob", "frontend", "k3sctl-adapter", "met-nonlinear", "oa-event-flow", "pipeline", "project-manager", "todo-note"]);
|
||||
const prodForbiddenTargetSideBuildServiceIds = new Set<string>(["backend-core", "baidu-netdisk", "decision-center", "findjob", "frontend", "k3sctl-adapter", "met-nonlinear", "pipeline"]);
|
||||
const prodArtifactConsumerServiceIds = new Set<string>(["backend-core", "baidu-netdisk", "claudeqq", "code-queue-mgr", "decision-center", "findjob", "frontend", "k3sctl-adapter", "mdtodo", "met-nonlinear", "oa-event-flow", "pipeline", "project-manager", "todo-note"]);
|
||||
const prodForbiddenTargetSideBuildServiceIds = new Set<string>(["backend-core", "baidu-netdisk", "claudeqq", "decision-center", "findjob", "frontend", "k3sctl-adapter", "mdtodo", "met-nonlinear", "pipeline"]);
|
||||
const prodArtifactLiveApplyBlockedServiceIds = new Map<string, string>([
|
||||
["code-queue-mgr", "code-queue-mgr is the main-server Code Queue control-plane sidecar; live production apply requires explicit supervisor confirmation."],
|
||||
["met-nonlinear", "met-nonlinear is blocked for live artifact deploy because config.json points at docker/unidesk/Dockerfile.ml while the compose service is met-nonlinear-ts."],
|
||||
@@ -206,8 +206,8 @@ export function deployHelp(action: string | undefined = undefined): Record<strin
|
||||
apply: "Start an async target-side reconcile job unless --run-now is explicitly present.",
|
||||
},
|
||||
options: [
|
||||
{ name: "--file <path>", 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 <dev|prod>", 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, todo-note, findjob, pipeline, and met-nonlinear. Prod apply uses the D601 registry artifact consumer for reviewed services; code-queue-mgr and D601 direct infrastructure/incomplete contracts are dry-run or supervisor-gated." },
|
||||
{ name: "--file <path>", 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 D601 maintenance apply is limited to approved direct exceptions; Code Queue direct rollout is disabled." },
|
||||
{ name: "--env <dev|prod>", 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, mdtodo, claudeqq, dev-only code-queue, project-manager, oa-event-flow, code-queue-mgr, todo-note, findjob, pipeline, and met-nonlinear. Prod apply uses reviewed D601 registry artifact consumers; code-queue has no prod target and gated/incomplete services return structured unsupported or dry-run-only output." },
|
||||
{ name: "--service <id>", description: "Limit reconcile to one service from the manifest." },
|
||||
{ name: "--commit <full-sha>", 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." },
|
||||
@@ -636,6 +636,7 @@ function devK3sDeployService(id: string): UniDeskMicroserviceConfig | undefined
|
||||
const specs: Record<string, {
|
||||
name: string;
|
||||
description: string;
|
||||
repoUrl?: string;
|
||||
dockerfile: string;
|
||||
composeService: string;
|
||||
composeFile: string;
|
||||
@@ -689,6 +690,35 @@ function devK3sDeployService(id: string): UniDeskMicroserviceConfig | undefined
|
||||
allowedMethods: ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"],
|
||||
allowedPathPrefixes: ["/", "/api/", "/logs"],
|
||||
},
|
||||
mdtodo: {
|
||||
name: "UniDesk Dev MDTODO",
|
||||
description: "Isolated dev MDTODO deployed into D601 native k3s namespace unidesk-dev.",
|
||||
dockerfile: "src/components/microservices/mdtodo/Dockerfile",
|
||||
composeFile: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-mdtodo.k8s.yaml",
|
||||
composeService: "mdtodo-dev",
|
||||
containerName: "k3s:mdtodo-dev",
|
||||
nodeBaseUrl: "k3s://mdtodo-dev",
|
||||
nodePort: 4267,
|
||||
healthPath: "/health",
|
||||
route: "/dev/mdtodo",
|
||||
allowedMethods: ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"],
|
||||
allowedPathPrefixes: ["/health", "/live", "/logs", "/api/"],
|
||||
},
|
||||
claudeqq: {
|
||||
name: "UniDesk Dev ClaudeQQ",
|
||||
description: "Isolated dev ClaudeQQ deployed into D601 native k3s namespace unidesk-dev.",
|
||||
repoUrl: "https://gitee.com/lyon1998/agent_skills",
|
||||
dockerfile: "claudeqq/Dockerfile",
|
||||
composeFile: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-claudeqq.k8s.yaml",
|
||||
composeService: "claudeqq-dev",
|
||||
containerName: "k3s:claudeqq-dev",
|
||||
nodeBaseUrl: "k3s://claudeqq-dev",
|
||||
nodePort: 3290,
|
||||
healthPath: "/health",
|
||||
route: "/dev/claudeqq",
|
||||
allowedMethods: ["GET", "HEAD", "POST", "DELETE"],
|
||||
allowedPathPrefixes: ["/health", "/logs", "/api/"],
|
||||
},
|
||||
"code-queue": {
|
||||
name: "UniDesk Dev Code Queue",
|
||||
description: "Isolated dev Code Queue execution plane deployed into D601 native k3s namespace unidesk-dev.",
|
||||
@@ -712,7 +742,7 @@ function devK3sDeployService(id: string): UniDeskMicroserviceConfig | undefined
|
||||
providerId: "D601",
|
||||
description: spec.description,
|
||||
repository: {
|
||||
url: unideskRepoUrl,
|
||||
url: spec.repoUrl ?? unideskRepoUrl,
|
||||
commitId: "deploy-env",
|
||||
dockerfile: spec.dockerfile,
|
||||
composeFile: spec.composeFile,
|
||||
@@ -809,6 +839,7 @@ function selectServices(config: UniDeskConfig, manifest: DeployManifest, service
|
||||
function unsupportedReason(service: UniDeskMicroserviceConfig): string | null {
|
||||
if (service.repository.dockerfile.startsWith("docker.io/")) return "image-only service has no Dockerfile source artifact";
|
||||
if (service.repository.composeFile.startsWith("docker run")) return "docker-run image-only service has no compose/k8s build path";
|
||||
if (isD601MaintenanceDeployBlocked(service)) return "D601 maintenance-channel deployment is not allowed for this service; use reviewed registry artifact consumers instead";
|
||||
if (service.repository.commitId === "local") return null;
|
||||
return null;
|
||||
}
|
||||
@@ -2242,7 +2273,7 @@ async function readK8sCommit(config: UniDeskConfig, service: UniDeskMicroservice
|
||||
}
|
||||
|
||||
function manifestEnvironmentForService(service: UniDeskMicroserviceConfig): DeployEnvironment {
|
||||
return service.id === "decision-center" && service.deployment.namespace === "unidesk-dev" ? "dev" : "prod";
|
||||
return service.deployment.namespace === "unidesk-dev" ? "dev" : "prod";
|
||||
}
|
||||
|
||||
function serviceDeployRef(service: UniDeskMicroserviceConfig): string {
|
||||
@@ -2250,9 +2281,7 @@ function serviceDeployRef(service: UniDeskMicroserviceConfig): string {
|
||||
}
|
||||
|
||||
function k3sDeploymentManifestPath(service: UniDeskMicroserviceConfig): string {
|
||||
if (service.id === "decision-center" && service.deployment.namespace === "unidesk-dev") {
|
||||
return "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-decision-center.k8s.yaml";
|
||||
}
|
||||
if (service.deployment.namespace === "unidesk-dev") return k8sManifestPath(service);
|
||||
if (service.id === "decision-center") {
|
||||
return "src/components/microservices/k3sctl-adapter/k3s/decision-center.k8s.yaml";
|
||||
}
|
||||
@@ -2649,7 +2678,7 @@ function blockedD601MaintenanceDeployServices(config: UniDeskConfig, manifest: D
|
||||
}
|
||||
|
||||
function d601MaintenanceDeployBlockMessage(blocked: string[]): string {
|
||||
return `D601 target-side deployment is enabled only for k3sctl-adapter and dev backend-core; artifact consumers must use registry CD. Blocked services: ${blocked.join(", ")}. Use ci run-dev-e2e for dev smoke verification.`;
|
||||
return `D601 target-side deployment is enabled only for k3sctl-adapter and dev backend-core; artifact consumers must use registry CD. Blocked services: ${blocked.join(", ")}. Code Queue is dev-only through artifact-registry/deploy --env dev and has no production direct rollout path.`;
|
||||
}
|
||||
|
||||
function selectedDevArtifactServices(manifest: DeployManifest, serviceId: string | null): DeployManifestService[] {
|
||||
@@ -2889,7 +2918,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/todo-note/findjob/pipeline/met-nonlinear artifact consumers; unsupported selected services: ${unsupported.join(", ")}. 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/mdtodo/claudeqq/code-queue/project-manager/oa-event-flow/code-queue-mgr/todo-note/findjob/pipeline/met-nonlinear 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);
|
||||
@@ -2909,15 +2938,16 @@ export async function runDeployCommand(config: UniDeskConfig | null, args: strin
|
||||
return applyJob(config, args, options);
|
||||
}
|
||||
if (config === null) throw new Error("deploy local manifest mode requires config.json");
|
||||
const manifest = resolveManifestCommits(await readDeployManifest(options.file), options.serviceId);
|
||||
const rawManifest = await readDeployManifest(options.file);
|
||||
if (action === "apply") {
|
||||
const blocked = blockedD601MaintenanceDeployServices(config, rawManifest, options.serviceId);
|
||||
if (blocked.length > 0) throw new Error(d601MaintenanceDeployBlockMessage(blocked));
|
||||
}
|
||||
const manifest = resolveManifestCommits(rawManifest, options.serviceId);
|
||||
if (action === "check" || action === "plan") return await checkOrPlan(config, manifest, options, action);
|
||||
const prodArtifactConsumers = selectedEnvironmentServices(manifest, options.serviceId)
|
||||
.filter((service) => manifest.environment !== "dev" && prodForbiddenTargetSideBuildServiceIds.has(service.id));
|
||||
if (prodArtifactConsumers.length > 0) return prodArtifactConsumerLocalManifestResult(prodArtifactConsumers);
|
||||
if (!options.dryRun) {
|
||||
const blocked = blockedD601MaintenanceDeployServices(config, manifest, options.serviceId);
|
||||
if (blocked.length > 0) throw new Error(d601MaintenanceDeployBlockMessage(blocked));
|
||||
}
|
||||
if (options.dryRun || options.runNow) return await runApplyNow(config, manifest, options);
|
||||
return applyJob(config, args, options);
|
||||
}
|
||||
@@ -2926,5 +2956,5 @@ export async function runCodeQueueDeployCompatCommand(_config: UniDeskConfig, ar
|
||||
if (args.includes("--skip-build")) throw new Error("codex deploy is disabled; --skip-build is not supported");
|
||||
const providerId = optionValue(args, ["--provider-id", "--provider"]) ?? "D601";
|
||||
if (providerId !== "D601") throw new Error(`codex deploy compatibility path only supports D601; got ${providerId}`);
|
||||
throw new Error("codex deploy is disabled because D601 maintenance-channel direct deployment must not deploy Code Queue. Current dev automation is CI-only; use ci run-dev-e2e for dev smoke verification.");
|
||||
throw new Error("codex deploy is disabled because D601 maintenance-channel direct deployment must not deploy Code Queue. Use the dev-only artifact consumer with deploy apply --env dev --service code-queue or artifact-registry deploy-service --env dev --service code-queue; production Code Queue artifact deployment is unsupported.");
|
||||
}
|
||||
|
||||
@@ -39,6 +39,14 @@ const codeQueueRequiredKinds = new Set([
|
||||
"Deployment/code-queue-read-dev",
|
||||
"Deployment/code-queue-write-dev",
|
||||
]);
|
||||
const mdtodoRequiredKinds = new Set([
|
||||
"Service/mdtodo-dev",
|
||||
"Deployment/mdtodo-dev",
|
||||
]);
|
||||
const claudeqqRequiredKinds = new Set([
|
||||
"Service/claudeqq-dev",
|
||||
"Deployment/claudeqq-dev",
|
||||
]);
|
||||
|
||||
interface ManifestDocument {
|
||||
index: number;
|
||||
@@ -172,6 +180,8 @@ function parseManifestDocuments(text: string): ManifestDocument[] {
|
||||
function requiredResourcesFor(resources: string[]): Set<string> {
|
||||
const resourceSet = new Set(resources);
|
||||
if (resourceSet.has("Deployment/code-queue-scheduler-dev") || resourceSet.has("Service/code-queue-scheduler-dev")) return codeQueueRequiredKinds;
|
||||
if (resourceSet.has("Deployment/mdtodo-dev") || resourceSet.has("Service/mdtodo-dev")) return mdtodoRequiredKinds;
|
||||
if (resourceSet.has("Deployment/claudeqq-dev") || resourceSet.has("Service/claudeqq-dev")) return claudeqqRequiredKinds;
|
||||
if (resourceSet.has("Deployment/backend-core-dev") || resourceSet.has("Deployment/frontend-dev")) return coreRequiredKinds;
|
||||
return foundationRequiredKinds;
|
||||
}
|
||||
@@ -301,6 +311,7 @@ function devEnvHelp(): Record<string, unknown> {
|
||||
checks: [
|
||||
"all namespaced resources must target unidesk-dev",
|
||||
"required foundation resources, backend-core-dev/frontend-dev resources, or code-queue-dev resources must exist",
|
||||
"mdtodo-dev and claudeqq-dev service manifests may be validated independently when those dev workload manifests are selected",
|
||||
"dev DATABASE_URL values must target postgres-dev/unidesk_dev and not production routes",
|
||||
"--kubectl-dry-run optionally asks kubectl to client-dry-run the manifest without applying it",
|
||||
"prewarm-images imports dev foundation images from Docker into native k3s containerd on D601",
|
||||
|
||||
+11
-4
@@ -36,12 +36,12 @@ 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 <id>", 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 applies supported dev target-side rollouts or reviewed D601 registry 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. code-queue artifact consumption is dev-only." },
|
||||
{ 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: "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 k3s-managed dev/prod consumers and code-queue dev-only validation." },
|
||||
{ command: "schedule list|get|runs|run|delete", description: "Manage backend-core scheduled tasks and run history; schedule run <id> supports --wait-ms N." },
|
||||
{ command: "schedule upsert-pgdata-backup [--time HH:MM] [--remote-base /SERVER_DATA/UNIDESK_PG_DATA]", description: "Create or update the daily PGDATA physical backup task that uploads monthly rotated archives to Baidu Netdisk." },
|
||||
{ command: "codex deploy <commitId> [--provider-id D601] [--timeout-ms N]", description: "Compatibility wrapper for deploy apply --service code-queue with a temporary repo+commit manifest." },
|
||||
{ command: "codex deploy <commitId> [--provider-id D601] [--timeout-ms N]", description: "Disabled legacy Code Queue deploy path; use the dev-only artifact consumer instead." },
|
||||
{ command: "codex submit [prompt] [--prompt-file path|--prompt-stdin] [--queue queueId] [--provider-id id] [--cwd path] [--model model] [--execution-mode mode] [--max-attempts N] [--reference-task-id id] [--dry-run]", description: "Submit a Code Queue task through backend-core -> code-queue proxy; --dry-run shows the structured request without enqueueing." },
|
||||
{ command: "codex task <taskId> [--trace --tail|--from-start|--after-seq N|--before-seq N --limit N] [--full]", description: "Fetch a compact Code Queue task summary; trace rows are opt-in and paged with next/previous commands to avoid output explosion." },
|
||||
{ command: "codex tasks [--queue id] [--limit N] [--unread-only]", description: "Show the current running, unread terminal, and recent completed Code Queue tasks in one JSON view." },
|
||||
@@ -183,6 +183,7 @@ function codexHelp(): unknown {
|
||||
command: "codex deploy|submit|task|tasks|output|judge|interrupt|cancel|queues|queue|move",
|
||||
output: "json",
|
||||
usage: [
|
||||
"bun scripts/cli.ts codex deploy <commitId> # disabled legacy deployment entry",
|
||||
"bun scripts/cli.ts codex submit [prompt] [--prompt-file path|--prompt-stdin] [--queue id] [--dry-run]",
|
||||
"bun scripts/cli.ts codex task <taskId> [--trace --tail|--from-start|--after-seq N|--before-seq N --limit N] [--full]",
|
||||
"bun scripts/cli.ts codex tasks [--queue id] [--limit N] [--unread-only]",
|
||||
@@ -269,6 +270,11 @@ function artifactRegistryHelp(): unknown {
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service code-queue-mgr --commit <full-sha> --dry-run [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
|
||||
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service code-queue --commit <full-sha> [--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: [
|
||||
@@ -276,7 +282,8 @@ 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, code-queue-mgr, and todo-note as standardized consumers; code-queue-mgr prod live apply remains supervisor-gated",
|
||||
"deploy-service currently supports backend-core, baidu-netdisk, prod/dev frontend, decision-center, mdtodo, claudeqq, project-manager, oa-event-flow, code-queue-mgr, todo-note, findjob, pipeline, met-nonlinear, k3sctl-adapter, and dev-only code-queue as standardized consumers",
|
||||
"code-queue has no prod artifact deploy target and prod requests return structured unsupported",
|
||||
"status and health use provider-gateway Host SSH readonly checks",
|
||||
],
|
||||
legacyEntrypoints: {
|
||||
|
||||
Reference in New Issue
Block a user