release-please #342
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: release-please | |
| on: | |
| push: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: Run npm publish with --dry-run (manual dispatch only) | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: release-please | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| release-please: | |
| if: github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| outputs: | |
| release_created: ${{ steps.release.outputs.release_created }} | |
| steps: | |
| - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 | |
| id: release | |
| with: | |
| # PAT so release PRs trigger other workflows (auto-label, add-issues-and-prs-to-fs-project-board). | |
| # This PAT has the permissions outlined in https://github.com/googleapis/release-please-action?tab=readme-ov-file#workflow-permissions. | |
| # Using GITHUB_TOKEN suppresses follow-on workflow runs, which would mean release please PRs wouldn't get properly labeled and added to the project board. | |
| token: ${{ secrets.FILOZZY_RELEASE_PLEASE_PAT }} | |
| config-file: release-please-config.json | |
| validate-dispatch: | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Validate dispatch ref and release state | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REF: ${{ github.ref }} | |
| SHA: ${{ github.sha }} | |
| DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} | |
| run: | | |
| set -euo pipefail | |
| case "$REF" in | |
| refs/tags/v[0-9]*.[0-9]*.[0-9]*) ;; | |
| *) | |
| echo "::error::Dispatch ref must be a vX.Y.Z tag, got: $REF" | |
| exit 1 | |
| ;; | |
| esac | |
| TAG="${REF#refs/tags/}" | |
| VERSION="${TAG#v}" | |
| PKG_NAME="$(node -p "require('./package.json').name")" | |
| PKG_VERSION="$(node -p "require('./package.json').version")" | |
| if [ "$VERSION" != "$PKG_VERSION" ]; then | |
| echo "::error::Tag $TAG does not match package.json version $PKG_VERSION" | |
| exit 1 | |
| fi | |
| # Confirm the tag commit is on the default branch via GitHub's | |
| # compare API (works regardless of local clone depth). | |
| STATUS="$(gh api "repos/$GITHUB_REPOSITORY/compare/$DEFAULT_BRANCH...$SHA" --jq .status)" | |
| case "$STATUS" in | |
| identical|behind) ;; | |
| *) | |
| echo "::error::Tag commit $SHA is not an ancestor of $DEFAULT_BRANCH (compare status: $STATUS)" | |
| exit 1 | |
| ;; | |
| esac | |
| if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then | |
| echo "::error::GitHub release $TAG not found" | |
| exit 1 | |
| fi | |
| PUBLISHED="$(npm view "$PKG_NAME@$VERSION" version 2>/dev/null || true)" | |
| if [ -n "$PUBLISHED" ]; then | |
| echo "::error::npm already has $PKG_NAME@$PUBLISHED" | |
| exit 1 | |
| fi | |
| build: | |
| needs: [release-please, validate-dispatch] | |
| if: | | |
| always() && ( | |
| needs.release-please.outputs.release_created == 'true' || | |
| needs.validate-dispatch.result == 'success' | |
| ) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 20 | |
| outputs: | |
| tarball: ${{ steps.pack.outputs.tarball }} | |
| steps: | |
| - uses: actions/checkout@v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 | |
| with: | |
| run_install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 'lts/*' | |
| registry-url: 'https://registry.npmjs.org' | |
| # Pin npm to a known-good major to avoid @latest drift on a publish-path runner. | |
| - name: Pin npm | |
| run: npm install -g npm@11 | |
| - name: Install dependencies | |
| env: | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1" | |
| run: pnpm install --frozen-lockfile | |
| - name: Build | |
| run: pnpm run build | |
| - name: Pack tarball | |
| id: pack | |
| run: | | |
| set -euo pipefail | |
| TARBALL="$(npm pack --silent)" | |
| test -n "$TARBALL" | |
| test -f "$TARBALL" | |
| echo "tarball=$TARBALL" >> "$GITHUB_OUTPUT" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: npm-tarball | |
| path: ${{ steps.pack.outputs.tarball }} | |
| retention-days: 7 | |
| if-no-files-found: error | |
| publish: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write # OIDC for npm trusted publishing | |
| contents: read | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 'lts/*' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Pin npm | |
| run: npm install -g npm@11 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: npm-tarball | |
| path: artifact | |
| - name: Publish tarball to npm | |
| env: | |
| DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }} | |
| TARBALL_NAME: ${{ needs.build.outputs.tarball }} | |
| run: | | |
| set -euo pipefail | |
| # Assert exactly one tarball was delivered and it matches the | |
| # filename emitted by the build job. | |
| COUNT="$(find artifact -maxdepth 1 -name '*.tgz' | wc -l | tr -d ' ')" | |
| if [ "$COUNT" != "1" ]; then | |
| echo "::error::Expected exactly one tarball in artifact/, found $COUNT" | |
| exit 1 | |
| fi | |
| TARBALL="artifact/$TARBALL_NAME" | |
| if [ ! -f "$TARBALL" ]; then | |
| echo "::error::Tarball $TARBALL not found" | |
| exit 1 | |
| fi | |
| if [ "$DRY_RUN" = "true" ]; then | |
| npm publish --access public --dry-run "$TARBALL" | |
| else | |
| npm publish --access public "$TARBALL" | |
| fi |