From 00d5066009cb52201782f491336234228fa10702 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 20 May 2026 03:41:13 +0000 Subject: [PATCH] fix: clarify todo note artifact producer --- CI.json | 3 ++- docs/reference/user-service-delivery.md | 3 ++- scripts/src/ci.ts | 21 +++++++++++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CI.json b/CI.json index b1609793..0e5d1c7f 100644 --- a/CI.json +++ b/CI.json @@ -132,7 +132,8 @@ }, "image": { "repository": "unidesk/todo-note" - } + }, + "notes": "External Gitee source repo. CI must fetch https://gitee.com/Lyon1998/todo_note at the requested commit and build that repo's Dockerfile; UniDesk only owns the runtime consumer metadata and Compose integration." }, { "serviceId": "code-queue-mgr", diff --git a/docs/reference/user-service-delivery.md b/docs/reference/user-service-delivery.md index 272ddf4e..eabfe7d2 100644 --- a/docs/reference/user-service-delivery.md +++ b/docs/reference/user-service-delivery.md @@ -116,7 +116,8 @@ OA Event Flow follows the same master-server Compose artifact flow as Project Ma 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`. -- 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. +- The standard producer is `bun scripts/cli.ts ci publish-user-service --service todo-note --commit --wait-ms 1200000`; it fetches the external Gitee repo at that commit and builds that repo's `Dockerfile`, rather than treating Todo Note as UniDesk-owned source. +- Dev/prod CD require the D601 registry artifact `127.0.0.1:5000/unidesk/todo-note:` published from that external source. - 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. diff --git a/scripts/src/ci.ts b/scripts/src/ci.ts index ae4fc099..40859107 100644 --- a/scripts/src/ci.ts +++ b/scripts/src/ci.ts @@ -201,6 +201,17 @@ function repoNeedsGithubSshIdentity(repoFetchUrl: string): boolean { return repoFetchUrl.startsWith("git@github.com:"); } +function repoConnectivityProbeUrl(repoFetchUrl: string): string { + const sshMatch = /^git@([^:]+):/u.exec(repoFetchUrl); + if (sshMatch !== null) return `https://${sshMatch[1]}`; + try { + const parsed = new URL(repoFetchUrl); + return `${parsed.protocol}//${parsed.host}`; + } catch { + return repoFetchUrl.startsWith("https://gitee.com/") ? "https://gitee.com" : "https://github.com"; + } +} + function requireRepoRelativePath(path: string, label: string): string { if (path.length === 0 || path.startsWith("/") || path.includes("\0") || path.split("/").includes("..")) { throw new Error(`${label} must be a repo-relative path`); @@ -768,6 +779,7 @@ async function prepareUserServiceArtifactSource(config: UniDeskConfig, options: const sourceHostPath = options.sourceHostPath; const repoCache = `/home/ubuntu/.unidesk/ci/git/${safePathToken(options.serviceId)}.git`; const repoFetchUrl = repoSshUrl(options.repoUrl); + const repoProbeUrl = repoConnectivityProbeUrl(repoFetchUrl); const sshIdentity = repoNeedsGithubSshIdentity(repoFetchUrl) ? await ensureGithubSshIdentityForProvider(config, d601ProviderId) : null; if (sshIdentity !== null && !sshIdentity.ok) throw new Error(sshIdentity.detail); const proxyPython = gitSshHttpConnectProxySource(); @@ -777,6 +789,7 @@ async function prepareUserServiceArtifactSource(config: UniDeskConfig, options: `commit=${shellQuote(options.commit)}`, `repo_url=${shellQuote(options.repoUrl)}`, `repo_fetch_url=${shellQuote(repoFetchUrl)}`, + `repo_probe_url=${shellQuote(repoProbeUrl)}`, `dockerfile=${shellQuote(options.dockerfile)}`, `source_root=${shellQuote(sourceRoot)}`, `source_dir=${shellQuote(sourceHostPath)}`, @@ -785,7 +798,7 @@ async function prepareUserServiceArtifactSource(config: UniDeskConfig, options: "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://github.com >/dev/null", + "curl -fsSI --max-time 20 -x \"$proxy_url\" \"$repo_probe_url\" >/dev/null", "git_ssh_proxy=/tmp/unidesk-git-ssh-http-connect.py", "cat > \"$git_ssh_proxy\" <<'UNIDESK_GIT_SSH_PROXY'", proxyPython, @@ -795,6 +808,7 @@ async function prepareUserServiceArtifactSource(config: UniDeskConfig, options: "export GIT_SSH_COMMAND=\"ssh -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/known_hosts -i $HOME/.ssh/id_ed25519 -o 'ProxyCommand=$git_ssh_proxy %h %p'\"", "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_repo_probe_url=$repo_probe_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\"", @@ -823,6 +837,7 @@ async function prepareUserServiceArtifactSource(config: UniDeskConfig, options: providerId: d601ProviderId, repoUrl: options.repoUrl, repoFetchUrl, + repoProbeUrl, commit: options.commit, serviceId: options.serviceId, dockerfile: options.dockerfile, @@ -1257,6 +1272,7 @@ async function publishUserServiceArtifact(config: UniDeskConfig, options: CiPubl imageRepository: options.imageRepository, }; const plannedArtifact = artifactSummaryDefaults(summaryContext); + const plannedRepoFetchUrl = repoSshUrl(options.repoUrl); if (options.dryRun) { return { ok: true, @@ -1272,7 +1288,8 @@ async function publishUserServiceArtifact(config: UniDeskConfig, options: CiPubl mode: "planned-only", providerId: d601ProviderId, repoUrl: options.repoUrl, - repoFetchUrl: repoSshUrl(options.repoUrl), + repoFetchUrl: plannedRepoFetchUrl, + repoProbeUrl: repoConnectivityProbeUrl(plannedRepoFetchUrl), commit: options.commit, serviceId: options.serviceId, dockerfile: options.dockerfile,