Skip to content

ci: npm publish workflow (trusted publishing)#24

Merged
zackkatz merged 1 commit into
mainfrom
develop
Jun 12, 2026
Merged

ci: npm publish workflow (trusted publishing)#24
zackkatz merged 1 commit into
mainfrom
develop

Conversation

@zackkatz

@zackkatz zackkatz commented Jun 12, 2026

Copy link
Copy Markdown
Member

Adds .github/workflows/npm-publish.yml: publishes @gravitykit/block-mcp on every push to main and on v* tags, via npm Trusted Publishing (OIDC) — no NPM_TOKEN secret.

  • Idempotent version guard: skips when the package.json version is already on the registry, so plugin-version tags (which version independently of the server) never re-publish, and back-to-back main+tag pushes are safe (serialized by a concurrency group).
  • Quality gate: prepublishOnly runs the Vitest suite before publish; prepare builds dist/ during npm ci.
  • Provenance: OIDC publishing generates provenance attestations automatically.

One-time manual step (after merge)

On npmjs.com → @gravitykit/block-mcp → Settings → Trusted Publisher → GitHub Actions: repository GravityKit/block-mcp, workflow npm-publish.yml. Until that's configured, publish runs will fail with an auth error; afterwards, trigger via gh workflow run npm-publish.yml (or the next push to main) to ship 2.0.1 — npm currently serves 2.0.0-beta.

Summary by CodeRabbit

  • Chores
    • Implemented automated package publishing pipeline with safeguards to prevent duplicate version releases.

💾 Build file (6ef7a87).

Publishes via npm Trusted Publishing (OIDC) — no token secret — whenever
the package.json version is not yet on the registry. Push-to-main and the
v* release tag are both triggers; a version guard makes them idempotent
and keeps the independently-versioned plugin tags from re-publishing an
already-live server version. prepublishOnly gates the publish on the
Vitest suite; OIDC publishing attaches provenance attestations.
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

A new GitHub Actions workflow publishes @gravitykit/block-mcp to npm using OIDC Trusted Publishing. The workflow runs on main pushes and version tags, sets up Node 22 with latest npm, installs dependencies, and includes a guard that prevents republishing already-available versions.

Changes

npm Trusted Publishing Workflow

Layer / File(s) Summary
Workflow triggers and OIDC permissions
.github/workflows/npm-publish.yml
Workflow metadata defines execution triggers (push to main, v* tags, manual dispatch), configures OIDC permissions for npm Trusted Publishing, and sets a concurrency group to serialize publish attempts.
Environment setup and dependency installation
.github/workflows/npm-publish.yml
Checks out repository, sets up Node.js 22, upgrades npm to latest version, and installs dependencies via npm ci.
Publish guard and conditional publish
.github/workflows/npm-publish.yml
Reads package version from package.json, queries npm registry via npm view to detect already-published versions, exports a published flag, and conditionally executes npm publish only when the version is not already present.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ci: npm publish workflow (trusted publishing)' directly and clearly summarizes the main change: adding a GitHub Actions workflow for npm publishing using trusted publishing (OIDC).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/npm-publish.yml (1)

46-47: ⚡ Quick win

Pin npm to a supported major instead of latest.

Line 47 makes the release toolchain drift over time; a future npm major can break publishing without any repo change. npm's trusted-publishing docs only require npm CLI 11.5.1+ on Node 22.14.0+, so pinning to npm@11 or npm@^11.5.1 keeps this job in the supported range without taking surprise majors from latest. (docs.npmjs.com)

Suggested change
-      - name: Update npm (trusted publishing requires npm >= 11.5)
-        run: npm install -g npm@latest
+      - name: Update npm (trusted publishing requires npm >= 11.5.1)
+        run: npm install -g npm@^11.5.1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/npm-publish.yml around lines 46 - 47, The workflow step
named "Update npm (trusted publishing requires npm >= 11.5)" currently installs
npm@latest; change the run command to pin npm to a supported major (e.g., npm@11
or npm@^11.5.1) so the release job stays within the trusted-publishing range and
avoids unexpected major upgrades—update the run string in that step accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/npm-publish.yml:
- Around line 54-62: The current guard treats any non-zero exit from the npm
view command as "not published", which lets transient/auth/network errors
proceed to publish; change the check around the npm view call so you capture its
stdout/stderr (run npm view "`@gravitykit/block-mcp`@$VERSION" version 2>&1 and
store output), then: if the command succeeded set published=true, else if the
captured output contains a definitive "not found" indicator (e.g., "404", "Not
Found", or "npm ERR! 404") set published=false, otherwise echo the error and
exit non-zero to fail fast; update the block that writes "published" to
GITHUB_OUTPUT accordingly and include a clear error log when exiting.

---

Nitpick comments:
In @.github/workflows/npm-publish.yml:
- Around line 46-47: The workflow step named "Update npm (trusted publishing
requires npm >= 11.5)" currently installs npm@latest; change the run command to
pin npm to a supported major (e.g., npm@11 or npm@^11.5.1) so the release job
stays within the trusted-publishing range and avoids unexpected major
upgrades—update the run string in that step accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b2bf1381-79c6-435b-94c0-d78097c91211

📥 Commits

Reviewing files that changed from the base of the PR and between 959860a and 6ef7a87.

📒 Files selected for processing (1)
  • .github/workflows/npm-publish.yml

Comment on lines +54 to +62
run: |
VERSION="$(node -p "require('./package.json').version")"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if npm view "@gravitykit/block-mcp@$VERSION" version >/dev/null 2>&1; then
echo "published=true" >> "$GITHUB_OUTPUT"
echo "@gravitykit/block-mcp@$VERSION is already on npm — nothing to publish."
else
echo "published=false" >> "$GITHUB_OUTPUT"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/npm-publish.yml"
echo "== File: $FILE =="
ls -la "$FILE" || true

echo
echo "== Lines 40-90 =="
nl -ba "$FILE" | sed -n '40,90p'

echo
echo "== References to 'published' and 'npm publish' =="
rg -n "published|npm publish|npm view" "$FILE" || true

echo
echo "== Entire 'guard' step (id: guard) =="
rg -n "id: guard" -n "$FILE" || true

Repository: GravityKit/block-mcp

Length of output: 274


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/npm-publish.yml"

echo "== Lines 1-120 =="
sed -n '1,120p' "$FILE" | cat -n

echo
echo "== Grep for guard/published/npm view/npm publish =="
rg -n "id: guard|published=true|published=false|npm view|npm publish" "$FILE" || true

Repository: GravityKit/block-mcp

Length of output: 3416


Fail closed on npm view errors in publish guard

In .github/workflows/npm-publish.yml (lines 52-62), the guard treats any non-zero npm view "@gravitykit/block-mcp@$VERSION" version exit as published=false, so transient/auth/registry/network errors can cause the workflow to proceed to npm publish instead of failing fast. Only the “package/version not found” case should set published=false; other errors should exit non-zero.

Suggested change
       - name: Skip when this version is already published
         id: guard
         run: |
-          VERSION="$(node -p "require('./package.json').version")"
+          PACKAGE_NAME="$(node -p "require('./package.json').name")"
+          VERSION="$(node -p "require('./package.json').version")"
           echo "version=$VERSION" >> "$GITHUB_OUTPUT"
-          if npm view "`@gravitykit/block-mcp`@$VERSION" version >/dev/null 2>&1; then
+          set +e
+          VIEW_OUTPUT="$(npm view "${PACKAGE_NAME}@${VERSION}" version 2>&1)"
+          VIEW_STATUS=$?
+          set -e
+          if [ "$VIEW_STATUS" -eq 0 ]; then
             echo "published=true" >> "$GITHUB_OUTPUT"
-            echo "`@gravitykit/block-mcp`@$VERSION is already on npm — nothing to publish."
+            echo "${PACKAGE_NAME}@${VERSION} is already on npm — nothing to publish."
+          elif printf '%s' "$VIEW_OUTPUT" | grep -q 'E404'; then
+            echo "published=false" >> "$GITHUB_OUTPUT"
           else
-            echo "published=false" >> "$GITHUB_OUTPUT"
+            printf '%s\n' "$VIEW_OUTPUT" >&2
+            exit "$VIEW_STATUS"
           fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: |
VERSION="$(node -p "require('./package.json').version")"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if npm view "@gravitykit/block-mcp@$VERSION" version >/dev/null 2>&1; then
echo "published=true" >> "$GITHUB_OUTPUT"
echo "@gravitykit/block-mcp@$VERSION is already on npm — nothing to publish."
else
echo "published=false" >> "$GITHUB_OUTPUT"
fi
run: |
PACKAGE_NAME="$(node -p "require('./package.json').name")"
VERSION="$(node -p "require('./package.json').version")"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
set +e
VIEW_OUTPUT="$(npm view "${PACKAGE_NAME}@${VERSION}" version 2>&1)"
VIEW_STATUS=$?
set -e
if [ "$VIEW_STATUS" -eq 0 ]; then
echo "published=true" >> "$GITHUB_OUTPUT"
echo "${PACKAGE_NAME}@${VERSION} is already on npm — nothing to publish."
elif printf '%s' "$VIEW_OUTPUT" | grep -q 'E404'; then
echo "published=false" >> "$GITHUB_OUTPUT"
else
printf '%s\n' "$VIEW_OUTPUT" >&2
exit "$VIEW_STATUS"
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/npm-publish.yml around lines 54 - 62, The current guard
treats any non-zero exit from the npm view command as "not published", which
lets transient/auth/network errors proceed to publish; change the check around
the npm view call so you capture its stdout/stderr (run npm view
"`@gravitykit/block-mcp`@$VERSION" version 2>&1 and store output), then: if the
command succeeded set published=true, else if the captured output contains a
definitive "not found" indicator (e.g., "404", "Not Found", or "npm ERR! 404")
set published=false, otherwise echo the error and exit non-zero to fail fast;
update the block that writes "published" to GITHUB_OUTPUT accordingly and
include a clear error log when exiting.

@zackkatz zackkatz merged commit 26fae5f into main Jun 12, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant