From e9c84c7b81e5bfd8accf5d7853d0672bac155546 Mon Sep 17 00:00:00 2001 From: Savio Dias Date: Wed, 14 Oct 2026 18:47:58 +0530 Subject: [PATCH 1/3] fix(ci): wait for npm propagation before publishing to MCP Registry The MCP Registry validates that the npm version already exists before it accepts the server entry. The release workflow dispatches this one right after `npm publish`, but npm's read API lags publish by up to a minute, so the registry check raced it and 404'd. That race failed the last three tag-triggered releases: v2.2.0 registry 404 at 15:21:34, npm served it at 15:21:57 (23s early) v2.2.1 registry 404 at 14:29:12, npm served it at 14:29:30 (18s early) v2.2.2 registry 404 at 14:23:26, npm served it at 14:24:04 (38s early) In every case the npm publish itself succeeded; only the registry step failed, which is why manually re-running it later always went green. Poll registry.npmjs.org for the exact version (up to 5 minutes) before logging in, and retry the publish up to 3 times so a brief blip does not cost a whole release cycle. Co-Authored-By: Claude Opus 5 --- .github/workflows/mcp-registry-publish.yml | 39 +++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mcp-registry-publish.yml b/.github/workflows/mcp-registry-publish.yml index 6b52489e..cdbeb886 100644 --- a/.github/workflows/mcp-registry-publish.yml +++ b/.github/workflows/mcp-registry-publish.yml @@ -50,8 +50,45 @@ jobs: mv server.json.tmp server.json cat server.json + - name: Wait for npm to serve the release + # The registry validates that the npm version exists before accepting + # the server entry. npm's read API lags publish by up to a minute, so + # tag-triggered runs raced it and failed (v2.2.0/2.2.1/2.2.2 all 404'd + # seconds before the version appeared). Poll until npm serves it. + env: + PACKAGE_NAME: "@browserstack/mcp-server" + run: | + VERSION="$(node -p 'require("./package.json").version')" + ENCODED="${PACKAGE_NAME/\//%2F}" + for attempt in $(seq 1 30); do + STATUS="$(curl -sS -o /dev/null -w '%{http_code}' \ + "https://registry.npmjs.org/${ENCODED}/${VERSION}" || true)" + if [ "$STATUS" = "200" ]; then + echo "npm is serving ${PACKAGE_NAME}@${VERSION} (attempt ${attempt})." + exit 0 + fi + echo "Attempt ${attempt}/30: npm returned ${STATUS} for ${VERSION}; retrying in 10s." + sleep 10 + done + echo "::error::npm did not serve ${PACKAGE_NAME}@${VERSION} within 5 minutes." + exit 1 + - name: Login to MCP Registry run: ./mcp-publisher login github-oidc - name: Publish to MCP Registry - run: ./mcp-publisher publish + # Retry on transient registry/propagation errors so a brief blip does + # not cost a whole release cycle. + run: | + for attempt in 1 2 3; do + if ./mcp-publisher publish; then + echo "Published to MCP Registry (attempt ${attempt})." + exit 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "Publish attempt ${attempt} failed; retrying in 30s." + sleep 30 + fi + done + echo "::error::Failed to publish to the MCP Registry after 3 attempts." + exit 1 From 3a6eed15534870f8a46cb5718330be2514a4684f Mon Sep 17 00:00:00 2001 From: Savio Dias Date: Thu, 15 Oct 2026 13:48:14 +0530 Subject: [PATCH 2/3] chore(ci): trim redundant comments in registry publish workflow Co-Authored-By: Claude Opus 5 --- .github/workflows/mcp-registry-publish.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mcp-registry-publish.yml b/.github/workflows/mcp-registry-publish.yml index cdbeb886..037291c3 100644 --- a/.github/workflows/mcp-registry-publish.yml +++ b/.github/workflows/mcp-registry-publish.yml @@ -51,10 +51,8 @@ jobs: cat server.json - name: Wait for npm to serve the release - # The registry validates that the npm version exists before accepting - # the server entry. npm's read API lags publish by up to a minute, so - # tag-triggered runs raced it and failed (v2.2.0/2.2.1/2.2.2 all 404'd - # seconds before the version appeared). Poll until npm serves it. + # The registry rejects the entry unless npm already serves the version, + # and npm's read API lags publish by up to a minute. env: PACKAGE_NAME: "@browserstack/mcp-server" run: | @@ -77,8 +75,6 @@ jobs: run: ./mcp-publisher login github-oidc - name: Publish to MCP Registry - # Retry on transient registry/propagation errors so a brief blip does - # not cost a whole release cycle. run: | for attempt in 1 2 3; do if ./mcp-publisher publish; then From a5eacb23ea29bd367203ef2e413a317b3e34da47 Mon Sep 17 00:00:00 2001 From: Savio Dias Date: Thu, 15 Oct 2026 14:55:19 +0530 Subject: [PATCH 3/3] fix(ci): widen registry publish retry windows Give both retry loops more room so a slow npm propagation or a longer registry blip does not cost a whole release cycle: - npm propagation wait: 5 -> 15 minutes - publish retry backoff: 30s -> 5 minutes between attempts Both loops exit as soon as they succeed, so the normal path is unchanged (runs still finish in ~90s); the wider caps only apply when something is actually slow, and an exhausted loop still fails the job rather than publishing a version npm is not serving. Add timeout-minutes: 45 so the job is explicitly bounded instead of inheriting GitHub's 6-hour default. Worst case is ~31 min. Co-Authored-By: Claude Opus 5 --- .github/workflows/mcp-registry-publish.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/mcp-registry-publish.yml b/.github/workflows/mcp-registry-publish.yml index 037291c3..fda676b4 100644 --- a/.github/workflows/mcp-registry-publish.yml +++ b/.github/workflows/mcp-registry-publish.yml @@ -8,6 +8,7 @@ on: jobs: publish: runs-on: ubuntu-latest + timeout-minutes: 45 permissions: id-token: write contents: read @@ -58,17 +59,17 @@ jobs: run: | VERSION="$(node -p 'require("./package.json").version')" ENCODED="${PACKAGE_NAME/\//%2F}" - for attempt in $(seq 1 30); do + for attempt in $(seq 1 90); do STATUS="$(curl -sS -o /dev/null -w '%{http_code}' \ "https://registry.npmjs.org/${ENCODED}/${VERSION}" || true)" if [ "$STATUS" = "200" ]; then echo "npm is serving ${PACKAGE_NAME}@${VERSION} (attempt ${attempt})." exit 0 fi - echo "Attempt ${attempt}/30: npm returned ${STATUS} for ${VERSION}; retrying in 10s." + echo "Attempt ${attempt}/90: npm returned ${STATUS} for ${VERSION}; retrying in 10s." sleep 10 done - echo "::error::npm did not serve ${PACKAGE_NAME}@${VERSION} within 5 minutes." + echo "::error::npm did not serve ${PACKAGE_NAME}@${VERSION} within 15 minutes." exit 1 - name: Login to MCP Registry @@ -82,8 +83,8 @@ jobs: exit 0 fi if [ "$attempt" -lt 3 ]; then - echo "Publish attempt ${attempt} failed; retrying in 30s." - sleep 30 + echo "Publish attempt ${attempt} failed; retrying in 5m." + sleep 300 fi done echo "::error::Failed to publish to the MCP Registry after 3 attempts."