@@ -124,65 +124,58 @@ jobs:
124124 if : steps.version.outputs.new == 'true'
125125 run : node .github/scripts/check_release.js
126126
127- release :
127+ stage :
128128 runs-on : ubuntu-latest
129129 needs : version
130130 if : needs.version.outputs.new == 'true'
131- # the npm environment holds the approval step, and npm's trusted publisher setting names it
131+ # a maintainer approves this job through the npm environment, which npm's trusted publisher setting also names
132132 environment : npm
133133 permissions :
134- contents : write
134+ contents : read
135135 id-token : write
136- outputs :
137- created : ${{ steps.release.outputs.created }}
138- url : ${{ steps.release.outputs.url }}
139- notes : ${{ steps.release.outputs.notes }}
140136 steps :
141137 - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
142138 - name : Use Node.js 24
143139 uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
144140 with :
145141 node-version : 24
142+ # npm stage needs npm 11.15.0 or newer, which only Node 24.18.0 and newer ship
143+ check-latest : true
146144 registry-url : https://registry.npmjs.org
147145 package-manager-cache : false
148- - name : Publish to npm
146+ - name : Stage the package on npm
149147 env :
150148 VERSION : ${{ needs.version.outputs.version }}
151149 run : |
152150 if [ "$(npm view "countly-sdk-nodejs@$VERSION" version 2> /dev/null)" = "$VERSION" ]; then
153- echo "::notice::$VERSION is on npm already, publishing is skipped"
154- else
155- npm publish
151+ echo "::notice::$VERSION is on npm already, staging is skipped"
152+ elif ! npm stage publish; then
153+ echo "::error::Staging $VERSION failed. If $VERSION is already in the Staged Packages tab on npmjs.com, approve or reject it there"
154+ exit 1
156155 fi
157- - name : Create the GitHub release
158- id : release
156+
157+ # a draft release sends no notice; publishing it after the npm approval starts the Release Notice workflow
158+ draft :
159+ runs-on : ubuntu-latest
160+ needs : [ version, stage ]
161+ permissions :
162+ contents : write
163+ steps :
164+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
165+ - name : Create the draft GitHub release
159166 env :
160167 GH_TOKEN : ${{ github.token }}
161168 VERSION : ${{ needs.version.outputs.version }}
162169 run : |
163- node .github/scripts/check_release.js --notes > release-notes.md
164170 if gh release view "$VERSION" > /dev/null 2>&1; then
165- echo "::notice::The GitHub release $VERSION exists already, so it is not created again and no notice is sent"
166- echo "created=false" >> "$GITHUB_OUTPUT"
171+ echo "::notice::The GitHub release $VERSION exists already"
167172 else
168- gh release create "$VERSION" --title "Countly NodeJS SDK $VERSION" -- notes-file release-notes.md --target "$GITHUB_SHA"
169- echo "created=true" >> "$GITHUB_OUTPUT "
173+ node .github/scripts/check_release.js -- notes > release-notes.md
174+ gh release create "$VERSION" --draft --title "Countly NodeJS SDK $VERSION" --notes-file release-notes.md --target "$GITHUB_SHA "
170175 fi
171176 URL=$(gh release view "$VERSION" --json url --jq .url)
172- echo "url=$URL" >> "$GITHUB_OUTPUT"
173177 {
174- echo "notes<<RELEASE_NOTES_END"
175- cat release-notes.md
176- echo "RELEASE_NOTES_END"
177- } >> "$GITHUB_OUTPUT"
178-
179- # a release created with the workflow token does not start other workflows, so the notice is called directly
180- notify :
181- needs : [ version, release ]
182- if : needs.release.outputs.created == 'true'
183- uses : ./.github/workflows/release_notice.yml
184- with :
185- tag_name : ${{ needs.version.outputs.version }}
186- html_url : ${{ needs.release.outputs.url }}
187- body : ${{ needs.release.outputs.notes }}
188- secrets : inherit
178+ echo "### Next steps for $VERSION"
179+ echo "1. Approve $VERSION in the Staged Packages tab of https://www.npmjs.com/package/countly-sdk-nodejs"
180+ echo "2. Publish the draft release, which sends the release notice: $URL"
181+ } >> "$GITHUB_STEP_SUMMARY"
0 commit comments