|
1 | | -name: Publish to NPM |
| 1 | +name: Publish NPM and Release (on merged PR) |
2 | 2 |
|
3 | 3 | on: |
4 | | - workflow_dispatch: |
5 | | - inputs: |
6 | | - semver: |
7 | | - description: "The semantic version to bump" |
8 | | - required: true |
9 | | - type: choice |
10 | | - options: |
11 | | - - patch |
12 | | - - minor |
13 | | - - major |
14 | | - default: "patch" |
15 | | - nodeVersion: |
16 | | - description: "The Node.js version to use" |
17 | | - required: true |
18 | | - type: choice |
19 | | - options: |
20 | | - - "18.x" |
21 | | - - "20.x" |
22 | | - - "22.x" |
23 | | - default: "18.x" |
| 4 | + pull_request: |
| 5 | + types: |
| 6 | + - closed |
24 | 7 |
|
25 | 8 | jobs: |
26 | 9 | release: |
| 10 | + if: ${{ github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'master' }} |
27 | 11 | permissions: |
28 | 12 | contents: write |
| 13 | + packages: write |
| 14 | + id-token: write |
29 | 15 |
|
30 | | - # Use the semver as the job name |
31 | | - name: "Release ${{ github.event.inputs.semver }}" |
| 16 | + name: Publish on master (patch) |
32 | 17 | runs-on: ubuntu-latest |
| 18 | + concurrency: |
| 19 | + group: publish-pr-${{ github.event.pull_request.number }} |
| 20 | + cancel-in-progress: true |
33 | 21 | steps: |
34 | 22 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
| 23 | + with: |
| 24 | + fetch-depth: 0 |
| 25 | + persist-credentials: true |
35 | 26 |
|
36 | 27 | - uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 |
37 | 28 | with: |
38 | | - node-version: ${{ github.event.inputs.nodeVersion }} |
39 | | - registry-url: "https://registry.npmjs.org" |
| 29 | + node-version: 24 |
| 30 | + registry-url: 'https://registry.npmjs.org' |
40 | 31 |
|
41 | | - - name: Bump and commit version |
| 32 | + - name: Detect version bump in merged PR |
| 33 | + id: detect |
42 | 34 | run: | |
43 | | - git config --global user.email "github-actions[bot]@github.com" |
44 | | - git config --global user.name "github-actions[bot]" |
45 | | - npm version ${{ github.event.inputs.semver }} --message "chore(release): bump version to %s" |
46 | | - git push --follow-tags |
| 35 | + set -euo pipefail |
| 36 | + VERSION=$(node -p "require('./package.json').version") |
| 37 | + PREV_JSON=$(git show HEAD^:package.json 2>/dev/null || true) |
| 38 | + if [ -z "$PREV_JSON" ]; then |
| 39 | + echo "No previous package.json found; treating as release" |
| 40 | + echo "release=true" >> $GITHUB_OUTPUT |
| 41 | + else |
| 42 | + PREV_VERSION=$(printf "%s" "$PREV_JSON" | node -e "let s=''; process.stdin.on('data',d=>s+=d); process.stdin.on('end',()=>console.log(JSON.parse(s).version));") |
| 43 | + echo "current: $VERSION, previous: $PREV_VERSION" |
| 44 | + if [ "$VERSION" != "$PREV_VERSION" ]; then |
| 45 | + echo "release=true" >> $GITHUB_OUTPUT |
| 46 | + else |
| 47 | + echo "release=false" >> $GITHUB_OUTPUT |
| 48 | + fi |
| 49 | + fi |
| 50 | + echo "VERSION=$VERSION" >> $GITHUB_ENV |
47 | 51 |
|
48 | | - - name: Publish |
49 | | - run: npm publish |
| 52 | + - name: Create annotated tag from package.json and push |
| 53 | + if: ${{ steps.detect.outputs.release == 'true' }} |
50 | 54 | env: |
51 | | - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} |
| 55 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 56 | + run: | |
| 57 | + set -euo pipefail |
| 58 | + git config user.email "github-actions[bot]@github.com" |
| 59 | + git config user.name "github-actions[bot]" |
| 60 | +
|
| 61 | + TAG="v${VERSION}" |
| 62 | + echo "Creating annotated tag $TAG from current HEAD" |
| 63 | + git tag -a "$TAG" -m "chore(release): $TAG" |
| 64 | + git push origin "$TAG" |
52 | 65 |
|
53 | | - - name: Set version as env var |
| 66 | + - name: Publish to npm (OIDC) |
| 67 | + if: ${{ steps.detect.outputs.release == 'true' }} |
54 | 68 | run: | |
55 | | - echo "VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV |
| 69 | + npm publish |
56 | 70 |
|
57 | | - - uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e |
58 | | - name: Release |
59 | | - env: |
60 | | - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 71 | + - name: Create GitHub release |
| 72 | + if: ${{ steps.detect.outputs.release == 'true' }} |
| 73 | + uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 |
61 | 74 | with: |
62 | | - tag_name: ${{ env.VERSION }} |
63 | | - release_name: Release ${{ env.VERSION }} |
64 | | - draft: false |
65 | | - prerelease: false |
| 75 | + tag_name: v${{ env.VERSION }} |
| 76 | + name: Release ${{ env.VERSION }} |
| 77 | + |
| 78 | + - name: No version bump detected — skipping publish |
| 79 | + if: ${{ steps.detect.outputs.release != 'true' }} |
| 80 | + run: | |
| 81 | + echo "No package.json version bump detected in merged PR; skipping tagging and publish." |
0 commit comments