@@ -2,61 +2,151 @@ name: CI
22
33on :
44 push :
5- branches : [main]
5+ branches : [' main' ]
66 pull_request :
7- branches : [main]
7+ branches : [' main' ]
88
99concurrency :
1010 group : ${{ github.workflow }}-${{ github.ref }}
1111 cancel-in-progress : true
1212
13+ permissions :
14+ contents : write
15+ id-token : write
16+
1317jobs :
14- lint :
15- name : Lint & Format
18+ check :
19+ name : Lint, Format & Test
1620 runs-on : ubuntu-latest
21+
22+ # Skip release commits pushed by the release workflow
23+ if : ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }}
24+
1725 steps :
18- - uses : actions/checkout@v4
19- - uses : actions/setup-node@v4
26+ - name : Checkout repository
27+ uses : actions/checkout@v5
28+
29+ - name : Setup Node.js
30+ uses : actions/setup-node@v5
2031 with :
2132 node-version-file : .nvmrc
22- cache : npm
23- - run : npm ci
24- - run : npm run format:check
25- - run : npm run lint
33+ cache : ' npm'
34+ cache-dependency-path : package-lock.json
35+
36+ - name : Install dependencies
37+ run : npm ci --prefer-offline --no-audit --no-fund
38+
39+ - name : Run format check
40+ run : npm run format:check
41+
42+ - name : Run linter
43+ run : npm run lint
44+
45+ - name : Run typecheck
46+ run : npx tsc --noEmit
2647
27- typecheck :
28- name : Typecheck
48+ - name : Run tests
49+ run : npm test
50+
51+ build :
52+ name : Build
2953 runs-on : ubuntu-latest
54+ needs : [check]
3055 steps :
31- - uses : actions/checkout@v4
32- - uses : actions/setup-node@v4
56+ - name : Checkout repository
57+ uses : actions/checkout@v5
58+
59+ - name : Setup Node.js
60+ uses : actions/setup-node@v5
3361 with :
3462 node-version-file : .nvmrc
35- cache : npm
36- - run : npm ci
37- - run : npx tsc --noEmit
63+ cache : ' npm'
64+ cache-dependency-path : package-lock.json
3865
39- test :
40- name : Test
66+ - name : Install dependencies
67+ run : npm ci --prefer-offline --no-audit --no-fund
68+
69+ - name : Build
70+ run : npm run build:only
71+
72+ release :
73+ name : Release
4174 runs-on : ubuntu-latest
75+ needs : [build]
76+
77+ # Only release on push to main, not on PRs
78+ if : ${{ github.event_name == 'push' }}
79+
4280 steps :
43- - uses : actions/checkout@v4
44- - uses : actions/setup-node@v4
81+ - name : Checkout repository
82+ uses : actions/checkout@v5
4583 with :
46- node-version-file : .nvmrc
47- cache : npm
48- - run : npm ci
49- - run : npm test
84+ fetch-depth : 0
5085
51- build :
52- name : Build
53- runs-on : ubuntu-latest
54- needs : [lint, typecheck, test]
55- steps :
56- - uses : actions/checkout@v4
57- - uses : actions/setup-node@v4
86+ - name : Install git-cliff
87+ uses : kenji-miyake/setup-git-cliff@v2
88+
89+ - name : Determine next version
90+ id : version
91+ run : |
92+ NEXT=$(git-cliff --bumped-version 2>/dev/null)
93+ CURRENT=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
94+ if [ "$NEXT" = "$CURRENT" ]; then
95+ echo "No version bump needed"
96+ echo "bump=false" >> "$GITHUB_OUTPUT"
97+ else
98+ echo "Next version: $NEXT"
99+ echo "bump=true" >> "$GITHUB_OUTPUT"
100+ echo "version=$NEXT" >> "$GITHUB_OUTPUT"
101+ fi
102+
103+ - name : Setup Node.js
104+ if : steps.version.outputs.bump == 'true'
105+ uses : actions/setup-node@v5
58106 with :
59107 node-version-file : .nvmrc
60- cache : npm
61- - run : npm ci
62- - run : npm run build:only
108+ cache : ' npm'
109+ cache-dependency-path : package-lock.json
110+ registry-url : ' https://registry.npmjs.org'
111+
112+ - name : Install dependencies
113+ if : steps.version.outputs.bump == 'true'
114+ run : npm ci --prefer-offline --no-audit --no-fund
115+
116+ - name : Build
117+ if : steps.version.outputs.bump == 'true'
118+ run : npm run build:only
119+
120+ - name : Bump package.json version
121+ if : steps.version.outputs.bump == 'true'
122+ run : npm version "${{ steps.version.outputs.version }}" --no-git-tag-version
123+
124+ - name : Generate changelog
125+ if : steps.version.outputs.bump == 'true'
126+ run : git-cliff --tag "${{ steps.version.outputs.version }}" -o CHANGELOG.md
127+
128+ - name : Commit and tag
129+ if : steps.version.outputs.bump == 'true'
130+ run : |
131+ git config user.name "github-actions[bot]"
132+ git config user.email "github-actions[bot]@users.noreply.github.com"
133+ git add package.json package-lock.json CHANGELOG.md
134+ git commit -m "chore(release): ${{ steps.version.outputs.version }}"
135+ git tag -a "${{ steps.version.outputs.version }}" -m "${{ steps.version.outputs.version }}"
136+ git push origin main --follow-tags
137+
138+ - name : Publish to npm
139+ if : steps.version.outputs.bump == 'true'
140+ run : npm publish --provenance --access public --ignore-scripts
141+ env :
142+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
143+
144+ - name : Generate release notes
145+ if : steps.version.outputs.bump == 'true'
146+ run : git-cliff --latest --strip header > RELEASE_NOTES.md
147+
148+ - name : Create GitHub Release
149+ if : steps.version.outputs.bump == 'true'
150+ run : gh release create "${{ steps.version.outputs.version }}" --title "${{ steps.version.outputs.version }}" --notes-file RELEASE_NOTES.md
151+ env :
152+ GH_TOKEN : ${{ github.token }}
0 commit comments