feat(release): add NPM publishing workflow #5
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 | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version bump type' | |
| required: true | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| permissions: | |
| contents: write | |
| id-token: write | |
| pull-requests: write | |
| jobs: | |
| # Preview release on PRs - publishes to @next tag | |
| preview: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'yarn' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Run lint | |
| run: yarn lint | |
| - name: TypeScript check | |
| run: yarn tsc | |
| - name: Run tests | |
| run: yarn test --ci | |
| - name: Build package | |
| run: yarn build | |
| - name: Set preview version | |
| id: version | |
| run: | | |
| # Get current version and create preview version with PR number and short SHA | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| SHORT_SHA=$(echo "${{ github.event.pull_request.head.sha }}" | cut -c1-7) | |
| PREVIEW_VERSION="${CURRENT_VERSION}-pr.${{ github.event.pull_request.number }}.${SHORT_SHA}" | |
| echo "preview_version=$PREVIEW_VERSION" >> $GITHUB_OUTPUT | |
| npm version "$PREVIEW_VERSION" --no-git-tag-version | |
| - name: Publish preview to NPM | |
| run: npm publish --provenance --access public --tag next | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Comment on PR | |
| uses: actions/github-script@v7 | |
| env: | |
| PREVIEW_VERSION: ${{ steps.version.outputs.preview_version }} | |
| with: | |
| script: | | |
| const script = require('./scripts/comment-pr-preview.js'); | |
| await script({ github, context }); | |
| # Publish on GitHub Release (manual release via UI) | |
| publish-on-release: | |
| if: github.event_name == 'release' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.release.tag_name }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'yarn' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Run lint | |
| run: yarn lint | |
| - name: TypeScript check | |
| run: yarn tsc | |
| - name: Run tests | |
| run: yarn test --ci | |
| - name: Build package | |
| run: yarn build | |
| - name: Set version from tag | |
| run: | | |
| # Extract version from tag (removes 'v' prefix if present) | |
| VERSION="${{ github.event.release.tag_name }}" | |
| VERSION="${VERSION#v}" | |
| npm version "$VERSION" --no-git-tag-version --allow-same-version | |
| - name: Publish to NPM | |
| run: npm publish --provenance --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| # Production release - manual workflow trigger | |
| release: | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'yarn' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Run lint | |
| run: yarn lint | |
| - name: TypeScript check | |
| run: yarn tsc | |
| - name: Run tests | |
| run: yarn test --ci | |
| - name: Build package | |
| run: yarn build | |
| - name: Configure Git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Bump version | |
| id: version | |
| run: | | |
| NEW_VERSION=$(npm version ${{ inputs.version }} --no-git-tag-version) | |
| echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| - name: Commit version bump | |
| run: | | |
| git add package.json | |
| git commit -m "chore(release): ${{ steps.version.outputs.new_version }}" | |
| git tag ${{ steps.version.outputs.new_version }} | |
| - name: Publish to NPM | |
| run: npm publish --provenance --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Push changes | |
| run: git push --follow-tags | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.new_version }} | |
| generate_release_notes: true |