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.
Quick start
Section titled “Quick start”- Create
.github/workflows/verify-and-release.ymlusing the verify-and-release workflow configuration. - Choose a publishing path.
- Use trusted publishing (recommended): follow Path A, then review Trusted publishing and npm provenance.
- If you cannot use trusted publishing, add
NPM_TOKENas a GitHub Actions secret as described in Environment variables and follow Path B.
- Push a commit to
main/master(or runworkflow_dispatch) and verify with the Release readiness checklist. For manual runs, see Trigger semantic-release on demand.
Choose a publishing path
Section titled “Choose a publishing path”Path A (recommended): Trusted publishing (OIDC)
Section titled “Path A (recommended): Trusted publishing (OIDC)”- No long-lived npm token in GitHub secrets.
- npm provenance is generated automatically.
- Requires
id-token: writepermission in the job that runs semantic-release. - Requires an npm Trusted Publisher configured for the workflow that triggers the run.
Path B (fallback): NPM_TOKEN
Section titled “Path B (fallback): NPM_TOKEN”- Add
NPM_TOKENto repository or organization secrets. - Keep
GITHUB_TOKENfor GitHub release notes, issue comments, and pull request comments. - Use this only when trusted publishing is not available for your setup.
Node project configuration
Section titled “Node project configuration”GitHub Actions supports workflows, allowing you to run tests on multiple Node versions and publish a release only when all tests pass.
.github/workflows/verify-and-release.yml configuration for Node projects
Section titled “.github/workflows/verify-and-release.yml configuration for Node projects”Use this as a starting point for .github/workflows/verify-and-release.yml. This example runs verification first and only runs semantic-release if verification succeeds. 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: Verify and Releaseon: push: branches: - main # or master
permissions: contents: read # for checkout
jobs: verify: name: Verify runs-on: ubuntu-latest 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: Run tests run: npm test
release: name: Release runs-on: ubuntu-latest needs: verify 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 CommnandThe workflow above shows a verify-then-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.
Environment variables
Section titled “Environment variables”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.
Trusted publishing and npm provenance
Section titled “Trusted publishing and npm provenance”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.
Common pitfalls checklist
Section titled “Common pitfalls checklist”- Do not set
registry-urlinactions/setup-nodewhen using semantic-release for npm publishing. It creates an.npmrcthat can conflict with semantic-release auth and lead toEINVALIDNPMTOKENerrors. - If you need a custom npm registry, set it in your project
.npmrc. - If using npm trusted publishing, keep
id-token: writepermission 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 release job using GitHub App authentication with @semantic-release/git (assuming a preceding verify job):
# verify:# # ... your existing verify job
release: name: Release runs-on: ubuntu-latest needs: verify permissions: contents: write issues: write pull-requests: write id-token: write steps: - 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 }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "lts/*" - name: Install dependencies run: npm clean-install - name: Release env: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} run: npx semantic-releaseRelease readiness checklist
Section titled “Release readiness checklist”- Your workflow triggers on the branch you release from (
mainormaster). fetch-depth: 0is enabled in checkout.GITHUB_TOKENis 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) orNPM_TOKENsecret. registry-urlis not set inactions/setup-node.- Your runtime meets the supported Node version policy.
Trigger semantic-release on demand
Section titled “Trigger semantic-release on demand”Use these options when you want to trigger a release outside the normal push-based workflow.
Using GUI
Section titled “Using GUI”You can use workflow_dispatch to run the release workflow manually from the GitHub UI.
Using HTTP
Section titled “Using HTTP”Use the repository_dispatch event to control when to generate a release by making an HTTP request, for example:
name: Releaseon: 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" }'