From 472f29312ef2a59cd5b9c540d35823aff3d7df6a Mon Sep 17 00:00:00 2001 From: CabLate <85614048+cablate@users.noreply.github.com> Date: Wed, 16 Sep 2026 21:04:39 +0800 Subject: [PATCH 1/2] fix: safely resume partially published releases --- .github/workflows/ci.yml | 9 +++++++ .github/workflows/release.yml | 44 ++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a03c465..57c1db4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,15 @@ jobs: env: GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} + # Temporary PR-only probe; remove before merge. + - name: Verify v0.0.61 retry package matches npm + if: github.head_ref == 'codex/retry-release-publication' + run: | + npm version patch --no-git-tag-version + REMOTE=$(npm view @cablate/mcp-google-map@0.0.61 dist.integrity --json | jq -r '.') + LOCAL=$(npm pack --dry-run --json | jq -r '.[0].integrity') + test "$REMOTE" = "$LOCAL" + node18: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18ae7c0..928d879 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,7 +93,22 @@ jobs: mv "$TMPFILE" CHANGELOG.md - name: Publish to npm - run: npm publish --access public + run: | + PACKAGE=$(node -p "require('./package.json').name") + VERSION=$(node -p "require('./package.json').version") + if npm view "${PACKAGE}@${VERSION}" version --json >/dev/null 2>&1; then + # npm may have accepted a previous attempt before the registry or + # version tag succeeded. Resume only if the packed bytes are identical. + PUBLISHED_INTEGRITY=$(npm view "${PACKAGE}@${VERSION}" dist.integrity --json | jq -r '.') + LOCAL_INTEGRITY=$(npm pack --dry-run --json | jq -r '.[0].integrity') + if [ "$PUBLISHED_INTEGRITY" != "$LOCAL_INTEGRITY" ]; then + echo "${PACKAGE}@${VERSION} already exists with different package contents" >&2 + exit 1 + fi + echo "${PACKAGE}@${VERSION} was already published with identical contents" + else + npm publish --access public + fi env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} @@ -104,14 +119,37 @@ jobs: - name: Publish to MCP Registry run: | + VERSION=$(node -p "require('./package.json').version") + SERVER_NAME=$(jq -r '.name' server.json) + ENCODED_SERVER_NAME=${SERVER_NAME//\//%2F} + REGISTRY_RESPONSE="$RUNNER_TEMP/mcp-registry-version.json" + STATUS=$(curl -sS --retry 3 -o "$REGISTRY_RESPONSE" -w '%{http_code}' \ + "https://registry.modelcontextprotocol.io/v0.1/servers/${ENCODED_SERVER_NAME}/versions/${VERSION}") + if [ "$STATUS" = 200 ]; then + # The registry omits optional false fields; compare after normalizing them. + if ! jq -e -s ' + def strip_false: walk(if type == "object" then with_entries(select(.value != false)) else . end); + (.[0].server | strip_false) == (.[1] | strip_false) + ' "$REGISTRY_RESPONSE" server.json >/dev/null; then + echo "MCP Registry already has a different ${SERVER_NAME}@${VERSION}" >&2 + exit 1 + fi + echo "${SERVER_NAME}@${VERSION} was already published to MCP Registry" + exit 0 + fi + if [ "$STATUS" != 404 ]; then + echo "Could not check MCP Registry version: HTTP ${STATUS}" >&2 + exit 1 + fi + curl -sL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_linux_amd64.tar.gz" | tar xz mcp-publisher ./mcp-publisher login github-oidc - for attempt in 1 2 3 4 5 6; do + for attempt in {1..30}; do if ./mcp-publisher publish; then exit 0 fi - if [ "$attempt" -eq 6 ]; then + if [ "$attempt" -eq 30 ]; then echo "MCP Registry publish failed after $attempt attempts" exit 1 fi From 4f1987720c1a80d63bcf60bf593ea1ec0fe9917e Mon Sep 17 00:00:00 2001 From: CabLate <85614048+cablate@users.noreply.github.com> Date: Wed, 16 Sep 2026 21:06:08 +0800 Subject: [PATCH 2/2] test: remove temporary release fingerprint probe --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57c1db4..a03c465 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,15 +25,6 @@ jobs: env: GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} - # Temporary PR-only probe; remove before merge. - - name: Verify v0.0.61 retry package matches npm - if: github.head_ref == 'codex/retry-release-publication' - run: | - npm version patch --no-git-tag-version - REMOTE=$(npm view @cablate/mcp-google-map@0.0.61 dist.integrity --json | jq -r '.') - LOCAL=$(npm pack --dry-run --json | jq -r '.[0].integrity') - test "$REMOTE" = "$LOCAL" - node18: runs-on: ubuntu-latest steps: