This document outlines how to enable npm trusted publishing and provenance for HarperFast repositories. This allows for more secure publishing eliminating the need for long-lived npm tokens in GitHub Secrets.
Add the following permissions to your GitHub release workflow (usually in .github/workflows/release.yaml). These are required to properly allow the workflow to create GitHub releases and publish to npm.
permissions:
contents: write
issues: write
pull-requests: write
id-token: writeNote: The
id-token: writepermission is specifically required for npm provenance and trusted publishing.
Update your npm publish step to include the --provenance flag:
- name: Publish to npm
run: npm publish --provenanceIf the package has never been published to npm before, you must manually publish it once from your local machine.
For @harperfast scoped packages, use:
npm publish --access publicThis initial manual publish adds the package to npm, allowing you to then configure it for trusted publishing.
Once the package exists on npm, you can configure the repository as a trusted publisher:
- Visit
https://www.npmjs.com/package/{packageName}/access - Add or edit a Trusted Publisher.
- Publisher: GitHub Actions
- Organization or user:
HarperFast - Repo: The exact name of your repository.
- Workflow filename: The exact name of your release workflow file (e.g.,
release.yaml). This is case-sensitive and must be located in the.github/workflows/folder. - Environment name: Leave blank unless you are specifically using GitHub Environments.
While you're in npm access settings, also disallow tokens:
Require two-factor authentication and disallow tokens (recommended)
Remember to hit save!
I'll mention two options for configuring version increments:
- Manual Increment: Manually update the version number in your
package.jsonfile before publishing. - Automated Increment with Semantic Release: Use
semantic-releaseto automatically determine and update the version number based on commit messages.
HarperFast projects often use semantic-release to automate the entire package release workflow, including determining the next version number, generating release notes, and publishing to npm.
You can configure semantic-release using a .releaserc.json file or a release.config.js file in your repository root.
Example .releaserc.json:
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/npm", {"npmPublish": false}],
"@semantic-release/github"
]
}Ensure you have the following devDependencies in your package.json:
npm install --save-dev semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/npm @semantic-release/githubWhen using semantic-release, your publish step in GitHub Actions might look like this:
jobs:
release:
name: Release
environment: Release
# Ensure releases run only when code reaches main via GitHub Merge Queue, or when manually dispatched
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: '.nvmrc'
cache: npm
registry-url: 'https://registry.npmjs.org'
- name: Update npm
run: npm install -g npm@latest
- name: Install dependencies
run: npm ci
- name: Check lint
run: npm run lint
- name: Check format
run: npm run format
- name: Run unit tests
run: npm test
- name: Semantic Release
if: ${{ github.event_name == 'push' }}
uses: cycjimmy/semantic-release-action@b12c8f6015dc215fe37bc154d4ad456dd3833c90 # v6.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_CONFIG_PROVENANCE: true
- name: Publish to npm
run: npm publish --provenanceFor a reference implementation, see the harper-agent release workflow.