99 pull_request :
1010 branches : [ master, staging ]
1111
12+ permissions :
13+ contents : read
14+
1215concurrency :
1316 group : ${{ github.workflow }}-${{ github.ref }}
14- cancel-in-progress : true
17+ cancel-in-progress : ${{ github.event_name == 'pull_request' }}
1518
1619jobs :
1720 build :
18-
19- runs-on : ubuntu-latest
21+ runs-on : ${{ matrix.os }}
2022 strategy :
21- matrix :
22- # mocha 11 requires Node 18.18+, 24 is the active LTS
23- node : [18, 20, 22, 24]
23+ fail-fast : false
24+ matrix :
25+ # the test suite needs Node 18.18+ (mocha 11), the compat job covers the older supported versions
26+ os : [ ubuntu-latest ]
27+ node : [ 18, 20, 22, 24, 26 ]
28+ include :
29+ - os : windows-latest
30+ node : 24
2431 steps :
25- - uses : actions/checkout@v4
32+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2633 - name : Use Node.js ${{ matrix.node }}
27- uses : actions/setup-node@v4
34+ uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
2835 with :
2936 node-version : ${{ matrix.node }}
3037 cache : ' npm'
3138 - run : npm ci
32- - run : npm test
39+ - name : Lint and test
40+ if : matrix.os == 'ubuntu-latest' && matrix.node != 24
41+ run : npm test
42+ - name : Lint and test with coverage
43+ if : matrix.os == 'ubuntu-latest' && matrix.node == 24
44+ run : npm run coverage
45+ - name : Upload the coverage report
46+ if : matrix.os == 'ubuntu-latest' && matrix.node == 24
47+ uses : actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
48+ with :
49+ name : coverage-report
50+ path : coverage/
51+ # lint runs on Linux only, as Windows checkouts can have CRLF line endings that the lint rules reject
52+ - name : Test
53+ if : matrix.os == 'windows-latest'
54+ run : npm test --ignore-scripts
55+
56+ compat :
57+ runs-on : ubuntu-latest
58+ timeout-minutes : 5
59+ strategy :
60+ fail-fast : false
61+ matrix :
62+ node : [ 10, 12, 14, 16 ]
63+ steps :
64+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
65+ - name : Use Node.js ${{ matrix.node }}
66+ uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
67+ with :
68+ node-version : ${{ matrix.node }}
69+ # the SDK has no dependencies, so the check runs without installing packages
70+ - run : node test/compat/compat_check.js
3371
3472 deploy :
3573 runs-on : ubuntu-latest
36- needs : build
74+ needs : [ build, compat ]
3775 if : github.event_name == 'push' && github.ref == 'refs/heads/master'
76+ permissions :
77+ contents : write
3878 steps :
39- - uses : actions/checkout@v4
79+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
4080 - name : Use Node.js 24.x
41- uses : actions/setup-node@v4
81+ uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
4282 with :
4383 node-version : 24.x
4484 cache : ' npm'
@@ -48,3 +88,101 @@ jobs:
4888 env :
4989 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
5090 run : bash generateDocs.sh
91+
92+ version :
93+ runs-on : ubuntu-latest
94+ needs : [ build, compat ]
95+ if : github.event_name == 'push' && github.ref == 'refs/heads/master'
96+ outputs :
97+ version : ${{ steps.version.outputs.version }}
98+ new : ${{ steps.version.outputs.new }}
99+ steps :
100+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
101+ - name : Use Node.js 24
102+ uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
103+ with :
104+ node-version : 24
105+ package-manager-cache : false
106+ - name : Check whether this version is on npm already
107+ id : version
108+ run : |
109+ VERSION=$(node -p "require('./package.json').version")
110+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
111+ STATUS=0
112+ PUBLISHED=$(npm view "countly-sdk-nodejs@$VERSION" version 2> npm-view-error.txt) || STATUS=$?
113+ if [ "$STATUS" -eq 0 ] && [ "$PUBLISHED" = "$VERSION" ]; then
114+ echo "new=false" >> "$GITHUB_OUTPUT"
115+ echo "::notice::$VERSION is on npm already, nothing to release"
116+ elif [ "$STATUS" -eq 0 ] || grep -q E404 npm-view-error.txt; then
117+ echo "new=true" >> "$GITHUB_OUTPUT"
118+ else
119+ cat npm-view-error.txt
120+ echo "::error::Could not check whether $VERSION is on npm"
121+ exit 1
122+ fi
123+ - name : Check that package.json, the code and the CHANGELOG name the same version
124+ if : steps.version.outputs.new == 'true'
125+ run : node .github/scripts/check_release.js
126+
127+ release :
128+ runs-on : ubuntu-latest
129+ needs : version
130+ if : needs.version.outputs.new == 'true'
131+ # the npm environment holds the approval step, and npm's trusted publisher setting names it
132+ environment : npm
133+ permissions :
134+ contents : write
135+ id-token : write
136+ outputs :
137+ created : ${{ steps.release.outputs.created }}
138+ url : ${{ steps.release.outputs.url }}
139+ notes : ${{ steps.release.outputs.notes }}
140+ steps :
141+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
142+ - name : Use Node.js 24
143+ uses : actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
144+ with :
145+ node-version : 24
146+ registry-url : https://registry.npmjs.org
147+ package-manager-cache : false
148+ - name : Publish to npm
149+ env :
150+ VERSION : ${{ needs.version.outputs.version }}
151+ run : |
152+ 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
156+ fi
157+ - name : Create the GitHub release
158+ id : release
159+ env :
160+ GH_TOKEN : ${{ github.token }}
161+ VERSION : ${{ needs.version.outputs.version }}
162+ run : |
163+ node .github/scripts/check_release.js --notes > release-notes.md
164+ 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"
167+ 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"
170+ fi
171+ URL=$(gh release view "$VERSION" --json url --jq .url)
172+ echo "url=$URL" >> "$GITHUB_OUTPUT"
173+ {
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
0 commit comments