diff --git a/.gitea/workflows/publish-workspace-server-image.yml b/.gitea/workflows/publish-workspace-server-image.yml index e050b5bc8..6b54bea73 100644 --- a/.gitea/workflows/publish-workspace-server-image.yml +++ b/.gitea/workflows/publish-workspace-server-image.yml @@ -123,7 +123,14 @@ jobs: # with a per-entry ::error:: annotation naming the missing repo # (issue #2192). This is the push-time complement to PR #2186's # PR-time manifest-entry-existence gate. + # + # Token: workspace-template-* repos are PRIVATE, so the existence check + # must authenticate (same AUTO_SYNC_TOKEN as the clone step). Without it + # an unauthenticated GET 404s on private repos and false-prunes them + # (regression that dropped seo-agent/google-adk from the palette). - name: Validate manifest entries exist + env: + MOLECULE_GITEA_TOKEN: ${{ secrets.AUTO_SYNC_TOKEN }} run: | set -euo pipefail bash scripts/check-manifest-repos-exist.sh manifest.json diff --git a/manifest.json b/manifest.json index 5024514f2..75395fcca 100644 --- a/manifest.json +++ b/manifest.json @@ -28,7 +28,9 @@ {"name": "claude-code-default", "repo": "molecule-ai/molecule-ai-workspace-template-claude-code", "ref": "main"}, {"name": "hermes", "repo": "molecule-ai/molecule-ai-workspace-template-hermes", "ref": "main"}, {"name": "openclaw", "repo": "molecule-ai/molecule-ai-workspace-template-openclaw", "ref": "main"}, - {"name": "codex", "repo": "molecule-ai/molecule-ai-workspace-template-codex", "ref": "main"} + {"name": "codex", "repo": "molecule-ai/molecule-ai-workspace-template-codex", "ref": "main"}, + {"name": "google-adk", "repo": "molecule-ai/molecule-ai-workspace-template-google-adk", "ref": "main"}, + {"name": "seo-agent", "repo": "molecule-ai/molecule-ai-workspace-template-seo-agent", "ref": "main"} ], "org_templates": [ {"name": "molecule-dev", "repo": "molecule-ai/molecule-ai-org-template-molecule-dev", "ref": "main"}, diff --git a/scripts/check-manifest-repos-exist.sh b/scripts/check-manifest-repos-exist.sh index 278d86a2c..4c56d4b16 100755 --- a/scripts/check-manifest-repos-exist.sh +++ b/scripts/check-manifest-repos-exist.sh @@ -50,8 +50,22 @@ check_category() { repo=$(echo "$MANIFEST_JSON" | jq -r ".${category}[$i].repo") TOTAL=$((TOTAL + 1)) - # Check repo existence via Gitea API (public endpoint, no auth needed) - http_code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 "${GITEA_API}/${repo}" 2>/dev/null || true) + # Check repo existence via Gitea API. Many manifest repos are PRIVATE + # (e.g. the workspace templates), so an *unauthenticated* GET returns + # 404 even when the repo exists — indistinguishable from a genuinely + # missing repo. We therefore authenticate with the same token + # clone-manifest.sh uses (MOLECULE_GITEA_TOKEN). A 404 *with* a valid + # token still means the repo is truly missing, which is what we want + # to catch. If the token is unset (local dev), fall back to an + # unauthenticated request — private repos will then 404, so run the + # check in CI where the token is present. + if [ -n "${MOLECULE_GITEA_TOKEN:-}" ]; then + http_code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 \ + -H "Authorization: token ${MOLECULE_GITEA_TOKEN}" \ + "${GITEA_API}/${repo}" 2>/dev/null || true) + else + http_code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 "${GITEA_API}/${repo}" 2>/dev/null || true) + fi if [ "$http_code" != "200" ]; then echo "::error::manifest.json ${category} entry '${name}' → repo '${repo}' returned HTTP ${http_code} (expected 200). Delete the manifest entry BEFORE deleting the repo." >&2