Skip to content

GitHub Actions

Use this recipe to run semantic-release on GitHub Actions with a secure default setup. It covers authentication options, trusted publishing with OIDC and npm provenance, a minimal release workflow for Node projects, and common pitfalls to avoid when configuring npm and GitHub tokens.

  1. Create .github/workflows/release.yml using the minimal workflow configuration.
  2. Use trusted publishing (recommended): follow Path A, then review Trusted publishing and npm provenance.
  3. If you cannot use trusted publishing, add NPM_TOKEN as a GitHub Actions secret as described in Environment variables and Choose a publishing path.
  4. Push a commit to main/master (or run workflow_dispatch) and verify with the Release readiness checklist. For manual runs, see Trigger semantic-release on demand.
Section titled “Path A (recommended): Trusted publishing (OIDC)”
  • No long-lived npm token in GitHub secrets.
  • npm provenance is generated automatically.
  • Requires id-token: write permission in the job that runs semantic-release.
  • Requires an npm Trusted Publisher configured for the workflow that triggers the run.
  • Add NPM_TOKEN to repository or organization secrets.
  • Keep GITHUB_TOKEN for GitHub release notes, issue comments, and pull request comments.
  • Use this only when trusted publishing is not available for your setup.

GitHub Actions supports workflows, allowing you to run tests on multiple Node versions and publish a release only when all tests pass.

.github/workflows/release.yml configuration for Node projects

Section titled “.github/workflows/release.yml configuration for Node projects”

Use this as a starting point for .github/workflows/release.yml. Make sure to adjust the trigger and branch name as needed. The example below is configured for trusted publishing with OIDC, but it can be easily adapted to use NPM_TOKEN instead by removing the id-token: write permission and ensuring NPM_TOKEN is available in secrets.

name: Release
on:
push:
branches:
- main # or master
permissions:
contents: read # for checkout
jobs:
release:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for trusted publishing and npm provenance
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"
- name: Install dependencies
run: npm clean-install
- name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
run: npm audit signatures
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release # <- The Run Commnand

The workflow above shows a simple release setup with the default semantic-release flow. If your release process needs a different invocation style or non-default behavior (for example, plugins or shareable configurations), refer to Running semantic-release.

The Authentication environment variables can be configured with GitHub Actions secrets.

If you are not using trusted publishing, an NPM_TOKEN is required to publish a package to the npm registry. GitHub Actions automatically populates a GITHUB_TOKEN environment variable that can be used in workflows.

For improved security and automation, it is recommended to leverage trusted publishing through OpenID Connect (OIDC) when publishing to npm from GitHub Actions. GitHub Actions is a trusted identity provider for npm, enabling configuration of a trust relationship between your GitHub repository and npm so that no long-lived secret (like an NPM_TOKEN) is required to publish packages to npm from GitHub Actions. The npm registry recently increased restrictions for use of long-lived access tokens, further encouraging trusted publishing as the preferred approach for publishing to npm from GitHub Actions. Enabling trusted publishing requires granting the id-token: write permission to the job performing the publish step and configuring a trust relationship between your GitHub repository and npm.

npm provenance is valuable for increasing supply-chain security for your npm packages. Before trusted publishing was available, generating provenance attestations required configuring your project to enable publishing with provenance. With trusted publishing, npm provenance is automatically generated for packages published to npm from GitHub Actions without any additional configuration.

  • Do not set registry-url in actions/setup-node when using semantic-release for npm publishing. It creates an .npmrc that can conflict with semantic-release auth and lead to EINVALIDNPMTOKEN errors.
  • If you need a custom npm registry, set it in your project .npmrc.
  • If using npm trusted publishing, keep id-token: write permission in the release job.
  • If using NPM_TOKEN, ensure it is configured as a repository or organization secret.
# ❌ Don't do this - can cause conflicts with semantic-release
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"
registry-url: "https://registry.npmjs.org"
# ✅ Do this instead - let semantic-release handle registry configuration through normal npm conventions
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"

Pushing package.json changes to your repository

Section titled “Pushing package.json changes to your repository”

If you choose to commit changes to your package.json against our recommendation, the @semantic-release/git plugin can be used.

Example using GitHub App authentication:

- name: Create GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
  • Your workflow triggers on the branch you release from (main or master).
  • fetch-depth: 0 is enabled in checkout.
  • GITHUB_TOKEN is available to semantic-release for the default release flow.
  • If you commit files during release on a protected branch (for example with @semantic-release/git), GitHub App auth is configured and checkout uses the app token.
  • You chose one npm auth path: trusted publishing (id-token: write) or NPM_TOKEN secret.
  • registry-url is not set in actions/setup-node.
  • Your runtime meets the supported Node version policy.

Use these options when you want to trigger a release outside the normal push-based workflow.

You can use workflow_dispatch to run the release workflow manually from the GitHub UI.

Use the repository_dispatch event to control when to generate a release by making an HTTP request, for example:

name: Release
on:
repository_dispatch:
types: [semantic-release]
jobs:
# ...

To trigger a release, call the GitHub API with a Personal Access Token stored in the GITHUB_TOKEN environment variable:

$ curl -v -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/[org-name-or-username]/[repository]/dispatches \
-d '{ "event_type": "semantic-release" }'