forked from Zettlr/Zettlr
-
Notifications
You must be signed in to change notification settings - Fork 0
472 lines (457 loc) · 21.2 KB
/
build.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
name: Build
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# ZETTLR MAIN BUILD GITHUB ACTIONS FILE #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# This file contains the logic necessary to build a full release from source. #
# #
# WHEN IT RUNS: #
# #
# * Whenever someone successfully pushes develop --> master. #
# * Every Monday at noon (UTC) #
# * Manually #
# #
# The last two events are being used to create nightly releases. The first #
# event type indicates that the pipeline should build a regular release. #
# #
# HOW IT RUNS: #
# #
# 1. Three virtual machines are spun up in parallel: A Windows VM, a Ubuntu #
# VM, and a macOS VM. All three are tasked with building all releases that #
# we offer for the given platform. The Ubuntu VM builds the most since we #
# have many more Linux releases. Windows and macOS only build one x64 and #
# one ARM release. However, they also perform code signing (and #
# notarization in case of the macOS VM), which the Ubuntu VM doesn't do. #
# 2. Each VM uploads all resulting artifacts into their respective artifact #
# space, named "linux", "darwin", and "win32" respectively (analogous to #
# node.js's process.platform-variable). #
# 3. Iff (if and only if) all three runners have shut down successfully, #
# indicating successful builds, another Ubuntu VM will be started. That #
# one is tasked with downloading all releases from the three artifact #
# spaces, calculate the SHA-256 checksums for every file and afterwards #
# upload all files: In case of a nightly to the Zettlr server, where they #
# can be downloaded from nightly.zettlr.com, or, in case of a regular #
# release, to a newly created release draft here on GitHub. #
# #
# THINGS TO NOTE: #
# #
# * Every runner will retrieve the package.json's "version" field by running #
# a somewhat weird-looking command. This is necessary to make finding the #
# releases easier which are being produced by electron-forge and electron- #
# builder. #
# * Especially the macOS runner can often produce problems, because there #
# have been rumors that apparently even the macOS server operating systems #
# tend to open modal windows -- even though they're running headless. This #
# means that in case the macOS runners seem to hang it's likely we again #
# need to update the add-osx-cert.sh script. #
# * Everything is being run on Bash. Although PowerShell can do a lot, this #
# way all steps are within one language, making it easier to maintain. #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
on:
push:
branches:
- master
workflow_dispatch: {} # Used to manually trigger a nightly build.
schedule: # Every Monday at noon (UTC) we run a scheduled nightly build
- cron: '0 12 * * 1'
# Defaults for every job and step in this workflow
defaults:
run:
shell: bash # Run everything using bash
# Global environment variables
env:
NODE_VERSION: '20'
# Ensure only a single build workflow runs at any one time
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
# This workflow file contains four jobs, three to build the corresponding
# releases on all three supported platforms, and a last one, which will
# create the release draft.
jobs:
# First, ensure that nothing breaks before attempting to build
preflight:
name: 'Preflight: Lint/Unit tests'
uses: ./.github/workflows/check.yml
# If we're building a full release, we have to make sure that nobody (that is:
# Hendrik) forgot to increment the tag version. If we already have a tag with
# this version, we should not proceed, because that will then lead to an
# overwriting of the files in the previous release. That doesn't wreak any
# havoc because we don't push unstable code to master, BUT it looks bad.
verify_version:
name: 'Preflight: Verify version tag'
runs-on: ubuntu-22.04
steps:
- name: Clone repository (master branch)
uses: actions/checkout@v4
with:
ref: 'master'
fetch-depth: 0 # Required for the tag verification step.
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
- name: Verify the corresponding tag does not yet exist
if: github.ref_name == 'master'
# NOTE: the ! will return 0 if the command fails, and 1 otherwise
run: '! git rev-parse "v${{env.version}}"'
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# WINDOWS BUILDS #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
build_win_x64:
name: Windows (x86_64)
env:
npm_config_arch: x64
needs: [preflight, verify_version]
runs-on: windows-latest
steps:
- name: Checkout branch ${{ github.ref_name }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Set up build environment
run: yarn install --immutable
- name: Set tag version to nightly
if: github.ref_name == 'develop'
# run: echo "$(cat package.json | jq --arg commit "$(git rev-parse --short HEAD)" '.version = .version + "-nightly+" + $commit')" > package.json
run: echo "$(cat package.json | jq '.version = .version + "-nightly"')" > package.json
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
- name: Package & Release
run: yarn package:win-x64 && yarn release:win-x64
env:
CSC_LINK: ${{ secrets.WIN_CERT_2025_03_15 }}
CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_PASS_2025_03_15 }}
- name: Cache installer
uses: actions/upload-artifact@v4
with:
name: win32_x64
path: |
./release/Zettlr-${{env.version}}-x64.exe
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# MACOS BUILDS #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
build_macos_x64:
name: macOS (x86_64)
env:
npm_config_arch: x64
needs: [preflight, verify_version]
runs-on: macos-latest
steps:
# Check out master for a regular release, or develop branch for a nightly
- name: Checkout branch ${{ github.ref_name }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Set up build environment
run: yarn install --immutable
- name: Set tag version to nightly
if: github.ref_name == 'develop'
# run: echo "$(cat package.json | jq --arg commit "$(git rev-parse --short HEAD)" '.version = .version + "-nightly+" + $commit')" > package.json
run: echo "$(cat package.json | jq '.version = .version + "-nightly"')" > package.json
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
# Save the macOS certificate on this runner for forge to access it in the
# next step below.
- name: Retrieve code signing certificate
run: ./scripts/add-osx-cert.sh
env:
MACOS_CERT: ${{ secrets.MACOS_CERT }}
MACOS_CERT_PASS: ${{ secrets.MACOS_CERT_PASS }}
- name: Package
run: yarn package:mac-x64
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
- name: Release
run: yarn release:mac-x64
- name: Cache image file
uses: actions/upload-artifact@v4
with:
name: darwin_x64
path: |
./release/Zettlr-${{env.version}}-x64.dmg
build_macos_arm64:
name: macOS (arm64)
env:
npm_config_arch: arm64
needs: [preflight, verify_version]
runs-on: macos-latest
steps:
- name: Checkout branch ${{ github.ref_name }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Set up build environment
run: yarn install --immutable
- name: Set tag version to nightly
if: github.ref_name == 'develop'
# run: echo "$(cat package.json | jq --arg commit "$(git rev-parse --short HEAD)" '.version = .version + "-nightly+" + $commit')" > package.json
run: echo "$(cat package.json | jq '.version = .version + "-nightly"')" > package.json
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
# Save the macOS certificate on this runner for forge to access it in the
# next step below.
- name: Retrieve code signing certificate
run: ./scripts/add-osx-cert.sh
env:
MACOS_CERT: ${{ secrets.MACOS_CERT }}
MACOS_CERT_PASS: ${{ secrets.MACOS_CERT_PASS }}
- name: Package
run: yarn package:mac-arm
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
- name: Release
run: yarn release:mac-arm
- name: Cache image file
uses: actions/upload-artifact@v4
with:
name: darwin_arm64
path: |
./release/Zettlr-${{env.version}}-arm64.dmg
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# LINUX BUILDS #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
build_linux_x64:
name: Linux (x86_64)
env:
npm_config_arch: x64
needs: [preflight, verify_version]
runs-on: ubuntu-22.04
steps:
# Check out master for a regular release, or develop branch for a nightly
- name: Checkout branch ${{ github.ref_name }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Set up build environment
run: yarn install --immutable
- name: Set tag version to nightly
# If this a scheduled workflow, we know that we should build a nightly
if: github.ref_name == 'develop'
# run: echo "$(cat package.json | jq --arg commit "$(git rev-parse --short HEAD)" '.version = .version + "-nightly+" + $commit')" > package.json
run: echo "$(cat package.json | jq '.version = .version + "-nightly"')" > package.json
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
- name: Package & Release
run: |
yarn package:linux-x64
yarn release:linux-x64
- name: Cache installers
uses: actions/upload-artifact@v4
with:
name: linux_x64
path: |
./release/Zettlr-${{env.version}}-amd64.deb
./release/Zettlr-${{env.version}}-x86_64.rpm
./release/Zettlr-${{env.version}}-x86_64.AppImage
build_linux_arm64:
name: Linux (arm64)
env:
npm_config_arch: arm64
CC: zig cc -target aarch64-linux-gnu
CXX: zig c++ -target aarch64-linux-gnu
needs: [preflight, verify_version]
runs-on: ubuntu-22.04
steps:
- name: Checkout branch ${{ github.ref_name }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Install Zig
uses: goto-bus-stop/setup-zig@v2
- name: Set up build environment
run: yarn install --immutable
- name: Set tag version to nightly
if: github.ref_name == 'develop'
# run: echo "$(cat package.json | jq --arg commit "$(git rev-parse --short HEAD)" '.version = .version + "-nightly+" + $commit')" > package.json
run: echo "$(cat package.json | jq '.version = .version + "-nightly"')" > package.json
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
- name: Package & Release
run: |
yarn package:linux-arm
yarn release:linux-arm
- name: Cache installers
uses: actions/upload-artifact@v4
with:
name: linux_arm64
path: |
./release/Zettlr-${{env.version}}-arm64.deb
./release/Zettlr-${{env.version}}-aarch64.rpm
./release/Zettlr-${{env.version}}-arm64.AppImage
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# PREPARE RELEASE DRAFT #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# After the three builds, this job downloads all assets, creates and verifies
# SHA256 checksums, and finally creates a release draft and uploads all
# assets to it. NOTE: If the workflow detects a nightly is being built, this
# step rather uploads the binaries to the Zettlr server instead of creating
# a release draft.
prepare_release:
name: Prepare release draft
# Make sure (and wait until) the builds have succeeded
needs:
- build_win_x64
# - build_win_arm64 # DEBUG: Disable win arm for now
- build_macos_x64
- build_macos_arm64
- build_linux_x64
- build_linux_arm64
runs-on: ubuntu-22.04
steps:
- name: Checkout branch ${{ github.ref_name }}
uses: actions/checkout@v4
- name: Setup NodeJS ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Set up build environment
run: yarn install --immutable
- name: Set tag version to nightly
if: github.ref_name == 'develop'
# run: echo "$(cat package.json | jq --arg commit "$(git rev-parse --short HEAD)" '.version = .version + "-nightly+" + $commit')" > package.json
run: echo "$(cat package.json | jq '.version = .version + "-nightly"')" > package.json
- name: Retrieve tag version
id: ref
run: echo "version=$(cat package.json | jq -r '.version')" >> $GITHUB_ENV
- name: Make release directory
run: mkdir ./release
# Download all resulting assets from the previous steps.
- name: Retrieve installers (Windows x86_64)
uses: actions/download-artifact@v4
with:
name: win32_x64
path: ./release
- name: Retrieve installers (macOS x86_64)
uses: actions/download-artifact@v4
with:
name: darwin_x64
path: ./release
- name: Retrieve installers (macOS arm64)
uses: actions/download-artifact@v4
with:
name: darwin_arm64
path: ./release
- name: Retrieve installers (Linux x86_64)
uses: actions/download-artifact@v4
with:
name: linux_x64
path: ./release
- name: Retrieve installers (Linux arm64)
uses: actions/download-artifact@v4
with:
name: linux_arm64
path: ./release
# Generate the checksums
- name: Generate SHA256 checksums
# sha256sum "Zettlr-${{env.version}}-arm64.exe" >> "SHA256SUMS.txt" # DEBUG: Disable win arm for now
run: |
cd ./release
sha256sum "Zettlr-${{env.version}}-x64.exe" > "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-x64.dmg" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-arm64.dmg" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-x86_64.AppImage" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-arm64.AppImage" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-amd64.deb" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-arm64.deb" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-x86_64.rpm" >> "SHA256SUMS.txt"
sha256sum "Zettlr-${{env.version}}-aarch64.rpm" >> "SHA256SUMS.txt"
cd ..
- name: Verify checksums
run: |
cd ./release
sha256sum -c SHA256SUMS.txt
cd ..
# IF WE BUILD A NIGHTLY, AT THIS POINT JUST UPLOAD TO THE SERVER.
# We must make sure to copy the three additional files
# to the release folder because of the --delete flag in rsync below.
- name: Copy Nightly Static Files
if: github.ref_name == 'develop'
run: |
cp ./scripts/assets/nightly-index.php ./release/index.php
cp ./scripts/assets/nightly-sm_preview.png ./release/sm_preview.png
cp ./resources/icons/png/512x512.png ./release/logo.png
- name: Upload nightlies to the server
if: github.ref_name == 'develop'
uses: easingthemes/ssh-deploy@v3.0.1
env:
SSH_PRIVATE_KEY: ${{ secrets.NIGHTLY_SSH_PRIVATE_KEY }}
# --delete so that no old releases remain on the server. Each iteration is approx. 1GB in size.
ARGS: "-vzhr --delete" # verbose, compress, human-readble, recursive, delete
SOURCE: "release/"
REMOTE_HOST: ${{ secrets.NIGHTLY_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.NIGHTLY_REMOTE_USER }}
TARGET: ${{ secrets.NIGHTLY_TARGET }}
# OTHERWISE: Create a new release draft
- name: Create release draft
if: github.ref_name == 'master'
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Populate the inputs of the release we already know
tag_name: v${{env.version}}
name: Release v${{env.version}}
body: If you can read this, we have forgotten to fill in the changelog. Sorry!
draft: true # Always create as draft, so that we can populate the remaining values easily
# Gosh, is that convenient as opposed to earlier!
files: |
./release/Zettlr-${{env.version}}-x64.exe
./release/Zettlr-${{env.version}}-arm64.exe
./release/Zettlr-${{env.version}}-x64.dmg
./release/Zettlr-${{env.version}}-arm64.dmg
./release/Zettlr-${{env.version}}-amd64.deb
./release/Zettlr-${{env.version}}-arm64.deb
./release/Zettlr-${{env.version}}-x86_64.rpm
./release/Zettlr-${{env.version}}-aarch64.rpm
./release/Zettlr-${{env.version}}-x86_64.AppImage
./release/Zettlr-${{env.version}}-arm64.AppImage
./release/SHA256SUMS.txt