Skip to content

Latest commit

 

History

History
222 lines (162 loc) · 6.17 KB

File metadata and controls

222 lines (162 loc) · 6.17 KB

NPM OIDC Publish Workflow

A reusable GitHub Actions workflow for publishing npm packages using OIDC (OpenID Connect) Trusted Publishing - no npm tokens required!

Features

  • No npm tokens - Uses OIDC authentication directly with npmjs.com
  • Automatic provenance - npm automatically generates provenance attestations
  • Enhanced security - Short-lived, workflow-specific credentials
  • Simple setup - Minimal configuration required
  • Public packages only - Designed for publishing public npm packages

Prerequisites

1. npm CLI Version

Requires npm CLI v11.5.1 or later (installed in the workflow)

2. Configure Trusted Publishing on npmjs.com

You must configure your package for Trusted Publishing before using this workflow:

Steps:

  1. Login to npmjs.com with a maintainer account

  2. Navigate directly to package access settings

  3. Add Trusted Publisher

    • Scroll to "Trusted publishers" section
    • Click "Add trusted publisher"
    • Select provider: GitHub Actions
    • Fill in:
      • GitHub organization or user: Your GitHub org/username
      • Repository: Your repository name
      • Workflow filename: Your workflow filename (e.g., publish.yml - filename only, not full path)
      • Environment name: Leave blank (unless using GitHub Environments)
    • Important: Check "npm publish" under "Allowed actions"
    • Click "Add" or "Save"
  4. Verify configuration

    ✓ GitHub Actions
      Organization: your-org
      Repository: your-repo
      Workflow: publish.yml
      Environment: (any)
      Allowed actions: npm publish
    

Basic Usage

Choose a trigger that fits your release process.

Option A: Manual release (workflow_dispatch)

Publish only when you explicitly decide to — useful when not every merge to main should cut a release.

name: Publish to npm

on:
  workflow_dispatch:

jobs:
  publish:
    uses: mapbox/gha-public/.github/workflows/workflow-npm-oidc-publish.yml@main
    with:
      npm-tag: 'latest'

Option B: Publish on every merge to default branch

Publish automatically on every PR merge. Best suited for projects where every merge is a releasable change and the version is always bumped in the PR.

name: Publish to npm

on:
  push:
    branches:
      - main

jobs:
  publish:
    uses: mapbox/gha-public/.github/workflows/workflow-npm-oidc-publish.yml@main
    with:
      npm-tag: 'latest'

Note: npm publish will fail if the version in package.json has already been published. Make sure the version is bumped before merging.

Inputs

Input Description Required Default
node-version Node.js version to use No '22'
working-directory Working directory for the package No '.'
npm-tag npm dist-tag to use No 'latest'
run-tests Run npm test before publishing No false
dry-run Perform a dry-run publish No false
create-github-release Create a GitHub release with auto-generated notes after publishing. Skipped on dry-run. Fails if the version tag already exists. No false

Outputs

Output Description
package-name The published package name
package-version The published package version

Advanced Examples

Publish with GitHub Release

name: Publish to npm

on:
  push:
    branches:
      - main

jobs:
  publish:
    uses: mapbox/gha-public/.github/workflows/workflow-npm-oidc-publish.yml@main
    with:
      create-github-release: true

Release notes are auto-generated by GitHub from merged PRs since the previous release tag. Docs The release tag is derived from the version field in package.json (e.g. 1.2.3v1.2.3). The workflow fails if that tag already exists — bump the version before merging.

Monorepo Support

name: Publish Package A

on:
  workflow_dispatch:

jobs:
  publish-a:
    uses: mapbox/gha-public/.github/workflows/workflow-npm-oidc-publish.yml@main
    with:
      working-directory: './packages/package-a'
      npm-tag: 'latest'

Dry Run for Testing

name: Test Publish

on:
  pull_request:

jobs:
  test-publish:
    uses: mapbox/gha-public/.github/workflows/workflow-npm-oidc-publish.yml@main
    with:
      dry-run: true

Package.json Requirements

Your package.json should include:

{
  "name": "@your-scope/your-package",
  "version": "1.0.0",
  "scripts": {
    "build": "your-build-command",  // Optional, runs if present
    "test": "your-test-command"      // Required if run-tests: true
  }
}

For scoped packages to be public, ensure:

{
  "publishConfig": {
    "access": "public"
  }
}

Troubleshooting

403 Forbidden Error

Cause: npm rejected the OIDC token - Trusted Publisher configuration doesn't match

Solution:

  1. Verify organization/repository name is correct (case-sensitive)
  2. Check workflow filename matches exactly (filename only, not path)
  3. Ensure "npm publish" is checked under Allowed actions
  4. Verify package is configured as public (not private)

404 Not Found

Cause: npm couldn't match your workflow to the Trusted Publisher config

Solution: Double-check all configuration values match exactly

No OIDC Token

Cause: Missing id-token: write permission

Solution: This workflow includes the permission - ensure you're not overriding it

More Information