name: Release on: workflow_dispatch: inputs: channel: description: Release channel required: true type: choice default: canary options: - canary - stable bump: description: Semantic version bump required: true type: choice default: patch options: - patch - minor - major dry_run: description: Preview the release without publishing required: true type: boolean default: true concurrency: group: release-${{ github.ref }} cancel-in-progress: false jobs: verify: if: startsWith(github.ref, 'refs/heads/release/') runs-on: ubuntu-latest timeout-minutes: 30 permissions: contents: read steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 9.15.4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 24 cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Typecheck run: pnpm -r typecheck - name: Run tests run: pnpm test:run - name: Build run: pnpm build publish: if: startsWith(github.ref, 'refs/heads/release/') needs: verify runs-on: ubuntu-latest timeout-minutes: 45 environment: npm-release permissions: contents: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 9.15.4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 24 cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Configure git author run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - name: Run release script env: GITHUB_ACTIONS: "true" run: | args=("${{ inputs.bump }}") if [ "${{ inputs.channel }}" = "canary" ]; then args+=("--canary") fi if [ "${{ inputs.dry_run }}" = "true" ]; then args+=("--dry-run") fi ./scripts/release.sh "${args[@]}" - name: Push stable release branch commit and tag if: inputs.channel == 'stable' && !inputs.dry_run run: git push origin "HEAD:${GITHUB_REF_NAME}" --follow-tags - name: Create GitHub Release if: inputs.channel == 'stable' && !inputs.dry_run env: GH_TOKEN: ${{ github.token }} run: | version="$(git tag --points-at HEAD | grep '^v' | head -1 | sed 's/^v//')" if [ -z "$version" ]; then echo "Error: no v* tag points at HEAD after stable release." >&2 exit 1 fi ./scripts/create-github-release.sh "$version"