Repository navigation
363 lines (315 loc) · 10.9 KB
/
Copy pathrelease-portable.yml
File metadata and controls
363 lines (315 loc) · 10.9 KB
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
name: CI/CD Desktop Releases
on:
push:
branches:
- main
permissions:
contents: read
concurrency:
group: release-main
cancel-in-progress: false
jobs:
quality:
name: Lint and audit
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: "3.12"
- name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b
with:
enable-cache: true
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: "22"
cache: npm
cache-dependency-path: |
bdgen/web/package-lock.json
bdgen/desktop/package-lock.json
- name: Install backend dependencies
run: uv sync
working-directory: bdgen
env:
UV_PROJECT_ENVIRONMENT: ../.venv
- name: Install frontend dependencies
run: npm ci
working-directory: bdgen/web
- name: Install desktop dependencies
run: npm ci
working-directory: bdgen/desktop
- name: Run all linters
run: make lint
- name: Audit frontend dependencies
run: npm audit
working-directory: bdgen/web
- name: Audit desktop dependencies
run: npm audit
working-directory: bdgen/desktop
test:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: "3.12"
- name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b
with:
enable-cache: true
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: "22"
cache: npm
cache-dependency-path: bdgen/web/package-lock.json
- name: Install backend dependencies
run: uv sync
working-directory: bdgen
env:
UV_PROJECT_ENVIRONMENT: ../.venv
- name: Install frontend dependencies
run: npm ci
working-directory: bdgen/web
- name: Run backend tests
run: uv run pytest
working-directory: bdgen
env:
UV_PROJECT_ENVIRONMENT: ../.venv
- name: Run frontend tests
run: npm test
working-directory: bdgen/web
version:
name: Compute release version
runs-on: ubuntu-latest
needs:
- quality
- test
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
tag_exists: ${{ steps.version.outputs.tag_exists }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
persist-credentials: false
- name: Compute next SemVer
id: version
shell: pwsh
run: |
$tags = git tag --list "v[0-9]*" | Where-Object { $_ -match '^v\d+\.\d+\.\d+$' } | Sort-Object { [version]($_.Substring(1)) }
$headTag = git tag --points-at HEAD --list "v[0-9]*" | Where-Object { $_ -match '^v\d+\.\d+\.\d+$' } | Sort-Object { [version]($_.Substring(1)) } | Select-Object -Last 1
if ($headTag) {
$version = $headTag.Substring(1)
"version=$version" >> $env:GITHUB_OUTPUT
"tag=$headTag" >> $env:GITHUB_OUTPUT
"tag_exists=true" >> $env:GITHUB_OUTPUT
exit 0
}
$lastTag = $tags | Select-Object -Last 1
if ($lastTag) {
$base = [version]$lastTag.Substring(1)
$messages = git log --format=%B "$lastTag..HEAD"
} else {
$package = Get-Content -Raw "bdgen/desktop/package.json" | ConvertFrom-Json
$base = [version]$package.version
$messages = git log --format=%B
}
$bump = "patch"
if ($messages -match "(?m)^BREAKING CHANGE:" -or $messages -match "(?m)^[a-zA-Z]+(\([^)]+\))?!:") {
$bump = "major"
} elseif ($messages -match "(?m)^feat(\([^)]+\))?:") {
$bump = "minor"
}
if ($bump -eq "major") {
$version = "$($base.Major + 1).0.0"
} elseif ($bump -eq "minor") {
$version = "$($base.Major).$($base.Minor + 1).0"
} else {
$version = "$($base.Major).$($base.Minor).$($base.Build + 1)"
}
"version=$version" >> $env:GITHUB_OUTPUT
"tag=v$version" >> $env:GITHUB_OUTPUT
"tag_exists=false" >> $env:GITHUB_OUTPUT
tag-release:
name: Create release tag
runs-on: ubuntu-latest
needs: version
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
persist-credentials: true
- name: Create git tag
if: needs.version.outputs.tag_exists == 'false'
env:
TAG: ${{ needs.version.outputs.tag }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag "$TAG"
git push origin "refs/tags/$TAG"
build-desktop:
name: Build ${{ matrix.label }}
runs-on: ${{ matrix.os }}
needs:
- version
- tag-release
strategy:
fail-fast: false
matrix:
include:
- platform: windows
label: Windows portable exe
os: windows-latest
build_script: build:windows
backend_binary: ../build/backend/bdgen-server.exe
artifact_name: windows-portable
artifact_path: build/portable/*.exe
- platform: macos
label: unsigned macOS DMG
os: macos-latest
build_script: build:mac
backend_binary: ../build/backend/bdgen-server
artifact_name: macos-dmg-unsigned
artifact_path: build/mac/*.dmg
- platform: linux
label: Linux AppImage
os: ubuntu-latest
build_script: build:linux
backend_binary: ../build/backend/bdgen-server
artifact_name: linux-appimage
artifact_path: build/linux/*.AppImage
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: "3.12"
- name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b
with:
enable-cache: true
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: "22"
cache: npm
cache-dependency-path: |
bdgen/web/package-lock.json
bdgen/desktop/package-lock.json
- name: Apply desktop package version
shell: pwsh
env:
VERSION: ${{ needs.version.outputs.version }}
run: npm version $env:VERSION --no-git-tag-version --allow-same-version
working-directory: bdgen/desktop
- name: Install backend dependencies
run: uv sync
working-directory: bdgen
env:
UV_PROJECT_ENVIRONMENT: ../.venv
- name: Build frontend static assets
run: |
npm ci
npm run build
working-directory: bdgen/web
- name: Build backend executable
shell: pwsh
run: |
uv run pyinstaller --distpath ../build/backend --workpath ../build/pyinstaller-work bdgen-server.spec
if (!(Test-Path -LiteralPath "${{ matrix.backend_binary }}")) {
throw "Missing backend executable: ${{ matrix.backend_binary }}"
}
if ("${{ matrix.platform }}" -ne "windows") {
chmod +x "${{ matrix.backend_binary }}"
}
if ("${{ matrix.platform }}" -eq "macos") {
codesign --force --sign - "${{ matrix.backend_binary }}"
}
working-directory: bdgen
env:
UV_PROJECT_ENVIRONMENT: ../.venv
- name: Build desktop artifact
run: |
npm ci
npm run ${{ matrix.build_script }}
working-directory: bdgen/desktop
env:
CSC_IDENTITY_AUTO_DISCOVERY: "false"
- name: Upload workflow artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: BdGEN-${{ needs.version.outputs.version }}-${{ matrix.artifact_name }}
path: ${{ matrix.artifact_path }}
if-no-files-found: error
publish-release:
name: Publish GitHub release
runs-on: ubuntu-latest
needs:
- version
- tag-release
- build-desktop
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
persist-credentials: false
- name: Download release artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
path: release-artifacts
merge-multiple: true
- name: Publish GitHub release
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.version.outputs.tag }}
VERSION: ${{ needs.version.outputs.version }}
run: |
shopt -s nullglob
assets=(release-artifacts/*.exe release-artifacts/*.dmg release-artifacts/*.AppImage exemple.bdgen)
if [ ${#assets[@]} -eq 0 ]; then
echo "No release assets found." >&2
exit 1
fi
notes=$(cat <<EOF
Automated desktop release for BdGEN $VERSION.
Quality gates:
- Backend (pytest) and frontend (vitest) tests passed.
- Backend, frontend and desktop lint passed.
- Frontend and desktop npm audit passed with no vulnerabilities.
Artifacts:
- Windows portable executable.
- Unsigned macOS DMG.
- Linux AppImage.
- Bundled example project archive (exemple.bdgen).
Note: the macOS DMG is not signed or notarized yet, so Gatekeeper may warn on first launch.
EOF
)
if gh release view "$TAG" >/dev/null 2>&1; then
gh release upload "$TAG" "${assets[@]}" --clobber
else
gh release create "$TAG" "${assets[@]}" --title "BdGEN $VERSION" --notes "$notes"
fi