Skip to content
Merged
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
85 changes: 75 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,83 @@ on:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}
# Deliberately no workflow-level concurrency: a publish waiting for its
# deployment approval would hold the group and keep every later push from
# refreshing the "Version Packages" pull request until someone approves. The
# two jobs that must not overlap carry their own groups instead.

jobs:
release:
name: Release
# changesets/action's sub-actions split the "what should happen?" decision out
# of the doing, which is what lets only the publish half sit behind the "main"
# environment. select-mode answers with 'version' (changesets are pending),
# 'publish' (no changesets and the registry is missing one of our versions) or
# 'none' — the last being every chore, docs and CI commit, which now finishes
# here instead of queuing a deployment approval for a no-op publish.
mode:
name: Select mode
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
mode: ${{ steps.select.outputs.mode }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: lts/krypton
cache: pnpm
# select-mode runs the locally installed @changesets/cli, so the workspace
# has to be installed before it.
- run: pnpm install

- id: select
uses: changesets/action/select-mode@v2
env:
# select-mode shells out to `changeset publish-plan`, which asks the
# registry which versions are missing — and that goes through
# `pnpm info`, so it needs the same escape hatch as publishing does.
# See the comment on the publish job below.
npm_config_force: true

# Opening (or updating) the "Version Packages" pull request touches nothing
# outside this repository, so it deliberately runs without the "main"
# environment: only the publish job below waits for a deployment approval.
version:
name: Version
needs: mode
if: needs.mode.outputs.mode == 'version'
runs-on: ubuntu-latest
concurrency: ${{ github.workflow }}-version-${{ github.ref }}
permissions:
contents: write # the version branch
pull-requests: write # the "Version Packages" pull request
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: lts/krypton
cache: pnpm
- run: pnpm install

- name: Create Release Pull Request
uses: changesets/action/version@v2

publish:
name: Publish
needs: mode
if: needs.mode.outputs.mode == 'publish'
runs-on: macos-latest
environment: main
concurrency:
group: ${{ github.workflow }}-publish-${{ github.ref }}
cancel-in-progress: false # never interrupt a release that is mid-flight
# Publishing to NPM happens through trusted publishing, which needs an OIDC
# token. Declaring permissions at all narrows them to exactly what is listed,
# so the two the changesets action already relied on are spelled out too.
# so the one the changesets action already relied on is spelled out too.
permissions:
contents: write # version commits, git tags and GitHub releases
pull-requests: write # the "Version Packages" pull request
contents: write # git tags and GitHub releases
id-token: write # NPM trusted publishing
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -56,11 +120,10 @@ jobs:
- run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi i686-linux-android aarch64-apple-ios-sim
- run: pnpm install

- name: Create Release Pull Request or Publish to NPM
id: changesets
uses: changesets/action@v2
- name: Publish to NPM
uses: changesets/action/publish@v2
with:
publish-script: pnpm run release
script: pnpm run release
env:
# changeset publish detects the pnpm lockfile and correctly shells out
# to `pnpm info`/`pnpm pack`/`pnpm publish` instead of npm's — but
Expand All @@ -73,4 +136,6 @@ jobs:
# and are unaffected. Passing force downgrades the devEngines error
# to a warning; this is pnpm's own `info` implementation, so there's
# no changesets- or pnpm-version bump that removes the need for it.
# Scoped to this step on purpose: as workflow-level env it would also
# reach `pnpm install`, where force means "recreate the lockfile".
npm_config_force: true
Loading