Skip to content
Merged
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
89 changes: 89 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Release

on:
workflow_dispatch:
inputs:
version:
description: "Version bump"
type: choice
default: patch
options:
- patch
- minor
- major
- prepatch
- preminor
- premajor
- prerelease
tag:
description: "npm dist-tag"
type: string
default: latest

concurrency:
group: release
cancel-in-progress: false

permissions: {}

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: read # Everything that writes uses the GitHub App token below
id-token: write # Mint the OIDC token npm trusted publishing requires

defaults:
run:
working-directory: packages/react-intersection-observer

steps:
- name: Mint GitHub App token
# `main` is protected, and the GitHub Actions app cannot be a ruleset
# bypass actor on a user-owned repository. This app can, so the version
# commit is pushed with a short-lived token minted here and revoked
# when the job ends.
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_KEY }}
- uses: actions/checkout@v7
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- run: corepack enable
working-directory: .
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: "pnpm"
registry-url: "https://registry.npmjs.org"
- name: Update npm
# Trusted publishing requires npm 11.5.1 or newer
run: npm install -g npm@latest
- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: .
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Bump version, commit and tag
run: pnpm exec bumpp ${{ inputs.version }} --yes
- name: Read version
id: version
run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
- name: Build
run: pnpm build
working-directory: .
- name: Publish to npm
# No NODE_AUTH_TOKEN: npm authenticates through the OIDC token, and
# provenance is attested automatically by trusted publishing.
run: npm publish --tag ${{ inputs.tag }}
- name: Create GitHub release
run: gh release create "v${{ steps.version.outputs.version }}" --generate-notes ${{ startsWith(inputs.version, 'pre') && '--prerelease' || '' }}
working-directory: .
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
30 changes: 24 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@ Fork the repository and create a branch for your feature/bug fix.

### Commit Message Conventions

- We use
[semantic-release](https://github.com/semantic-release/semantic-release) to
manage releases automatically. To ensure that releases are automatically
versioned correctly, we follow the
- We follow the
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
Conventions. This means that your commit messages should have the following
format:
Conventions, so the generated release notes stay readable. This means that
your commit messages should have the following format:

`<type>: <subject>`

Expand Down Expand Up @@ -92,3 +89,24 @@ Build every published and documentation surface with:
```shell
pnpm build:all
```

## Releasing

Releases are published from CI with
[npm trusted publishing](https://docs.npmjs.com/trusted-publishers), so no npm
token exists anywhere and packages are published with provenance. There is no
local publish step, and `npm publish` from a laptop will be rejected.

To cut a release, a maintainer opens the **Actions** tab, selects the
**Release** workflow and runs it from the branch to release:

- `version` picks the bump (`patch`, `minor`, `major` or a `pre*` variant).
- `tag` picks the npm dist-tag, `latest` by default. Use `beta` for prereleases.

The workflow bumps the version, commits and tags it, builds the package,
publishes it to npm, and creates a GitHub release with generated notes.

`main` is protected, so the version commit is pushed with a short-lived token
minted from a GitHub App that is listed as a bypass actor on the branch
ruleset. The app's id lives in the `RELEASE_APP_ID` variable and its private key
in the `RELEASE_APP_KEY` secret.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"dev:storybook": "pnpm --filter storybook dev",
"docs:build": "pnpm --filter docs build",
"lint": "pnpm --filter react-intersection-observer lint && pnpm --filter storybook lint && pnpm --filter docs lint",
"release": "pnpm --filter react-intersection-observer release",
"test": "pnpm --filter react-intersection-observer test",
"typecheck": "pnpm build && pnpm --filter react-intersection-observer typecheck && pnpm --filter storybook typecheck && pnpm --filter docs typecheck",
"turbo:build": "turbo run build",
Expand Down
16 changes: 0 additions & 16 deletions packages/react-intersection-observer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"postbuild": "npm_config_cache=.npm-cache attw --pack && publint && size-limit",
"dev": "run-p dev:*",
"dev:package": "tsup src/index.tsx --watch",
"release": "bumpp && npm publish",
"preview": "pnpx pkg-pr-new publish --no-template",
"lint": "biome check .",
"version": "pnpm build",
Expand All @@ -69,21 +68,6 @@
"useInView",
"useIntersectionObserver"
],
"release": {
"branches": [
"main",
{
"name": "beta",
"prerelease": true
}
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github"
]
},
"size-limit": [
{
"path": "dist/index.mjs",
Expand Down
Loading