Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .github/workflows/test-oidc-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Test OIDC Validation

on:
workflow_dispatch:
inputs:
test_scenario:
description: 'Test scenario'
required: true
type: choice
options:
- 'oidc-success'
- 'oidc-missing-permission'
- 'oidc-old-npm'
- 'legacy-success'

permissions:
contents: write
pull-requests: write
# id-token: write # Intentionally commented for testing

jobs:
test-oidc:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write # This enables OIDC
if: github.event.inputs.test_scenario == 'oidc-success'

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Update npm
run: npm install -g npm@latest

- name: Install dependencies
run: yarn install

- name: Test OIDC validation
uses: ./
with:
oidcAuth: true
# No publish script - will just validate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

test-missing-permission:
runs-on: ubuntu-latest
permissions:
contents: write
# No id-token permission
if: github.event.inputs.test_scenario == 'oidc-missing-permission'

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Update npm
run: npm install -g npm@latest

- name: Install dependencies
run: yarn install

- name: Test missing permission (should fail)
uses: ./
with:
publish: echo "test"
oidcAuth: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true

test-old-npm:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
if: github.event.inputs.test_scenario == 'oidc-old-npm'

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

# Don't update npm - use older version

- name: Install dependencies
run: yarn install

- name: Test old npm version (should fail)
uses: ./
with:
publish: echo "test"
oidcAuth: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true

test-legacy:
runs-on: ubuntu-latest
if: github.event.inputs.test_scenario == 'legacy-success'

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: yarn install

- name: Test legacy mode (no publish)
uses: ./
with:
oidcAuth: false
# No publish script - will just validate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: dummy-token-for-testing
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This action for [Changesets](https://github.com/changesets/changesets) creates a
- title - The pull request title. Default to `Version Packages`
- setupGitUser - Sets up the git user for commits as `"github-actions[bot]"`. Default to `true`
- createGithubReleases - A boolean value to indicate whether to create Github releases after `publish` or not. Default to `true`
- oidcAuth - Use npm OIDC trusted publishing instead of NPM_TOKEN. Default to `false`
- commitMode - Specifies the commit mode. Use `"git-cli"` to push changes using the Git CLI, or `"github-api"` to push changes via the GitHub API. When using `"github-api"`, all commits and tags are GPG-signed and attributed to the user or app who owns the `GITHUB_TOKEN`. Default to `git-cli`.
- cwd - Changes node's `process.cwd()` if the project is not located on the root. Default to `process.cwd()`

Expand Down Expand Up @@ -123,6 +124,101 @@ For example, you can add a step before running the Changesets GitHub Action:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
```

#### With OIDC Trusted Publishing

npm supports [Trusted Publishing with OIDC](https://docs.npmjs.com/trusted-publishers), which eliminates the need for long-lived NPM tokens. This is the recommended approach for publishing to npm from GitHub Actions.

**Prerequisites:**

1. npm CLI version 11.5.1 or higher
2. [Configure a trusted publisher](https://docs.npmjs.com/trusted-publishers) on npmjs.com for your packages:
- Go to your organization/package settings on npmjs.com
- Add a trusted publisher with your GitHub repository details (organization, repository, workflow file name)
3. Add `id-token: write` permission to your workflow

**Example workflow:**

```yml
name: Release

on:
push:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
contents: write
pull-requests: write
id-token: write # Required for npm OIDC

jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4

- name: Setup Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: 20.x

# Ensure npm 11.5.1+ is available
- name: Update npm
run: npm install -g npm@latest

- name: Install Dependencies
run: yarn

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
publish: yarn release
oidcAuth: true # Enable OIDC authentication
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# No NPM_TOKEN needed with OIDC!

- name: Send a Slack notification if a publish happens
if: steps.changesets.outputs.published == 'true'
run: my-slack-bot send-notification --message "A new version of ${GITHUB_REPOSITORY} was published!"
```

**Benefits of OIDC:**

- ✅ No long-lived tokens to manage or rotate
- ✅ Cryptographic provenance attestation automatically generated
- ✅ More secure authentication flow
- ✅ Eliminates risk of token leakage

**Provenance Attestation:**

When publishing with OIDC, npm automatically generates cryptographic provenance attestation. This provides verifiable proof that your package was published from the specified GitHub repository and workflow. The attestation appears on your package page on npmjs.com as a verified badge, giving users confidence in the package's origin and integrity.

Learn more: https://docs.npmjs.com/trusted-publishers#provenance-attestation

**Migration from NPM_TOKEN to OIDC:**

1. Update your workflow to use npm 11.5.1+
2. Configure trusted publisher on npmjs.com
3. Add `id-token: write` permission to your workflow
4. Set `oidcAuth: true` in the changesets action
5. Remove `NPM_TOKEN` from the workflow and GitHub secrets

**Validation:**

The action automatically validates:

- npm version is 11.5.1 or higher
- `id-token: write` permission is granted
- `NPM_TOKEN` is not set (to avoid conflicting authentication)

If validation fails, you'll receive clear error messages with instructions on how to fix the issue.

#### Custom Publishing

If you want to hook into when publishing should occur but have your own publishing functionality, you can utilize the `hasChangesets` output.
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ inputs:
or app who owns the GITHUB_TOKEN.
required: false
default: "git-cli"
oidcAuth:
description: Use npm OIDC trusted publishing instead of NPM_TOKEN
required: false
default: false
branch:
description: Sets the branch in which the action will run. Default to `github.ref_name` if not provided
required: false
Expand Down
132 changes: 132 additions & 0 deletions docs/testing-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# OIDC Testing Guide

## Quick Test Using This Workflow

1. Push the test workflow to your fork:
```bash
git add .github/workflows/test-oidc-validation.yml
git commit -m "test: add OIDC validation test workflow"
git push origin main
```

2. Run the workflow manually from GitHub Actions UI:
- Go to Actions tab
- Select "Test OIDC Validation"
- Run workflow with different scenarios

## Full End-to-End Test (If Needed)

### 1. Create Test Package Repository

```bash
# Create a new test repo
mkdir changesets-oidc-test
cd changesets-oidc-test
npm init -y

# Update package.json
cat > package.json <<'EOF'
{
"name": "@YOUR_NPM_USERNAME/changesets-oidc-test",
"version": "0.0.1",
"description": "Test package for OIDC changesets",
"main": "index.js",
"scripts": {
"release": "changeset publish"
},
"repository": {
"type": "git",
"url": "git+https://github.com/YOUR_USERNAME/changesets-oidc-test.git"
}
}
EOF

# Create minimal package
echo 'module.exports = "test";' > index.js

# Initialize changesets
npx @changesets/cli init
```

### 2. Configure npm OIDC Trusted Publishing

1. Go to npmjs.com → Your Profile → Publishing Access
2. Add a trusted publisher:
- Source: GitHub Actions
- Repository: `YOUR_USERNAME/changesets-oidc-test`
- Workflow file: `.github/workflows/release.yml`
- Environment: (leave empty or specify)

### 3. Create Workflow in Test Repo

```yaml
# .github/workflows/release.yml
name: Release

on:
push:
branches:
- main

permissions:
contents: write
pull-requests: write
id-token: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: 20

- run: npm install -g npm@latest
- run: yarn install

- uses: GarthDB/changesets-action@v1.6.9
with:
publish: yarn release
oidcAuth: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

### 4. Create a Test Changeset

```bash
npx changeset add
# Select patch
# Describe changes
# Commit and push
```

### 5. Monitor the Workflow

Watch the GitHub Actions run to verify:
- ✅ OIDC validation passes
- ✅ Version PR is created
- ✅ After merging, package publishes successfully
- ✅ Provenance attestation is generated

## Recommended Approach

Given that:
1. Your code is already tested in production (Adobe spectrum-design-data)
2. We only simplified redundant code without changing functionality
3. All 30 tests pass locally

**Recommendation: Use Option 1 or 2 first**

- Push test workflow to your fork
- Run validation tests
- If those pass, you're ready for PR

**Only create a full test package if:**
- Maintainers request it
- You want extra confidence
- You need to debug an issue
Loading