|
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 |
29 | 14 | id-token: write |
30 | 15 |
|
31 | | - # Use the semver as the job name |
32 | | - name: "Release ${{ github.event.inputs.semver }}" |
| 16 | + name: Publish on master (patch) |
33 | 17 | runs-on: ubuntu-latest |
| 18 | + concurrency: |
| 19 | + group: publish-pr-${{ github.event.pull_request.number }} |
| 20 | + cancel-in-progress: true |
34 | 21 | steps: |
35 | 22 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
| 23 | + with: |
| 24 | + fetch-depth: 0 |
| 25 | + persist-credentials: true |
36 | 26 |
|
37 | 27 | - uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 |
38 | 28 | with: |
39 | | - node-version: ${{ github.event.inputs.nodeVersion }} |
40 | | - registry-url: "https://registry.npmjs.org" |
| 29 | + node-version: '22' |
| 30 | + registry-url: 'https://registry.npmjs.org' |
| 31 | + |
| 32 | + - name: Install dependencies |
| 33 | + run: npm ci |
| 34 | + |
| 35 | + - name: Run tests |
| 36 | + run: npm test |
41 | 37 |
|
42 | | - - name: Bump and commit version |
| 38 | + - name: Detect version bump in merged PR |
| 39 | + id: detect |
43 | 40 | run: | |
44 | | - git config --global user.email "github-actions[bot]@github.com" |
45 | | - git config --global user.name "github-actions[bot]" |
46 | | - npm version ${{ github.event.inputs.semver }} --message "chore(release): bump version to %s" |
47 | | - git push --follow-tags |
| 41 | + set -euo pipefail |
| 42 | + VERSION=$(node -p "require('./package.json').version") |
| 43 | + PREV_JSON=$(git show HEAD^:package.json 2>/dev/null || true) |
| 44 | + if [ -z "$PREV_JSON" ]; then |
| 45 | + echo "No previous package.json found; treating as release" |
| 46 | + echo "release=true" >> $GITHUB_OUTPUT |
| 47 | + else |
| 48 | + 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));") |
| 49 | + echo "current: $VERSION, previous: $PREV_VERSION" |
| 50 | + if [ "$VERSION" != "$PREV_VERSION" ]; then |
| 51 | + echo "release=true" >> $GITHUB_OUTPUT |
| 52 | + else |
| 53 | + echo "release=false" >> $GITHUB_OUTPUT |
| 54 | + fi |
| 55 | + fi |
| 56 | + echo "VERSION=$VERSION" >> $GITHUB_ENV |
48 | 57 |
|
49 | | - - name: Publish |
50 | | - run: npm publish |
| 58 | + - name: Create annotated tag from package.json and push |
| 59 | + if: ${{ steps.detect.outputs.release == 'true' }} |
| 60 | + env: |
| 61 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 62 | + run: | |
| 63 | + set -euo pipefail |
| 64 | + git config user.email "github-actions[bot]@github.com" |
| 65 | + git config user.name "github-actions[bot]" |
51 | 66 |
|
52 | | - - name: Set version as env var |
| 67 | + TAG="v${VERSION}" |
| 68 | + echo "Creating annotated tag $TAG from current HEAD" |
| 69 | + git tag -a "$TAG" -m "chore(release): $TAG" |
| 70 | + git push origin "$TAG" |
| 71 | +
|
| 72 | + - name: Publish to npm (OIDC) |
| 73 | + if: ${{ steps.detect.outputs.release == 'true' }} |
53 | 74 | run: | |
54 | | - echo "VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV |
| 75 | + npm publish |
| 76 | +
|
| 77 | + - name: Set version as env var |
| 78 | + run: echo "VERSION=$(node -p \"require('./package.json').version\")" >> $GITHUB_ENV |
55 | 79 |
|
56 | | - - uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 |
57 | | - name: Release |
| 80 | + - name: Create GitHub release |
| 81 | + if: ${{ steps.detect.outputs.release == 'true' }} |
| 82 | + uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 |
58 | 83 | with: |
| 84 | + tag_name: v${{ env.VERSION }} |
59 | 85 | name: Release ${{ env.VERSION }} |
| 86 | + |
| 87 | + - name: No version bump detected — skipping publish |
| 88 | + if: ${{ steps.detect.outputs.release != 'true' }} |
| 89 | + run: | |
| 90 | + echo "No package.json version bump detected in merged PR; skipping tagging and publish." |
0 commit comments