Skip to content

P1: NPM publish pipeline + package contents control#40

Merged
Kinin-Code-Offical merged 1 commit intomainfrom
p1/npm-publish-pipeline
Dec 22, 2025
Merged

P1: NPM publish pipeline + package contents control#40
Kinin-Code-Offical merged 1 commit intomainfrom
p1/npm-publish-pipeline

Conversation

@Kinin-Code-Offical
Copy link
Owner

@Kinin-Code-Offical Kinin-Code-Offical commented Dec 22, 2025

Closes #23

Summary:

  • Add npm publish workflow triggered on GitHub releases or manual dispatch.
  • Constrain npm package contents via package.json files whitelist.

Tests:

  • npm ci (PASS)
  • npm run lint (PASS)
  • npm test (PASS)
  • npm run build (PASS)

Rollback:

  • Revert this commit to remove npm publish automation and files whitelist.

Summary by Sourcery

Add an automated npm publish workflow and restrict the published package contents.

Build:

  • Restrict published npm package contents using a package.json files whitelist.

CI:

  • Introduce a GitHub Actions workflow to publish the package to npm on release publication or manual dispatch, including version/tag validation and build before publish.

Copilot AI review requested due to automatic review settings December 22, 2025 02:19
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 22, 2025

Reviewer's Guide

Adds an automated GitHub Actions workflow to publish the package to npm on releases/manual dispatch, and restricts the published package contents via a package.json files whitelist.

Sequence diagram for GitHub release-triggered npm publish workflow

sequenceDiagram
  actor Maintainer
  participant GitHub
  participant Workflow_npm_publish
  participant Node_environment
  participant npm_registry

  Maintainer->>GitHub: Create release with tag vX.Y.Z
  GitHub-->>Workflow_npm_publish: Trigger release published event
  Workflow_npm_publish->>Workflow_npm_publish: Set RELEASE_TAG from github.event.release.tag_name
  Workflow_npm_publish->>GitHub: actions_checkout ref RELEASE_TAG
  Workflow_npm_publish->>Node_environment: actions_setup_node with node 22.x and npm registry
  Workflow_npm_publish->>Node_environment: npm ci
  Workflow_npm_publish->>Node_environment: Check Version script
  Node_environment-->>Workflow_npm_publish: Validate tag matches package.json version
  Workflow_npm_publish->>Node_environment: npm run build
  Workflow_npm_publish->>npm_registry: npm publish --access public using NODE_AUTH_TOKEN
  npm_registry-->>Workflow_npm_publish: Publish result
  Workflow_npm_publish-->>Maintainer: Workflow status and npm publish outcome
Loading

File-Level Changes

Change Details Files
Restrict npm package contents to a minimal, controlled set of artifacts for publication.
  • Add a files whitelist in the package manifest including only build output and key documentation/licensing files
  • Ensure only dist output and top-level docs are included in the published npm tarball
package.json
Introduce a GitHub Actions workflow to build and publish the package to npm on tagged releases or manual dispatch with tag validation.
  • Add workflow triggers for GitHub release publishing and manual workflow_dispatch with a tag input
  • Check out the repository at the specified release tag for reproducible builds
  • Set up Node.js 22 with npm registry configuration and caching
  • Install dependencies and run a build step prior to publishing
  • Validate that the npm package.json version matches the Git tag before publishing
  • Publish the package to npm using an auth token secret with public access
.github/workflows/npm-publish.yml

Assessment against linked issues

Issue Objective Addressed Explanation
#23 Implement an automated NPM publish pipeline (GitHub Actions workflow) to publish the package on releases or manual trigger.
#23 Restrict/control the contents of the published NPM package via package.json configuration.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In the env definition for RELEASE_TAG, the expression uses inputs.tag, which is not a valid context for workflow_dispatch; you likely want github.event.inputs.tag instead so that manual dispatch reads the provided tag correctly.
  • Consider adding a npm pack --dry-run step before npm publish to validate the files whitelist and resulting tarball contents, which will help catch accidental omissions from the package.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the `env` definition for `RELEASE_TAG`, the expression uses `inputs.tag`, which is not a valid context for `workflow_dispatch`; you likely want `github.event.inputs.tag` instead so that manual dispatch reads the provided tag correctly.
- Consider adding a `npm pack --dry-run` step before `npm publish` to validate the `files` whitelist and resulting tarball contents, which will help catch accidental omissions from the package.

## Individual Comments

### Comment 1
<location> `.github/workflows/npm-publish.yml:20-25` </location>
<code_context>
+    permissions:
+      contents: read
+    env:
+      RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.event.release.tag_name }}
+    steps:
+      - uses: actions/checkout@v4
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Tighten validation of `RELEASE_TAG` when triggered via `workflow_dispatch` to avoid publishing from an arbitrary ref.

Since `inputs.tag` is user-supplied, this lets a `workflow_dispatch` caller point checkout at any ref name they choose, not necessarily a real tag or one following your scheme. That means you can publish from a commit that isn’t actually referenced by a Git tag, even though you later compare the version to `package.json`. To avoid this, either validate that `inputs.tag` corresponds to an existing tag (e.g. `git rev-parse --verify refs/tags/$TAG`) or rely on `github.ref_name` only for release events and restrict `workflow_dispatch` to selecting from existing tags.

```suggestion
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Validate release tag exists (workflow_dispatch only)
        if: github.event_name == 'workflow_dispatch'
        run: |
          git rev-parse --verify "refs/tags/${RELEASE_TAG}"

      - name: Check out release tag
        run: |
          git checkout "refs/tags/${RELEASE_TAG}"

      - name: Use Node.js 22.x
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +20 to +25
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_TAG }}

- name: Use Node.js 22.x
Copy link

Choose a reason for hiding this comment

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

suggestion (bug_risk): Tighten validation of RELEASE_TAG when triggered via workflow_dispatch to avoid publishing from an arbitrary ref.

Since inputs.tag is user-supplied, this lets a workflow_dispatch caller point checkout at any ref name they choose, not necessarily a real tag or one following your scheme. That means you can publish from a commit that isn’t actually referenced by a Git tag, even though you later compare the version to package.json. To avoid this, either validate that inputs.tag corresponds to an existing tag (e.g. git rev-parse --verify refs/tags/$TAG) or rely on github.ref_name only for release events and restrict workflow_dispatch to selecting from existing tags.

Suggested change
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_TAG }}
- name: Use Node.js 22.x
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate release tag exists (workflow_dispatch only)
if: github.event_name == 'workflow_dispatch'
run: |
git rev-parse --verify "refs/tags/${RELEASE_TAG}"
- name: Check out release tag
run: |
git checkout "refs/tags/${RELEASE_TAG}"
- name: Use Node.js 22.x

@Kinin-Code-Offical Kinin-Code-Offical merged commit 1acadcd into main Dec 22, 2025
10 checks passed
@Kinin-Code-Offical Kinin-Code-Offical deleted the p1/npm-publish-pipeline branch December 22, 2025 02:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds automated npm package publishing functionality and controls what gets included in the published package. The workflow is triggered either automatically when a GitHub release is published or manually via workflow dispatch, and includes version validation to ensure package.json version matches the release tag.

Key changes:

  • Added npm publish GitHub Actions workflow with release and manual triggers
  • Configured package.json files whitelist to control npm package contents (dist, README.md, LICENSE, CHANGELOG.md)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
package.json Added files array to whitelist package contents for npm publish
.github/workflows/npm-publish.yml New workflow automating npm package publishing with version validation and build steps

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

contents: read
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.event.release.tag_name }}
steps:
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

When using workflow_dispatch, the workflow attempts to checkout a tag that might not exist yet. If someone manually triggers this workflow with a tag that hasn't been pushed, the checkout step will fail. Consider adding validation to ensure the tag exists, or document that the tag must be pushed before manually triggering this workflow.

Suggested change
steps:
steps:
- name: Validate tag exists (workflow_dispatch)
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
set -e
echo "Validating that tag '${RELEASE_TAG}' exists in remote repository '${{ github.repository }}'..."
if ! git ls-remote --exit-code --tags "https://github.com/${{ github.repository }}.git" "refs/tags/${RELEASE_TAG}" >/dev/null 2>&1; then
echo "Error: Tag '${RELEASE_TAG}' does not exist in the remote repository 'https://github.com/${{ github.repository }}.git'." >&2
echo "Please push the tag before manually triggering this workflow with it." >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +44 to +45
- name: Build
run: npm run build
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The workflow builds the package but doesn't run tests before publishing to npm. While releases typically follow CI validation, manual workflow_dispatch triggers could bypass testing. Consider adding a test step (npm test) before the build step to ensure code quality, especially since the repository has comprehensive test coverage.

Copilot uses AI. Check for mistakes.
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.

P1: NPM publish pipeline + package contents control

2 participants