ci: switch to npm Trusted Publishing (OIDC, no NPM_TOKEN) #40
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: | |
| push: | |
| branches: | |
| - main | |
| - "release/**" | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| registry-url: https://registry.npmjs.org | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Validate package | |
| run: bun run verify | |
| - name: Resolve release tag | |
| id: release | |
| run: | | |
| NAME="$(node -p "require('./package.json').name")" | |
| VERSION="$(node -p "require('./package.json').version")" | |
| echo "name=${NAME}" >> "$GITHUB_OUTPUT" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "tag=${NAME}@${VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Check release state | |
| id: release_state | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PACKAGE_NAME: ${{ steps.release.outputs.name }} | |
| PACKAGE_VERSION: ${{ steps.release.outputs.version }} | |
| TAG: ${{ steps.release.outputs.tag }} | |
| run: | | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version >/dev/null 2>&1; then | |
| echo "package_published=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "package_published=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| HAS_CHANGESETS=false | |
| for changeset in .changeset/*.md; do | |
| if [ -e "$changeset" ]; then | |
| HAS_CHANGESETS=true | |
| break | |
| fi | |
| done | |
| echo "has_changesets=${HAS_CHANGESETS}" >> "$GITHUB_OUTPUT" | |
| - name: Create version PR (changesets) | |
| if: steps.release_state.outputs.has_changesets == 'true' | |
| uses: changesets/action@v1 | |
| with: | |
| version: bun run changeset version | |
| createGithubReleases: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish to npm | |
| id: publish | |
| if: steps.release_state.outputs.package_published != 'true' && steps.release_state.outputs.has_changesets != 'true' | |
| run: npm publish --access public --provenance | |
| - name: Generate release notes | |
| if: steps.release_state.outputs.exists != 'true' && steps.publish.outcome == 'success' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TAG: ${{ steps.release.outputs.tag }} | |
| run: | | |
| gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" \ | |
| -f tag_name="$TAG" \ | |
| -f target_commitish="$GITHUB_SHA" \ | |
| --jq '.body // ""' > release-notes.md | |
| if ! grep -q '[^[:space:]]' release-notes.md; then | |
| echo "# Release $TAG" > release-notes.md | |
| fi | |
| - name: Create GitHub release | |
| if: steps.release_state.outputs.exists != 'true' && steps.publish.outcome == 'success' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TAG: ${{ steps.release.outputs.tag }} | |
| run: | | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release edit "$TAG" --title "$TAG" --notes-file release-notes.md | |
| else | |
| gh release create "$TAG" --target "$GITHUB_SHA" --title "$TAG" --notes-file release-notes.md | |
| fi |