-
-
Notifications
You must be signed in to change notification settings - Fork 613
497 lines (415 loc) · 15.8 KB
/
test-and-release.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
name: Test and Release
# Run this job on all pushes to master, for pull requests
# as well as tags with a semantic version
on:
push:
branches:
# This avoids having duplicate builds in non-forked PRs
- "master"
tags:
# normal versions
- "v[0-9]+.[0-9]+.[0-9]+"
# pre-releases
- "v[0-9]+.[0-9]+.[0-9]+-**"
pull_request: {}
merge_group:
types: [checks_requested]
# Cancel previous PR/branch runs when a new commit is pushed
concurrency:
group: 'test-and-release-${{ github.ref }}'
cancel-in-progress: true
env:
TURBO_API: "http://127.0.0.1:9080"
# The token and team are required by the TurboRepo server, just set them to anything
TURBO_TOKEN: foo
TURBO_TEAM: me
# Additional CLI flags for turbo commands
TURBO_FLAGS: "" # "--concurrency=2"
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Compile TypeScript code
run: yarn build $TURBO_FLAGS
- name: Save Turbo Cache between jobs
uses: ./.github/actions/build-cache-upload
# ===================
# Makes sure that the published packages can be require'd without issues in a production environment
test-packages:
needs: [build]
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Restore Turbo Cache from previous jobs
uses: ./.github/actions/build-cache-download
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Compile TypeScript code
run: yarn build $TURBO_FLAGS
# Test that the generated packages are ok
# I'd love to use yalc or something for this, but it doesn't use yarn pack to pack the tarballs
# so we need to fake the install
- name: Import main entry points for each package
id: monopack
run: |
TMP_DIR=$(mktemp -d)
echo TMP_DIR=$TMP_DIR >> $GITHUB_OUTPUT
echo "Re-creating a production environment..."
yarn monopack --target "$TMP_DIR/.tarballs" --no-version
cd $TMP_DIR
npm init -y
npm i .tarballs/zwave-js.tgz
echo "Testing ESM entry points..."
# Now all entrypoints should work
node -e '(async () => { await import("zwave-js") })()'
node -e '(async () => { await import("@zwave-js/cc") })()'
node -e '(async () => { await import("@zwave-js/config") })()'
node -e '(async () => { await import("@zwave-js/core") })()'
node -e '(async () => { await import("@zwave-js/host") })()'
node -e '(async () => { await import("@zwave-js/nvmedit") })()'
node -e '(async () => { await import("@zwave-js/serial") })()'
node -e '(async () => { await import("@zwave-js/shared") })()'
node -e '(async () => { await import("@zwave-js/testing") })()'
node -e '(async () => { await import("zwave-js/safe") })()'
node -e '(async () => { await import("@zwave-js/cc/safe") })()'
node -e '(async () => { await import("@zwave-js/config/safe") })()'
node -e '(async () => { await import("@zwave-js/core/safe") })()'
node -e '(async () => { await import("@zwave-js/host/safe") })()'
node -e '(async () => { await import("@zwave-js/nvmedit/safe") })()'
node -e '(async () => { await import("@zwave-js/serial/safe") })()'
node -e '(async () => { await import("@zwave-js/shared/safe") })()'
echo "Testing CJS entry points..."
# Now all entrypoints should work
node -e 'require("zwave-js")'
node -e 'require("@zwave-js/cc")'
node -e 'require("@zwave-js/config")'
node -e 'require("@zwave-js/core")'
node -e 'require("@zwave-js/host")'
node -e 'require("@zwave-js/nvmedit")'
node -e 'require("@zwave-js/serial")'
node -e 'require("@zwave-js/shared")'
node -e 'require("@zwave-js/testing")'
node -e 'require("zwave-js/safe")'
node -e 'require("@zwave-js/cc/safe")'
node -e 'require("@zwave-js/config/safe")'
node -e 'require("@zwave-js/core/safe")'
node -e 'require("@zwave-js/host/safe")'
node -e 'require("@zwave-js/nvmedit/safe")'
node -e 'require("@zwave-js/serial/safe")'
node -e 'require("@zwave-js/shared/safe")'
echo "Testing version exports..."
node -e 'assert.equal(require("@zwave-js/config").PACKAGE_VERSION, require("@zwave-js/config/package.json").version)'
node -e 'assert.equal(require("zwave-js").libVersion, require("zwave-js/package.json").version)'
node -e 'assert.equal(require("zwave-js").libName, require("zwave-js/package.json").name)'
echo "Doing spot checks for some exports"
node -e 'assert.equal(typeof require("@zwave-js/core").randomBytes, "function")'
# Test if bundling for the browser is supported yet
- name: Are we browser yet?
continue-on-error: true
env:
TMP_DIR: ${{ steps.monopack.outputs.TMP_DIR }}
run: |
cd $TMP_DIR
npm i -D esbuild
echo "import 'zwave-js'" > test.mjs
npx esbuild test.mjs --bundle --format=esm --outdir=build --sourcemap --target=es2022 --platform=browser --analyze=verbose --external:node:crypto
# ===================
lint:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Run linters
run: yarn run lint $TURBO_FLAGS
- name: Prepare lint auto-fix patch
if: |
failure() &&
github.event_name == 'pull_request'
id: lint
run: |
# Run all lint commands and abort if one has unfixable errors
yarn run lint:ts:fix $TURBO_FLAGS
yarn fmt $TURBO_FLAGS
git diff --name-only || true
if ! git diff --quiet ; then
echo "has changes"
git diff > fix.patch
echo "changed=true" >> $GITHUB_OUTPUT
else
echo "unchanged"
echo "changed=false" >> $GITHUB_OUTPUT
fi
- name: Upload Patch
if: |
failure() &&
github.event_name == 'pull_request' &&
steps.lint.outputs.changed == 'true'
uses: actions/upload-artifact@v4
with:
name: lint-fix
path: fix.patch
# ===================
lint-zwave:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Lint config files and Z-Wave specifics
# Disable log prefix, so GitHub recognizes annotations in the output
run: yarn run lint:zwave $TURBO_FLAGS --log-prefix=none
# ===================
# Runs unit tests on all supported node versions and OSes
unit-tests:
name: "Unit tests: ${{ matrix.os }}, Node.js ${{ matrix.node-version }} (part ${{ matrix.shard }})"
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [18, 20]
os: [ubuntu-latest]
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
# # For pull requests, only run tests for changed files
# - name: Run component tests (changes)
# if: github.event_name == 'pull_request'
# run: |
# git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1
# yarn run test:dirty --resolve --base origin/${{ github.event.pull_request.base.ref }}
# For all other events, especially on master and releases, run the full test suite
# Run the full test suite on master, release branches and tags
- name: Run component tests (full)
# if: github.event_name != 'pull_request'
run: yarn run test:ts --shard ${{ matrix.shard }}
# ===================
# Test if the transformers are working
test-transformers:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [18, 20]
os: [ubuntu-latest]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
# Transformer tests need their dependencies to be compiled
- name: Compile test dependencies
run: |
yarn workspace @zwave-js/shared run build
yarn workspace @zwave-js/core run build
# For pull requests, only run tests for changed files
- name: Test transformers
run: yarn workspace @zwave-js/transformers run test:ts
# # ===================
# # This job checks if a PR changes the public API surface
# api-surface:
# name: Check public API surface
# # Only run for PRs
# if: github.event_name == 'pull_request'
# needs: [build]
# runs-on: ubuntu-latest
# strategy:
# matrix:
# node-version: [18] # This should be LTS
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Restore Turbo Cache from previous jobs
# uses: ./.github/actions/build-cache-download
# - name: Prepare testing environment
# uses: ./.github/actions/prepare-env
# with:
# node-version: ${{ matrix.node-version }}
# githubToken: ${{ secrets.GITHUB_TOKEN }}
# - name: Generate API report
# run: yarn run extract-api $TURBO_FLAGS
# - name: Show changes
# if: failure()
# run: |
# cat packages/*/.tmp/api.md
# - name: Comment on PR
# if: failure()
# run: |
# echo "The public API surface has changed!" >> $GITHUB_STEP_SUMMARY
# echo "Please run" >> $GITHUB_STEP_SUMMARY
# echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
# echo "yarn accept-api" >> $GITHUB_STEP_SUMMARY
# echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
# echo "and review the changes, then commit them if desired." >> $GITHUB_STEP_SUMMARY
# echo "" >> $GITHUB_STEP_SUMMARY
# ===================
gh-cc-table:
name: Update CC implementation status
# Only run for master branch and don't run in forks
if: |
github.repository == 'zwave-js/node-zwave-js' &&
github.ref == 'refs/heads/master' &&
github.event_name == 'push'
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Update CC table # (maybe)
uses: actions/github-script@v7
with:
github-token: ${{secrets.BOT_TOKEN}}
result-encoding: string
script: |
const main = require(`${process.env.GITHUB_WORKSPACE}/.github/action-scripts/updateCCImplementationOverview.cjs`);
return main({github, context});
# ===================
generate-overview:
name: Update toLogEntry overview
# Only run for master branch and don't run in forks
if: |
github.repository == 'zwave-js/node-zwave-js' &&
github.ref == 'refs/heads/master' &&
github.event_name == 'push'
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Update overview
uses: actions/github-script@v7
with:
github-token: ${{secrets.BOT_TOKEN}}
result-encoding: string
script: |
const main = require(`${process.env.GITHUB_WORKSPACE}/.github/action-scripts/updateToLogEntryOverview.cjs`);
return main({github, context});
# ===================
# Deploys the final package to NPM
deploy:
# Trigger this step only when a commit on any branch is tagged with a version number
if: |
github.actor == 'AlCalzone' &&
github.event_name == 'push' &&
startsWith(github.ref, 'refs/tags/v')
needs:
- build
- lint
- lint-zwave
- unit-tests
- test-transformers
- test-packages
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18] # This should be LTS
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Restore Turbo Cache from previous jobs
uses: ./.github/actions/build-cache-download
- name: Prepare testing environment
uses: ./.github/actions/prepare-env
with:
node-version: ${{ matrix.node-version }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Compile TypeScript code
run: yarn build $TURBO_FLAGS
- name: Extract the version and commit body from the tag
id: extract_release
# The body may be multiline, therefore we need to escape some characters
run: |
VERSION="${{ github.ref }}"
VERSION=${VERSION##*/v}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
EOF=$(od -An -N6 -x /dev/urandom | tr -d ' ')
BODY=$(git show -s --format=%b)
echo "BODY<<$EOF" >> $GITHUB_OUTPUT
echo "$BODY" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
if [[ $VERSION == *"-"* ]] ; then
echo "TAG=--tag next" >> $GITHUB_OUTPUT
fi
- name: Publish packages to npm
env:
TAG: ${{ steps.extract_release.outputs.TAG }}
run: |
yarn config set npmAuthToken "${{ secrets.NPM_TOKEN }}"
yarn npm whoami
yarn workspaces foreach --all -vti --no-private npm publish --tolerate-republish $TAG
- name: Create Github Release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
name: Release v${{ steps.extract_release.outputs.VERSION }}
draft: false
# Prerelease versions create prereleases on Github
prerelease: ${{ contains(steps.extract_release.outputs.VERSION, '-') }}
body: ${{ steps.extract_release.outputs.BODY }}
# - name: Notify Sentry.io about the release
# run: |
# npm i -g @sentry/cli
# export SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
# export SENTRY_URL=https://sentry.iobroker.net
# export SENTRY_ORG=iobroker
# export SENTRY_PROJECT=zwave-js
# export SENTRY_VERSION=zwave-js@${{ steps.extract_release.outputs.VERSION }}
# sentry-cli releases new $SENTRY_VERSION
# # Commits disabled until the Github integration can be enabled
# sentry-cli releases set-commits $SENTRY_VERSION --auto
# sentry-cli releases files $SENTRY_VERSION upload-sourcemaps ./packages/*/build
# sentry-cli releases finalize $SENTRY_VERSION