Skip to content

Commit d51ce8e

Browse files
anvansterclaude
andcommitted
chore(release): authenticate both registries before packing
A stale credential used to surface at the very end of a publish. The last release spent several minutes on tests, the engine-asset probe and the pack before `npm publish` failed on an expired session, and `mcp-publisher` failed after that - so every one of those steps had to be repeated. Both logins now run first. Each has to succeed for the publish to happen anyway, so checking them up front costs nothing and turns a late failure into an immediate one. Gated on --publish. Packing needs no credentials, and this script also runs as a plain build step and inside the validation gate, where prompting for a login would hang it. npm is only prompted for when `npm whoami` already fails, so an existing session is left alone; it stays interactive because the account has 2FA. The mcp-publisher login uses `gh auth token` because the MCP Registry decides which namespaces a token may publish to by calling GET /user/memberships/orgs, which needs the read:org scope. Its own device flow mints a token without that scope, GitHub answers 403, and the registry treats the 403 as "no admin orgs" rather than an error - so publishing silently degrades to io.github.<user>/* and then fails on io.github.codegraph-ai/* with a message blaming organization membership, which is not the cause. That cost a release cycle to diagnose, so the reasoning is recorded next to the call. CODEGRAPH_MCP_TOKEN overrides it for anyone preferring a PAT scoped to read:org alone, since gh's token also carries repo and workflow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017rVbt7rENTwXkdHt3Bpgb5
1 parent 489ccf1 commit d51ce8e

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

‎scripts/package-npm.sh‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,64 @@ BIN_DIR="$PKG_DIR/bin"
3131
echo "=== CodeGraph npm package builder ==="
3232
echo ""
3333

34+
# ------------------------------------------------------------------ auth
35+
#
36+
# Both registries are authenticated here, before the tests, the asset probe and
37+
# the pack - not at the point of use. Every one of those has to pass anyway, and
38+
# discovering an expired credential after them means doing them again. The last
39+
# release failed exactly there: `npm publish` ran after several minutes of work
40+
# and `mcp-publisher` after that, so a stale token surfaced at the end.
41+
#
42+
# Only for --publish. Packing needs no credentials, and this script also runs as
43+
# a plain build step, where prompting for a login would hang it.
44+
if [ "${1:-}" = "--publish" ]; then
45+
echo "Checking publish credentials..."
46+
47+
# npm's own session. Left interactive on purpose: the account has 2FA, so this
48+
# needs a human and a TTY, and that is better spent now than after the pack.
49+
if npm whoami >/dev/null 2>&1; then
50+
echo " ✓ npm authenticated as $(npm whoami)"
51+
else
52+
echo " npm: not logged in - starting login (2FA expected)"
53+
npm login || { echo " ✗ npm login failed - not packaging" >&2; exit 1; }
54+
echo " ✓ npm authenticated as $(npm whoami)"
55+
fi
56+
57+
# The MCP Registry decides which namespaces a token may publish to by calling
58+
# GET /user/memberships/orgs, which requires the read:org scope. Its own device
59+
# flow mints a token without it, GitHub answers 403, and the registry treats
60+
# that as "no admin orgs" rather than an error - so publishing silently
61+
# degrades to io.github.<user>/* and then 403s on io.github.codegraph-ai/*
62+
# with a message about organization membership that is not the actual cause.
63+
#
64+
# `gh auth token` already carries read:org. It also carries repo and workflow,
65+
# which is broader than the registry needs; a PAT limited to read:org can be
66+
# substituted by setting CODEGRAPH_MCP_TOKEN.
67+
if command -v mcp-publisher >/dev/null 2>&1; then
68+
MCP_TOKEN="${CODEGRAPH_MCP_TOKEN:-}"
69+
if [ -z "$MCP_TOKEN" ] && command -v gh >/dev/null 2>&1; then
70+
MCP_TOKEN="$(gh auth token 2>/dev/null || true)"
71+
fi
72+
if [ -n "$MCP_TOKEN" ]; then
73+
if mcp-publisher login github -token "$MCP_TOKEN" >/dev/null 2>&1; then
74+
echo " ✓ mcp-publisher authenticated"
75+
else
76+
echo " ✗ mcp-publisher login failed - not packaging" >&2
77+
echo " Check that the token has read:org and that the account is an" >&2
78+
echo " owner of the codegraph-ai organisation." >&2
79+
exit 1
80+
fi
81+
else
82+
echo " ✗ no GitHub token for mcp-publisher - not packaging" >&2
83+
echo " Run 'gh auth login', or set CODEGRAPH_MCP_TOKEN to a PAT with read:org." >&2
84+
exit 1
85+
fi
86+
else
87+
echo " ⚠ mcp-publisher not on PATH - the MCP Registry step will be skipped"
88+
fi
89+
echo ""
90+
fi
91+
3492
echo "Removing any bundled binaries (the engine is fetched at install time)..."
3593
for stale in "$BIN_DIR"/codegraph-server-* "$BIN_DIR/onnxruntime.dll"; do
3694
if [ -e "$stale" ]; then

0 commit comments

Comments
 (0)