Skip to content

Prepare npm publishing: package.json hygiene + release workflow#10

Merged
cmm-cmm merged 1 commit into
mainfrom
claude/readme-documentation-expansion-1j8wa1
Jul 12, 2026
Merged

Prepare npm publishing: package.json hygiene + release workflow#10
cmm-cmm merged 1 commit into
mainfrom
claude/readme-documentation-expansion-1j8wa1

Conversation

@cmm-cmm

@cmm-cmm cmm-cmm commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

Gets forge-select ready to publish to npm (name is currently unclaimed — verified npm view forge-select returns 404). This PR sets up the automation; it does not publish anything by itself, since publishing requires an NPM_TOKEN repository secret that only a maintainer with npm credentials can create.

  • package.json hygiene: adds homepage, bugs, engines (node >=18), and publishConfig.access: "public". Adds a prepublishOnly script (typecheck && test && build) so a broken package can never ship even via manual npm publish.
  • .github/workflows/release.yml: publishes to npm with provenance on push of a vX.Y.Z tag (or manual workflow_dispatch). Verifies the tag matches package.json's version before running typecheck/test/build/publish — a mismatched tag fails loudly instead of publishing the wrong version.
  • README: npm version / CI / license badges.
  • CONTRIBUTING.md: a "Releasing" section documenting the tag-based release flow and the required NPM_TOKEN secret (npm Automation token, so CI doesn't need interactive 2FA).

Test plan

  • npm run typecheck, npm test (36/36), npm run build all green.
  • npm pack --dry-run inspected: tarball ships exactly dist/, styles/, LICENSE, README.md, package.json — 12 files, 55.6 kB packed / 250.8 kB unpacked. No source, tests, docs, or site files leak into the published package.
  • After merge, a maintainer needs to: add the NPM_TOKEN secret, then push tag v0.1.0 (or open a GitHub Release for it) to trigger the first publish. Documented in CONTRIBUTING.md.

Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added automated npm publishing for version tags and manual releases, including provenance support.
    • Added pre-publish validation to run type checks, tests, and builds.
    • Added package homepage, issue tracker, Node.js version requirement, and public publishing metadata.
  • Documentation

    • Documented the maintainer release process and publishing requirements.
    • Added npm, CI, and license badges to the README.
    • Updated the changelog with release automation details.

- package.json: add homepage, bugs, engines, publishConfig.access,
  and a prepublishOnly script (typecheck + test + build) so a broken
  package can never be published
- .github/workflows/release.yml: publishes to npm with provenance on
  vX.Y.Z tags (or manual dispatch), verifying the tag matches
  package.json's version before running typecheck/test/build/publish
- README: npm version, CI, and license badges
- CONTRIBUTING.md: releasing steps and the NPM_TOKEN secret this
  workflow requires
- Verified with npm pack --dry-run: tarball ships exactly dist/,
  styles/, LICENSE, README.md, package.json (12 files, 55.6 kB)
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds npm package metadata, automated tag-based or manual publishing with provenance and verification, maintainer release instructions, changelog entries, and README badges.

Changes

npm release automation

Layer / File(s) Summary
Package publishing contract
package.json
Adds npm distribution metadata and a prepublishOnly script that runs type checking, tests, and the build.
Verified release workflow
.github/workflows/release.yml
Adds tag and manual triggers, Node setup, tag/version validation, verification steps, and provenance-enabled npm publishing.
Release process documentation
CHANGELOG.md, CONTRIBUTING.md, README.md
Documents the release process and adds npm, CI, and license badges.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Maintainer
  participant GitHubActions
  participant packageJson
  participant npm
  Maintainer->>GitHubActions: Push vX.Y.Z tag or start manual dispatch
  GitHubActions->>packageJson: Verify tag version matches package version
  GitHubActions->>GitHubActions: Run typecheck, tests, and build
  GitHubActions->>npm: Publish package with provenance
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preparing the package for npm publishing and adding the release workflow.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/readme-documentation-expansion-1j8wa1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@cmm-cmm
cmm-cmm merged commit a58330f into main Jul 12, 2026
3 checks passed

@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: 3

🧹 Nitpick comments (1)
CONTRIBUTING.md (1)

54-54: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Prefer Trusted Publishing over NPM_TOKEN. npm automation/granular tokens with 2FA bypass are being phased out, and this release workflow already uses id-token: write plus npm publish --provenance; update the contributing docs to point at OIDC trusted publishing instead of a long-lived token.

🤖 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 `@CONTRIBUTING.md` at line 54, Update the release setup guidance in
CONTRIBUTING.md to remove the NPM_TOKEN secret requirement and direct
maintainers to configure npm OIDC Trusted Publishing for the existing workflow,
which already uses id-token: write and npm publish --provenance.
🤖 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/release.yml:
- Line 7: Restrict the workflow_dispatch release path in the release workflow so
manual runs cannot publish from arbitrary branches. Require a protected release
environment or validate that the selected ref is a v*.*.* tag before executing
the publishing steps, while preserving the existing tag/version guard for other
triggers.
- Around line 21-24: Disable npm package-manager caching in the release
workflow’s actions/setup-node@v4 configuration by setting package-manager-cache
to false, while preserving the Node.js version and publish behavior.

In `@CHANGELOG.md`:
- Line 17: Update the release workflow bullet in CHANGELOG.md to clarify that
tag-triggered publishes additionally require tag/version validation, while
manual dispatch publishes do not perform this check.

---

Nitpick comments:
In `@CONTRIBUTING.md`:
- Line 54: Update the release setup guidance in CONTRIBUTING.md to remove the
NPM_TOKEN secret requirement and direct maintainers to configure npm OIDC
Trusted Publishing for the existing workflow, which already uses id-token: write
and npm publish --provenance.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d5709019-ae7d-485e-8d79-21af4b22de7c

📥 Commits

Reviewing files that changed from the base of the PR and between 465d553 and e3621c6.

📒 Files selected for processing (5)
  • .github/workflows/release.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • package.json

push:
tags:
- "v*.*.*"
workflow_dispatch:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files .github/workflows/release.yml
echo '---'
cat -n .github/workflows/release.yml | sed -n '1,220p'

Repository: cmm-cmm/ForgeSelect

Length of output: 1699


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect any workflow-level safeguards or related release docs if present.
rg -n "workflow_dispatch|release|publish|NPM_TOKEN|cache" .github/workflows . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' | sed -n '1,240p'

Repository: cmm-cmm/ForgeSelect

Length of output: 5288


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate any docs or scripts that describe the intended release trigger/ref policy.
fd -a -t f -H 'release*' .
fd -a -t f -H 'publish*' .
fd -a -t f -H '.github/workflows/*.yml' .github/workflows

Repository: cmm-cmm/ForgeSelect

Length of output: 206


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If the workflow uses checkout or cache actions, inspect those exact lines.
python3 - <<'PY'
from pathlib import Path
p = Path('.github/workflows/release.yml')
for i, line in enumerate(p.read_text().splitlines(), 1):
    if any(k in line for k in ['actions/checkout', 'actions/cache', 'npm', 'workflow_dispatch', 'release', 'publish', 'environment', 'ref']):
        print(f"{i}: {line}")
PY

Repository: cmm-cmm/ForgeSelect

Length of output: 537


Restrict manual publishing to a protected release ref. .github/workflows/release.yml:7,30-31,46-49 Manual runs skip the tag/version guard and can publish from any selected branch with NPM_TOKEN; gate this behind a protected environment or require a v*.*.* tag before publishing.

🤖 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/release.yml at line 7, Restrict the workflow_dispatch
release path in the release workflow so manual runs cannot publish from
arbitrary branches. Require a protected release environment or validate that the
selected ref is a v*.*.* tag before executing the publishing steps, while
preserving the existing tag/version guard for other triggers.

Comment on lines +21 to +24
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files .github/workflows/release.yml
echo "----"
cat -n .github/workflows/release.yml

Repository: cmm-cmm/ForgeSelect

Length of output: 1700


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Workflow files:"
git ls-files .github/workflows

echo "---- npm cache usage ----"
rg -n --glob '.github/workflows/*.yml' 'cache:\s*npm|actions/setup-node@v4|registry-url|persist-credentials|id-token' .github/workflows

Repository: cmm-cmm/ForgeSelect

Length of output: 1003


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- ci.yml ----"
cat -n .github/workflows/ci.yml

echo "---- pages.yml ----"
cat -n .github/workflows/pages.yml

Repository: cmm-cmm/ForgeSelect

Length of output: 2187


🌐 Web query:

actions/setup-node cache poisoning elevated privileges GitHub recommends disabling package manager caching workflow permissions

💡 Result:

GitHub recommends disabling automatic package manager caching in workflows with elevated privileges or access to sensitive information to mitigate the risk of cache poisoning [1]. In versions of the actions/setup-node action where automatic caching is enabled (specifically for npm when defined in package.json), the action may restore dependencies from a cache that could be influenced by previous, less secure workflow runs [2][1]. In a cache poisoning scenario, an attacker with the ability to trigger a workflow can inject malicious content into the shared cache [3][4]. When a subsequent, privileged workflow (such as a release or publishing pipeline) restores this cache, it may use the compromised artifacts, potentially leading to supply chain attacks or the exfiltration of secrets and credentials [2][3][4]. To prevent this vulnerability, you should explicitly disable automatic caching in these sensitive workflows by setting the package-manager-cache input to false in your workflow file [5][3][1]: - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: '20' package-manager-cache: false This configuration is particularly critical for workflows that handle OIDC tokens, production secrets, or the publishing of release artifacts [5][4]. Additionally, following the principle of least privilege by restricting GITHUB_TOKEN permissions is a key practice for reducing the overall attack surface in GitHub Actions [4].

Citations:


Disable npm caching in the publish workflow.
cache: npm restores shared package-manager cache data before npm ci, and this job has OIDC plus npm publish credentials. Keep automatic caching in unprivileged CI jobs, or disable it here with package-manager-cache: false.

🧰 Tools
🪛 zizmor (1.26.1)

[error] 21-21: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): this step

(cache-poisoning)

🤖 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/release.yml around lines 21 - 24, Disable npm
package-manager caching in the release workflow’s actions/setup-node@v4
configuration by setting package-manager-cache to false, while preserving the
Node.js version and publish behavior.

Source: Linters/SAST tools

Comment thread CHANGELOG.md
### Added

- `CHANGELOG.md`, `LICENSE`, `SECURITY.md`, and `CONTRIBUTING.md`.
- `.github/workflows/release.yml`: publishes to npm with provenance on `vX.Y.Z` tags (or manual dispatch), gated on typecheck/test/build and a tag/version match check.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clarify that tag/version validation is push-only.

The workflow gates the version comparison with github.event_name == 'push'; manual dispatch runs do not perform that check. Reword this bullet to say that tag-triggered publishes additionally require a tag/version match.

🤖 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 `@CHANGELOG.md` at line 17, Update the release workflow bullet in CHANGELOG.md
to clarify that tag-triggered publishes additionally require tag/version
validation, while manual dispatch publishes do not perform this check.

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