fix(release): publish the MCP registry entry after the release is public

v0.10.3 published, then failed:

    MCPB package '...codebase-memory-mcp-darwin-amd64.mcpb' is not publicly
    accessible (status: 404)

publish-mcp-registry and publish-final both needed only publish-registries, so
they ran in PARALLEL — and publish-final is the job that un-drafts the release.
The registry validates every package URL it is handed by fetching it, and a
draft release's assets are not publicly readable. The registry lost the race by
five seconds; the identical URL served 200 once the release went public, and the
job passed on a plain re-run.

The registry now needs publish-final. This keeps the documented intent exactly:
publish-final still does NOT depend on the registry, so a registry-preview
outage can never block shipping — the registry simply runs after the assets it
validates exist to the outside world.

The gate-chain contract now pins BOTH directions, because either one alone is a
bug: the registry must depend on publish-final, and publish-final must never
depend on the registry. Verified by reverting the ordering — the contract goes
red with the exact v0.10.3 failure, and green again with it restored.

This is the second latent defect the .mcpb path produced on its first real
release (after the security-strings audit treating a manifest as a binary).
Both were invisible until a stable release ran; an end-to-end bundle gate is
worth adding before the next one.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin Vogel committed 2026-08-13 11:00:51 +02:00
1 parent 1649fa8344
commit e4cb304a11
2 files changed
+39 -2

No files matched your search

+14 -2
View File
@@ -409,11 +409,23 @@ jobs:
# product, the registry entry is metadata. A registry-preview outage
# must never block shipping. Re-run this job alone to retry — it does
# not touch npm/PyPI, so retries are safe.
#
# It DOES depend on publish-final, which is the job that un-drafts the
# release. Both used to need only publish-registries, so they raced: the
# registry validates every package URL it is given by fetching it, and a
# DRAFT release's assets are not publicly readable. In v0.10.3 the registry
# ran 5s before the un-draft and was told its own .mcpb URL was a 404:
# MCPB package '...codebase-memory-mcp-darwin-amd64.mcpb' is not publicly
# accessible (status: 404)
# The same URL served 200 once the release went public, and the job passed on
# a plain re-run. Depending on publish-final keeps the documented intent
# exactly — the registry still cannot block the release, it just runs after
# the assets it validates actually exist to the outside world.
publish-mcp-registry:
needs: [publish-registries]
needs: [publish-registries, publish-final]
# Skipped for prereleases: the MCP Registry has no channel concept, so an
# RC would present itself as the current version to every registry consumer.
if: ${{ !cancelled() && !failure() && needs.publish-registries.result == 'success' && !contains(inputs.version, '-') }}
if: ${{ !cancelled() && !failure() && needs.publish-registries.result == 'success' && needs.publish-final.result == 'success' && !contains(inputs.version, '-') }}
runs-on: ubuntu-latest
permissions:
id-token: write # GitHub OIDC auth to the MCP Registry