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

# Publish to npm + cut a GitHub Release when a version tag is pushed.
# Flow: bump package.json → merge to main → `git tag v0.1.5 && git push --tags`.
# Requires repo secret NPM_TOKEN (a granular/automation token with publish + bypass-2FA).
on:
push:
tags: ['v*.*.*']
workflow_dispatch: {}

permissions:
contents: write # cut the GitHub Release

jobs:
publish:
name: publish to npm + GitHub Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: ">=1.1"

- name: Setup Node (registry auth)
uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"

- name: Install
run: bun install --frozen-lockfile

# Guard: a v0.1.5 tag must match package.json 0.1.5, so a mistagged push
# can never publish the wrong version.
- name: Tag matches package.json version
if: github.event_name == 'push'
run: |
TAG="${GITHUB_REF_NAME#v}"
PKG="$(node -p "require('./package.json').version")"
echo "tag=$TAG package.json=$PKG"
[ "$TAG" = "$PKG" ] || { echo "::error::tag $TAG != package.json $PKG"; exit 1; }

# `npm publish` runs prepublishOnly (build + tests + gen:check + compat +
# migrations) before uploading, so the gate is enforced here too.
- name: Publish to npm
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Create GitHub Release
if: github.event_name == 'push'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --generate-notes
Loading