Skip to content

chore: add automated npm release tooling - #72

Closed
hideokamoto wants to merge 2 commits into
masterfrom
claude/optimize-npm-release-018SnQEQ9aaTaZYBNVtZLQdW
Closed

chore: add automated npm release tooling#72
hideokamoto wants to merge 2 commits into
masterfrom
claude/optimize-npm-release-018SnQEQ9aaTaZYBNVtZLQdW

Conversation

@hideokamoto

@hideokamoto hideokamoto commented Nov 16, 2025

Copy link
Copy Markdown
Collaborator
  • Add np package for interactive releases
  • Add prepublishOnly script to run tests/lint/build before publish
  • Add GitHub Actions workflow to auto-publish on tag push
  • Configure .nprc for release settings

Summary by CodeRabbit

  • Chores

    • Set up automated publishing on version-tag pushes and added release helper scripts to enforce lint/build/test before publish
    • Added release configuration to streamline and guard the publish process
  • Documentation

    • Added release workflow, first-time setup for maintainers, and release-related guidance to the README
  • Security

    • Added release security guidance and checklist covering verification, token handling, and incident response

- Add np package for interactive releases
- Add prepublishOnly script to run tests/lint/build before publish
- Add GitHub Actions workflow to auto-publish on tag push
- Configure .nprc for release settings
@coderabbitai

coderabbitai Bot commented Nov 16, 2025

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds automated npm publishing: a GitHub Actions workflow that runs on pushed tags matching v* to lint, build, test, verify artifacts, and publish to npm; introduces .nprc for np configuration; updates package.json with prepublish and release scripts; and adds release/security documentation.

Changes

Cohort / File(s) Summary
CI/CD workflow
.github/workflows/publish.yml
New GitHub Actions workflow triggered on tag pushes v*; checks tag format, sets up Node.js, installs deps, runs audit/lint/build/test, verifies dist and version alignment, publishes to npm with provenance using NPM_TOKEN, then creates a GitHub Release. Uses least-privilege permissions.
Release tooling & config
.nprc, package.json
Adds .nprc JSON config (yarn:false, anyBranch:false, 2fa:false, contents:".", cleanup:true). Updates package.json scripts: prepublishOnly to run lint/build/test and release to run np; adds np as a devDependency.
Documentation & security
README.md, SECURITY.md
Adds Release workflow and First-time Setup sections to README.md and a new SECURITY.md describing release-time protections, recommended settings, incident response steps, and a release checklist.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Maintainer
  participant GH as GitHub (tags)
  participant Actions as GitHub Actions (publish workflow)
  participant Registry as npm

  Dev->>GH: Push tag "vX.Y.Z"
  GH->>Actions: Trigger on tag push (v*)
  rect rgb(220,235,255)
    Actions->>Actions: Checkout + verify tag format
    Actions->>Actions: Setup Node.js & npm registry
    Actions->>Actions: Install deps, run audit (warn on high), lint, build, test
    Actions->>Actions: Verify dist artifacts and required files
    Actions->>Actions: Ensure tag version == package.json version
  end
  rect rgb(200,255,200)
    Actions->>Registry: Publish package (provenance, public) using NPM_TOKEN
    Registry-->>Actions: Publish result
  end
  Actions->>GH: Create GitHub Release (script)
  GH-->>Dev: Release created / publish status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to .github/workflows/publish.yml steps that verify tag format, artifact checks, and version alignment.
  • Validate NPM_TOKEN usage, provenance flags, and permissions (contents read, id-token write).
  • Confirm prepublishOnly and release scripts in package.json and .nprc settings match intended CI behavior.
  • Review added docs (README.md, SECURITY.md) for accuracy against workflow behavior.

Poem

🐇 I hopped a tag into the sky,
Linted, built, then watched it fly,
Tests passed, the package shone so bright,
Provenance stamped, released by night,
A tiny rabbit cheers the publish rite! 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding automated npm release tooling including the np package, GitHub Actions workflow, prepublishOnly script, and .nprc configuration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/optimize-npm-release-018SnQEQ9aaTaZYBNVtZLQdW

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

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @hideokamoto, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request automates and standardizes the npm package release process by incorporating the 'np' tool and establishing mandatory pre-publish checks. This ensures that every new package version is thoroughly validated before being published, enhancing the overall reliability and consistency of releases.

Highlights

  • Release Tooling Integration: Integrated the 'np' package to streamline the interactive release process for publishing new versions to npm.
  • Pre-publish Checks: Introduced a 'prepublishOnly' script in 'package.json' to automatically run linting, building, and testing before any package publication, ensuring quality and consistency.
  • np Configuration: Added a '.nprc' configuration file to customize 'np's behavior, specifically disabling 'yarn', 'anyBranch', and '2fa', while enabling 'cleanup' and setting 'contents' to the current directory.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/publish.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces tooling for automated npm releases using the np package, which is a great step towards streamlining the release process. The configuration includes adding np as a dev dependency, setting up scripts in package.json, and providing an .nprc configuration file.

My review has identified a critical security issue and a minor redundancy:

  • Security: The .nprc file disables two-factor authentication (2FA) for publishing, which is a significant security risk. I've left a comment with a suggestion to address this.
  • Redundancy: The prepublishOnly script runs tests, which np also does by default, leading to tests running twice. I've suggested a change to avoid this.

Additionally, the pull request description mentions adding a GitHub Actions workflow for auto-publishing on tag push, but this file seems to be missing from the changes. Please ensure it's included to complete the automated release setup.

Comment thread .nprc
{
"yarn": false,
"anyBranch": false,
"2fa": false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Disabling two-factor authentication (2FA) for publishing ("2fa": false) is a critical security risk. If your npm credentials are ever compromised, an attacker could publish malicious versions of your package. It is strongly recommended to enable 2FA on your npm account and require it for publishing.

  "2fa": true,

Comment thread package.json
"format": "biome format --write .",
"prepare": "husky"
"prepare": "husky",
"prepublishOnly": "npm run lint && npm run build && npm test",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The np tool runs npm test by default before publishing. Since your prepublishOnly script also runs npm test, the tests will be executed twice during a release. To avoid this redundancy, I suggest removing npm test from this script and letting np handle the testing step.

Suggested change
"prepublishOnly": "npm run lint && npm run build && npm test",
"prepublishOnly": "npm run lint && npm run build",

@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)
.github/workflows/publish.yml (1)

26-36: Consider consolidating pre-publish steps with npm hooks.

The workflow manually runs npm run lint, npm run build, and npm test before publishing. These are also defined in the prepublishOnly hook in package.json (line 33). The GitHub Actions workflow does not use the release script or invoke the prepublishOnly hook; instead, it duplicates the logic.

This duplication can lead to inconsistency if one set of commands is updated without the other. Consider simplifying the workflow to leverage the release process defined in package.json:

- name: Install dependencies
  run: npm ci

- name: Release
  run: npm run release
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
    NPM_PUBLISH_TOKEN: ${{ secrets.NPM_TOKEN }}

Alternatively, if you prefer explicit control, document why the workflow does not use the release script.

Note: The np tool has its own hooks and configuration; verify that --provenance --access public flags are compatible with np's publish command. You may need to add these flags to .nprc or invoke np with additional CLI arguments.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fd3247 and 457036d.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/publish.yml (1 hunks)
  • .nprc (1 hunks)
  • package.json (3 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
package.json

[error] 16-19: Formatter would have adjusted package.json formatting (files array). Run 'biome format .' to fix.

🔇 Additional comments (5)
package.json (2)

33-34: Verify prepublishOnly hook covers all pre-release validation.

The prepublishOnly script properly chains commands with && to ensure that failure at any step (lint, build, or test) prevents publication. However, this is also replicated in the GitHub Actions workflow, which runs the same commands again.

Confirm:

  1. Is the redundant test/lint/build in the CI workflow intentional, or should the workflow use npm run release to leverage the prepublishOnly hook?
  2. The release script invokes np, which has its own hooks and logic—verify that np's configuration in .nprc aligns with the intended workflow.

Consider whether the GitHub Actions workflow should be simplified to invoke npm run release instead of manually running individual scripts, or document why the explicit separation is preferred.


49-49: No issues found — the np package is current and secure.

The latest version of the np package is 10.2.0, which matches the version specified in package.json. No security advisories have been identified for this package.

.github/workflows/publish.yml (3)

1-6: Verify tag naming convention is enforced.

The workflow triggers on tags matching the pattern v*, which is a common convention for semantic versioning. However, there is no validation that the tag follows semantic versioning (e.g., v1.2.3). A malformed tag could trigger the workflow and result in an incorrect package version.

Confirm that:

  1. Your repository has branch protection rules or tagging conventions that enforce valid semantic version tags
  2. The np tool in .nprc is configured to validate tag format before publishing

Alternatively, consider adding a validation step to ensure the tag matches a strict semver pattern:

- name: Validate tag format
  run: |
    if [[ ! "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
      echo "Invalid tag format: ${{ github.ref }}"
      exit 1
    fi

11-13: LGTM on minimal permissions.

The permissions are properly scoped to contents: read and id-token: write. The latter is necessary for npm's provenance feature, which is good security practice. The settings follow the principle of least privilege.


38-41: Verify NPM_TOKEN secret is configured and that provenance settings are compatible with np.

The workflow uses --provenance and --access public flags for npm publish. These are standard npm CLI flags, but verify that they work correctly with the np tool and that np is not being invoked directly (since the current workflow uses npm publish).

Confirm:

  1. The NPM_TOKEN secret is configured in the GitHub repository settings
  2. If np is meant to be used (as defined in the release script), verify that the flags --provenance and --access public are compatible with np's publish command, or move them to .nprc

You may also want to verify that the Node.js authentication is properly set up. Consider testing this workflow in a staging environment or using GitHub's workflow visualization to debug any issues.

Also, note that registry-url is set in the Node.js setup (line 23), which should handle npm authentication correctly when NODE_AUTH_TOKEN is provided.

Comment on lines +38 to +41
- name: Publish to npm
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

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 | 🔴 Critical

Critical: Missing NPM_CONFIG_PROVENANCE environment variable for provenance signing.

npm provenance requires the NPM_CONFIG_PROVENANCE environment variable set to true in the GitHub Actions workflow, in addition to the --provenance flag. Without this environment variable, provenance signing may not be properly configured.

Add the missing environment variable:

  - name: Publish to npm
    run: npm publish --provenance --access public
    env:
      NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+     NPM_CONFIG_PROVENANCE: true

Additionally, npm classic token creation is now disabled as of November 19, 2025, and you should migrate to trusted publishing or granular access tokens to avoid disruption. Consider migrating from long-lived tokens to trusted publishers which use short-lived, scoped credentials that eliminate the need for long-lived tokens and reduce security risks.

🤖 Prompt for AI Agents
.github/workflows/publish.yml around lines 38 to 41: the Publish to npm step is
missing the NPM_CONFIG_PROVENANCE environment variable required for npm
provenance signing; add NPM_CONFIG_PROVENANCE set to "true" to the step's env
block so the --provenance flag works as intended, and keep NODE_AUTH_TOKEN
as-is; additionally, plan to migrate from classic long-lived tokens to trusted
publishers or granular access tokens and update workflow secrets accordingly.

Comment thread .nprc
Comment on lines +1 to +7
{
"yarn": false,
"anyBranch": false,
"2fa": false,
"contents": ".",
"cleanup": true
}

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

Disable 2FA requirement in .nprc introduces security risk.

The setting "2fa": false disables npm's 2-factor authentication verification for releases. This weakens the security posture when publishing packages, as it removes an important protection against account compromise or unauthorized releases.

Enable 2FA verification to strengthen package security:

{
  "yarn": false,
  "anyBranch": false,
-  "2fa": false,
+  "2fa": true,
  "contents": ".",
  "cleanup": true
}

If there are operational reasons for disabling 2FA here, consider implementing compensating controls such as:

  • GitHub branch protections requiring approval before tag pushes
  • IP allow-lists on the GitHub organization or npm account
  • Audit logging and alerts on all releases
📝 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
{
"yarn": false,
"anyBranch": false,
"2fa": false,
"contents": ".",
"cleanup": true
}
{
"yarn": false,
"anyBranch": false,
"2fa": true,
"contents": ".",
"cleanup": true
}
🤖 Prompt for AI Agents
.nprc lines 1-7: the config currently sets "2fa": false which disables npm
two-factor auth for releases; change this to enable 2FA by setting "2fa": true
(or remove the key so the default enforces 2FA) and update release docs to
require personal or org-level 2FA for any account that publishes; if there are
operational constraints that prevent enabling 2FA, implement compensating
controls such as branch protections preventing direct tag pushes, IP allow-lists
for CI/publish runners, and alerting/audit logging for all publish events and
document those exceptions.

Comment thread package.json
Comment on lines +16 to +19
"files": [
"dist",
"src"
],

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 | 🔴 Critical

Fix formatting failure in files array.

The pipeline reports that Biome formatter would adjust the formatting of the files array. The array is currently formatted on multiple lines, but Biome expects a different format.

Run biome format . to fix the formatting issue before merging:

biome format .

Alternatively, if you want to manually apply the fix, use the biome format --write . command or reformat inline:

-  "files": [
-    "dist",
-    "src"
-  ],
+  "files": ["dist", "src"],
🧰 Tools
🪛 GitHub Actions: CI

[error] 16-19: Formatter would have adjusted package.json formatting (files array). Run 'biome format .' to fix.

🤖 Prompt for AI Agents
In package.json around lines 16 to 19, the "files" array is formatted across
multiple lines which the Biome formatter will change; run "biome format ." (or
"biome format --write .") to reformat the file so the files array matches the
project's Biome style, or manually reformat the array to the expected
single-line style and commit the updated package.json.

- Add environment protection requiring manual approval
- Verify tag format and version matching
- Validate package-lock.json integrity
- Audit dependencies before publish
- Verify build artifacts completeness
- Pin GitHub Actions to SHA hashes
- Add comprehensive security documentation

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

♻️ Duplicate comments (1)
.github/workflows/publish.yml (1)

93-96: [DUPLICATE] Add NPM_CONFIG_PROVENANCE environment variable.

npm provenance requires the NPM_CONFIG_PROVENANCE environment variable to be set to true in addition to the --provenance flag. Without this environment variable, provenance signing may not be properly configured.

Apply this diff:

  - name: Publish to npm
    run: npm publish --provenance --access public
    env:
      NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+     NPM_CONFIG_PROVENANCE: true
🧹 Nitpick comments (3)
SECURITY.md (1)

44-50: Add language specification to all fenced code blocks.

Lines 44, 53, 61, 69, 104, and 127 contain fenced code blocks without a language identifier. Add bash, json, or other appropriate language tags for consistency with markdown best practices and linter requirements.

Apply this diff to the first instance (line 44) and repeat for other code blocks:

- ```
+ ```bash
  Settings → Branches → Add rule
.github/workflows/publish.yml (1)

93-96: Plan migration away from classic npm tokens.

npm classic token creation is now disabled and existing classic tokens will be revoked on November 19, 2025. Migrate to trusted publishing or granular access tokens to avoid disruption. While the current workflow uses NODE_AUTH_TOKEN with a long-lived secret, consider migrating to trusted publishing, which eliminates security risks by using short-lived, workflow-specific credentials that are automatically managed and cannot be extracted.

README.md (1)

159-163: Add language specification to fenced code blocks.

Lines 159 and 166 contain fenced code blocks without a language identifier. These should be marked as bash to match markdown linting standards.

Apply this diff:

  1. **Configure npm-publish environment** in GitHub:
-    ```
+    ```bash
     Settings → Environments → New environment: "npm-publish"

And similarly for line 166:

  2. **Add NPM_TOKEN secret**:
-    ```
+    ```bash
     Settings → Secrets → New repository secret
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 457036d and 4aebcf0.

📒 Files selected for processing (3)
  • .github/workflows/publish.yml (1 hunks)
  • README.md (1 hunks)
  • SECURITY.md (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
SECURITY.md

44-44: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


53-53: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


61-61: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


69-69: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


104-104: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


127-127: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

README.md

159-159: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


166-166: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

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.

2 participants