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
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,57 @@
# Offchain Labs GitHub Actions

A collection of reusable GitHub actions and workflows.

## Publish an npm package

The [`publish-npm`](publish-npm/action.yml) composite action publishes a pnpm package to npm using [trusted publishing](https://docs.npmjs.com/trusted-publishers) and [staged publishing](https://docs.npmjs.com/staged-publishing).

It accepts stable tags (`v1.2.3`) and `alpha`, `beta`, or `rc` prerelease tags (`v1.2.3-beta.0`), verifies that the tag matches `package.json`, and selects the matching npm dist-tag (`latest`, `alpha`, `beta`, or `rc`). The packed tarball is checked with a dry run before it is staged for publishing.

Configure the calling repository and `.github/workflows/publish-npm.yml` as a trusted publisher on npm, using the `Publish` GitHub environment. The calling workflow is responsible for checking out and building the package before invoking the action:

```yml
name: Publish NPM Package

on:
push:
tags:
- "v*"

jobs:
publish:
name: Publish to npm
runs-on: ubuntu-latest
environment: Publish
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Set up pnpm and Node.js
uses: pnpm/setup@v1
with:
runtime: node@24
cache: true

- name: Build
run: pnpm build

- name: Publish package
uses: OffchainLabs/actions/publish-npm@main
with:
working-directory: src
```

### Permissions

The calling job must grant these permissions because composite actions cannot declare job-level permissions:

- `contents: read` allows the workflow to check out the repository.
- `id-token: write` allows pnpm to request the GitHub OIDC token required by npm trusted publishing.

With trusted publishing configured, no npm token secret is required.
50 changes: 50 additions & 0 deletions publish-npm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Publish npm package
description: Validate, pack, and publish an npm package using pnpm

inputs:
working-directory:
description: Directory containing the package to publish
required: false
default: .

runs:
using: composite
steps:
- name: Resolve package version and npm dist-tag
env:
RELEASE_TAG: ${{ github.ref_name }}
shell: bash
run: |
if [[ ! "$RELEASE_TAG" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$ ]]; then
echo "Tag must be vX.Y.Z or vX.Y.Z-{alpha,beta,rc}.N, for example v1.0.2 or v1.0.2-alpha.0." >&2
exit 1
fi

echo "NPM_PACKAGE_VERSION=${RELEASE_TAG#v}" >> "$GITHUB_ENV"
echo "NPM_DIST_TAG=${BASH_REMATCH[5]:-latest}" >> "$GITHUB_ENV"

- name: Verify package version matches tag
env:
PACKAGE_JSON: ${{ inputs.working-directory }}/package.json
shell: bash
run: |
PACKAGE_VERSION=$(jq -er '.version' "$PACKAGE_JSON")
if [ "$PACKAGE_VERSION" != "$NPM_PACKAGE_VERSION" ]; then
echo "$PACKAGE_JSON version ($PACKAGE_VERSION) must match the tag version ($NPM_PACKAGE_VERSION). Bump and commit $PACKAGE_JSON manually before tagging." >&2
exit 1
fi

- name: Pack package
working-directory: ${{ inputs.working-directory }}
shell: bash
run: pnpm pack

- name: Verify package
working-directory: ${{ inputs.working-directory }}
shell: bash
run: pnpm stage publish ./*.tgz --dry-run --no-git-checks --tag "$NPM_DIST_TAG"

- name: Publish package
working-directory: ${{ inputs.working-directory }}
shell: bash
run: pnpm stage publish ./*.tgz --no-git-checks --tag "$NPM_DIST_TAG"
Loading