1
+ ---
1
2
name : CI & Release
3
+
2
4
on :
3
- # Build on pushes to release branches
4
- push :
5
- branches : ["main"]
6
- # Build on pull requests targeting release branches
5
+ # Build on pushes branches that have a PR (including drafts)
7
6
pull_request :
8
- branches : ["main"]
7
+ # Build on commits pushed to branches without a PR if it's in the allowlist
8
+ push :
9
+ branches : [main]
10
+ # https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow
9
11
workflow_dispatch :
10
12
inputs :
13
+ test :
14
+ description : Run tests
15
+ required : true
16
+ default : true
17
+ type : boolean
11
18
release :
12
19
description : Release new version
13
20
required : true
14
21
default : false
15
22
type : boolean
16
23
24
+ concurrency :
25
+ # On PRs builds will cancel if new pushes happen before the CI completes, as it defines `github.head_ref` and gives it the name of the branch the PR wants to merge into
26
+ # Otherwise `github.run_id` ensures that you can quickly merge a queue of PRs without causing tests to auto cancel on any of the commits pushed to main.
27
+ group : ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
28
+ cancel-in-progress : true
29
+
17
30
jobs :
18
31
log-the-inputs :
19
32
name : Log inputs
@@ -25,45 +38,63 @@ jobs:
25
38
INPUTS: ${{ toJSON(inputs) }}
26
39
27
40
build :
28
- name : Lint & Build
29
41
runs-on : ubuntu-latest
42
+ name : Lint & Build
30
43
steps :
31
- - name : Set git to use LF
32
- run : |
33
- git config --global core.autocrlf false
34
- git config --global core.eol lf
35
44
- uses : actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
36
45
- uses : actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3
37
46
with :
38
- node-version : lts/*
39
47
cache : npm
48
+ node-version : lts/*
40
49
- run : npm ci
50
+ # Linting can be skipped
41
51
- run : npm run lint --if-present
42
- - run : npm run prepublishOnly
52
+ if : github.event.inputs.test != 'false'
53
+ # But not the build script, as semantic-release will crash if this command fails so it makes sense to test it early
54
+ - run : npm run prepublishOnly --if-present
43
55
44
56
test :
45
- name : Test
46
57
needs : build
58
+ # The test matrix can be skipped, in case a new release needs to be fast-tracked and tests are already passing on main
59
+ if : github.event.inputs.test != 'false'
60
+ runs-on : ${{ matrix.os }}
61
+ name : Node.js ${{ matrix.node }} / ${{ matrix.os }}
47
62
strategy :
63
+ # A test failing on windows doesn't mean it'll fail on macos. It's useful to let all tests run to its completion to get the full picture
64
+ fail-fast : false
48
65
matrix :
49
- os : [ macos-latest, ubuntu-latest ]
50
- node : [ lts/*, current ]
51
- runs-on : ${{ matrix.os }}
66
+ # Run the testing suite on each major OS with the latest LTS release of Node.js
67
+ os : [macos-latest, ubuntu-latest, windows-latest]
68
+ node : [lts/*]
69
+ # It makes sense to also test the oldest, and latest, versions of Node.js, on ubuntu-only since it's the fastest CI runner
70
+ include :
71
+ - os : ubuntu-latest
72
+ # Test the oldest LTS release of Node that's still receiving bugfixes and security patches, versions older than that have reached End-of-Life
73
+ node : lts/-2
74
+ - os : ubuntu-latest
75
+ # Test the actively developed version that will become the latest LTS release next October
76
+ node : current
52
77
steps :
78
+ # It's only necessary to do this for windows, as mac and ubuntu are sane OS's that already use LF
79
+ - name : Set git to use LF
80
+ if : matrix.os == 'windows-latest'
81
+ run : |
82
+ git config --global core.autocrlf false
83
+ git config --global core.eol lf
53
84
- uses : actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
54
85
- uses : actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3
55
86
with :
56
- node-version : ${{ matrix.node }}
57
87
cache : npm
88
+ node-version : ${{ matrix.node }}
58
89
- run : npm ci
59
- - run : npm test --if-present
90
+ - run : npm test
60
91
61
92
release :
62
- name : Semantic release
63
- needs : test
64
- runs-on : ubuntu-latest
93
+ needs : [build, test]
65
94
# only run if opt-in during workflow_dispatch
66
- if : inputs.release == true
95
+ if : always() && github.event.inputs.release == 'true' && needs.build.result != 'failure' && needs.test.result != 'failure' && needs.test.result != 'cancelled'
96
+ runs-on : ubuntu-latest
97
+ name : Semantic release
67
98
steps :
68
99
- uses : actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
69
100
with :
72
103
fetch-depth : 0
73
104
- uses : actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3
74
105
with :
75
- node-version : lts/*
76
106
cache : npm
107
+ node-version : lts/*
77
108
- run : npm ci
78
109
# Branches that will release new versions are defined in .releaserc.json
79
110
- run : npx semantic-release
83
114
env :
84
115
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
85
116
NPM_TOKEN : ${{ secrets.NPM_PUBLISH_TOKEN }}
117
+ # Re-run semantic release with rich logs if it failed to publish for easier debugging
118
+ - run : npx semantic-release --dry-run --debug
119
+ if : failure()
120
+ env :
121
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
122
+ NPM_TOKEN : ${{ secrets.NPM_PUBLISH_TOKEN }}
0 commit comments