From 37c6f121d308f46839e09e9a511168836c197ed2 Mon Sep 17 00:00:00 2001 From: Christoph Dyllick-Brenzinger Date: Tue, 1 Sep 2026 17:02:04 +0200 Subject: [PATCH] Split MCP Registry publish into its own job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v1.6.1 release failed on the registry step with an i/o timeout during the OIDC token exchange, after npm and Docker had already published successfully. Two problems followed from npm and the registry sharing one job: - The failure was unrecoverable by re-run. Re-running the job repeats `npm publish`, which npm rejects for an already-published version, so the run dies before reaching the registry again. Recovery meant publishing by hand. - The run showed red although the release itself was fine. A red release run that usually means "nothing shipped" but sometimes means "only the directory entry is missing" trains people to stop reading release status. publish-registry now runs after publish-npm as a separate job, so a registry outage can be retried on its own without touching npm. The version patch moves with it: server.json is not in package.json `files`, so it never ships to npm and only the registry publish ever needed it. Also retries the OIDC login three times with linear backoff. That only covers brief blips — the registry was still unreachable half an hour after the v1.6.1 failure, and no retry count would have helped there. The job split is what makes a real outage recoverable. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WUg1nG8m7NYmqdToqHsHvK --- .github/workflows/build-and-publish.yml | 47 +++++++++++++++++++++---- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 848119a..dda931a 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -127,8 +127,8 @@ jobs: vuln-type: "os,library" severity: "CRITICAL,HIGH" - # npm + MCP Registry publish — only on release tags (trusted publishing via OIDC) - publish: + # npm publish — only on release tags (trusted publishing via OIDC) + publish-npm: if: startsWith(github.ref, 'refs/tags/release-v') runs-on: ubuntu-latest needs: [lint-and-test, init-vars] @@ -156,18 +156,51 @@ jobs: echo "::error::package.json version ($PKG_VERSION) does not match tag version ($TAG_VERSION)" exit 1 fi - - name: Patch server.json version - run: | - jq --arg v "${{ needs.init-vars.outputs.version }}" \ - '.version = $v | .packages[].version = $v' server.json > tmp.json && mv tmp.json server.json - name: Build run: npm run build - name: Publish to npm run: npm publish --provenance --access public + + # MCP Registry publish — deliberately a separate job. + # + # The registry is third-party infrastructure and has gone unreachable during a + # release (v1.6.1: i/o timeout on the OIDC token exchange). While it shared a + # job with npm, that outage could not be retried: re-running the job repeats + # `npm publish`, which npm rejects for an already-published version, so the run + # died before ever reaching the registry again. Split out, this job retries on + # its own and a registry outage no longer marks an otherwise good release red. + # + # server.json is not in package.json `files`, so it never ships to npm and the + # version patch belongs here rather than in the npm job. + publish-registry: + if: startsWith(github.ref, 'refs/tags/release-v') + runs-on: ubuntu-latest + needs: [init-vars, publish-npm] + permissions: + contents: read + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Patch server.json version + run: | + jq --arg v "${{ needs.init-vars.outputs.version }}" \ + '.version = $v | .packages[].version = $v' server.json > tmp.json && mv tmp.json server.json - name: Install mcp-publisher run: | curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_linux_amd64.tar.gz" | tar xz mcp-publisher - name: Authenticate to MCP Registry - run: ./mcp-publisher login github-oidc + run: | + for attempt in 1 2 3; do + if ./mcp-publisher login github-oidc; then + exit 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "::warning::MCP Registry auth attempt $attempt failed, retrying" + sleep $((attempt * 20)) + fi + done + echo "::error::MCP Registry unreachable after 3 attempts. npm and Docker published fine; re-run this job alone once the registry is back." + exit 1 - name: Publish to MCP Registry run: ./mcp-publisher publish