|
5 | 5 | # Package the npm MCP server distribution. |
6 | 6 | # Run from the repo root after all platform binaries are built. |
7 | 7 | # |
8 | | -# Usage: |
9 | 8 | # The engine is not bundled: it is fetched from the GitHub release at install |
10 | 9 | # time by bin/postinstall.js. Publish the release assets first with |
11 | | -# ./scripts/publish-release-assets.sh, or installs of this version will fail to |
12 | | -# find an engine. |
| 10 | +# ./scripts/publish-release-assets.sh - this script refuses to pack until every |
| 11 | +# asset for the pinned engine version is on the release, because an install |
| 12 | +# without them succeeds and then has nothing to run. |
13 | 13 | # |
14 | 14 | # Usage: |
15 | 15 | # ./scripts/package-npm.sh # pack only |
|
54 | 54 | echo " ✓ package tests pass" |
55 | 55 |
|
56 | 56 | # Step 3: Verify version consistency |
| 57 | +# |
| 58 | +# server.json carries the release version twice: once at the top level, and once |
| 59 | +# inside the npm entry of `packages`, which is the field the MCP Registry |
| 60 | +# resolves the tarball from. Nothing synchronises the three numbers - they are |
| 61 | +# hand-edited - so all of them are compared, not just the top-level one. A |
| 62 | +# release that bumped package.json and server.json but missed the nested version |
| 63 | +# would register a new server entry pointing at the previous tarball, and the |
| 64 | +# Registry would accept it because that older tarball exists and carries the |
| 65 | +# right mcpName. |
57 | 66 | PKG_VERSION=$(node -e "console.log(require('$PKG_DIR/package.json').version)") |
58 | 67 | SERVER_VERSION=$(node -e "console.log(require('$PKG_DIR/server.json').version)") |
| 68 | +SERVER_NPM_VERSION=$(node -e " |
| 69 | + const npm = (require('$PKG_DIR/server.json').packages || []) |
| 70 | + .find((p) => p.registryType === 'npm'); |
| 71 | + console.log(npm ? npm.version : '<no npm package entry>'); |
| 72 | +") |
59 | 73 | echo "" |
60 | | -echo "package.json version: $PKG_VERSION" |
61 | | -echo "server.json version: $SERVER_VERSION" |
| 74 | +echo "package.json version: $PKG_VERSION" |
| 75 | +echo "server.json version: $SERVER_VERSION" |
| 76 | +echo "server.json npm package: $SERVER_NPM_VERSION" |
62 | 77 |
|
| 78 | +# A mismatch here is fatal rather than a warning. The two files are published to |
| 79 | +# two different registries under one version, and a warning scrolls past in the |
| 80 | +# npm pack output - leaving npmjs.com and the MCP Registry disagreeing about what |
| 81 | +# this release is, which cannot be corrected by republishing the same version. |
63 | 82 | if [ "$PKG_VERSION" != "$SERVER_VERSION" ]; then |
64 | | - echo "WARNING: version mismatch between package.json and server.json" |
| 83 | + echo "ERROR: version mismatch between package.json ($PKG_VERSION) and server.json ($SERVER_VERSION)" >&2 |
| 84 | + exit 1 |
| 85 | +fi |
| 86 | +if [ "$PKG_VERSION" != "$SERVER_NPM_VERSION" ]; then |
| 87 | + echo "ERROR: version mismatch between package.json ($PKG_VERSION) and the npm entry in server.json ($SERVER_NPM_VERSION)" >&2 |
| 88 | + echo " The MCP Registry resolves the tarball from packages[].version, so this would" >&2 |
| 89 | + echo " publish a $PKG_VERSION server entry pointing at the $SERVER_NPM_VERSION tarball." >&2 |
| 90 | + exit 1 |
| 91 | +fi |
| 92 | + |
| 93 | +# The npm package contains no engine; every install fetches one from the release |
| 94 | +# tagged with the engine version pinned in bin/fetch-engine.js, which is |
| 95 | +# deliberately not this package's version (see the ENGINE_VERSION comment there: |
| 96 | +# a client-only patch release must not start asking for a tag nobody published). |
| 97 | +# Publishing before those assets exist produces a package that installs cleanly |
| 98 | +# and then has nothing to run. |
| 99 | +# |
| 100 | +# Every asset is probed, not just one. publish-release-assets.sh uploads the |
| 101 | +# whole staging directory in a single `gh release upload`, so a network drop or |
| 102 | +# a rate limit part-way through leaves the release with some platforms attached |
| 103 | +# and others missing - and a one-platform probe would wave that through, giving |
| 104 | +# users on the missing platforms exactly the empty install this gate exists to |
| 105 | +# prevent. The list mirrors BINARIES + WINDOWS_SIDECAR there, which is the same |
| 106 | +# set bin/fetch-engine.js resolves against. |
| 107 | +ENGINE_VERSION=$(node -e "console.log(require('$PKG_DIR/bin/fetch-engine').ENGINE_VERSION)") |
| 108 | +ENGINE_ASSETS=( |
| 109 | + "codegraph-server-darwin-arm64" |
| 110 | + "codegraph-server-darwin-x64" |
| 111 | + "codegraph-server-linux-x64" |
| 112 | + "codegraph-server-win32-x64.exe" |
| 113 | + "onnxruntime.dll" |
| 114 | +) |
| 115 | +RELEASE_BASE="https://github.com/codegraph-ai/CodeGraph/releases/download/v${ENGINE_VERSION}" |
| 116 | + |
| 117 | +echo "" |
| 118 | +echo "engine version: $ENGINE_VERSION (fetched at install time)" |
| 119 | +echo "Checking published engine assets for v${ENGINE_VERSION}..." |
| 120 | +missing_assets=0 |
| 121 | +for asset in "${ENGINE_ASSETS[@]}"; do |
| 122 | + # A binary and its checksum are separate assets and the client needs both, so |
| 123 | + # both are probed. The binaries are requested one byte at a time - presence is |
| 124 | + # the question here, and downloading ~120 MB to answer it is not worth it. |
| 125 | + if ! curl -fsSL -o /dev/null -r 0-0 "$RELEASE_BASE/$asset" \ |
| 126 | + || ! curl -fsSL -o /dev/null "$RELEASE_BASE/$asset.sha256"; then |
| 127 | + printf ' ✗ %s\n' "$asset" |
| 128 | + missing_assets=1 |
| 129 | + else |
| 130 | + printf ' ✓ %s\n' "$asset" |
| 131 | + fi |
| 132 | +done |
| 133 | + |
| 134 | +if [ "$missing_assets" -ne 0 ]; then |
| 135 | + echo "ERROR: the release v${ENGINE_VERSION} is missing engine assets (binary or .sha256)." >&2 |
| 136 | + echo " Run ./scripts/publish-release-assets.sh --publish first, or installs on those" >&2 |
| 137 | + echo " platforms will find no engine." >&2 |
| 138 | + exit 1 |
65 | 139 | fi |
| 140 | +echo " ✓ every engine asset is published for v${ENGINE_VERSION}" |
66 | 141 |
|
67 | 142 | # Step 4: Pack |
68 | 143 | echo "" |
|
0 commit comments