-
Notifications
You must be signed in to change notification settings - Fork 43
431 lines (417 loc) · 18.7 KB
/
publish-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
name: Build, sign and publish release
# this workflow needs the following secrets set up:
#
# ARTIFACTORY_PASSWORD mongoDB artifactory password
# ARTIFACTORY_USER matching username
# GRS_PASSWORD Password for the Windows/Linux signer
# GRS_USERNAME Username for the Windows/Linux signer
# NOTARY_KEY_ID Key id for the macOS notary
# NOTARY_SECRET Secret for the macOS notary
# AWS_S3_ACCESS_KEY_ID Access key with write access to the release bucket
# AWS_S3_SECRET_ACCESS_KEY The matching secret key
# WG_CONFIG A complete wireguard configuration file for notary access
on:
workflow_dispatch:
inputs:
dry_run:
type: boolean
default: false
description: "Skip creating and merging PRs, posting messages and uploading artifacts to a test bucket"
env:
GRS_CONFIG_USER1_USERNAME: ${{ secrets.grs_username }}
GRS_CONFIG_USER1_PASSWORD: ${{ secrets.grs_password }}
S3_BUCKET: ${{ vars.AWS_S3_BUCKET }}
jobs:
build_sign_lw:
name: Build/sign Windows/Linux
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install wine
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt install -y wine wine32
- name: Install dependencies
run: npm ci
- name: Build the bundle
run: npm run build
- name: Store package version in environment
run: |
PACKAGE_VERSION=`jq -r '.version' package.json`
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV
# Both the Windows executable as well as the installer need to be signed.
# Electron builder will not rebuild existing files, even if they are
# different from the build results - that behaviour could be used to have
# it stop before packing everything into installers to sign the relevant
# binaries in place. Additionally there's also the option to pack up a
# prepared directory - as that's documented we're going with that one.
#
# Building for additional architectures works without conflicts - so to
# enable arm64 builds for Windows and Linux just add --arm64 here
- name: Prepare installer contents
run: |
npx electron-builder -lw --publish never --dir --x64
# Copying over the app-update.yml from Linux as it is skipped when using --dir
# https://github.com/electron-userland/electron-builder/blob/79df54238621fbe48ba20444129950ba2dc49983/packages/app-builder-lib/src/publish/PublishManager.ts#L113-L115
cat dist/linux-unpacked/resources/app-update.yml
cp dist/linux-unpacked/resources/app-update.yml dist/win-unpacked/resources/app-update.yml
# Docker actions don't seem to support supplying credentials, so log in
# manually
- name: Log in to mongodb registry
uses: docker/login-action@v3
with:
registry: artifactory.corp.mongodb.com
username: ${{ secrets.artifactory_user }}
password: ${{ secrets.artifactory_password }}
# Without having the image available locally the docker action referencing
# an image behind a registry requiring authentication may throw an error
# trying to pull the image - so we manually pull the image.
#
# A docker action has two ways of specifying the container to run:
# - container image, in which case this pull is required
# - Dockerfile, where it builds the image before launching in. In that
# case the pull is not required
# Dockerfile is most sensible when specifying ENTRYPOINT, and a separate
# entrypoint script - which in our simple case would just add two files
# for no added benefit.
- name: pull docker image
run: docker pull artifactory.corp.mongodb.com/release-tools-container-registry-local/garasign-jsign:latest
- name: Sign Windows executable
uses: ./actions/sign-windows
with:
binary: dist/win-unpacked/Realm Studio.exe
# Binary signing for Windows/arm64 just works, if arm64 is enabled above
#- name: Sign Windows executable (arm64)
# uses: ./actions/sign-windows
# with:
# binary: dist/win-arm64-unpacked/Realm Studio.exe
#
# This now just finishes the build step, packing up the installers using
# the binaries with the signatures attached
# Packing up would also work by just repeating above command without the
# --dir in a single command - but to avoid relying on undocumented
# behaviour splitting this up into multiple calls using the --pd switch
# is more sensible
#
# The Linux arm64 installer can easily be enabled, the windows one would
# overwrite the x86_64 one - that'd need changes in electron builder
# config to write that with a different name
- name: Build installers
run: |
npx electron-builder -l --publish never --pd dist/linux-unpacked
npx electron-builder -w --publish never --pd dist/win-unpacked
#npx electron-builder -l --arm64 --publish never --pd dist/linux-arm64-unpacked
#npx electron-builder -w --arm64 --publish never --pd dist/win-arm64-unpacked
#- name: Locate Windows installer
# run: |
# echo "WIN_SETUP=`find dist -name 'Realm Studio Setup *.exe'`" >> $GITHUB_ENV
- name: Rename yaml files
run: |
mv dist/major-*-linux.yml dist/latest-linux.yml
mv dist/major-*-linux-arm64.yml dist/latest-linux-arm64.yml || true
mv dist/major-*.yml dist/latest.yml
- name: Sign Windows installer
uses: ./actions/sign-windows
with:
binary: dist/Realm Studio Setup ${{ env.PACKAGE_VERSION }}.exe
#- name: Sign Windows installer (arm64)
# uses: ./actions/sign-windows
# with:
# binary: dist/Realm Studio Setup ${{ env.PACKAGE_VERSION }}.exe
- name: Archive Linux installers
uses: actions/upload-artifact@v3
with:
name: Linux
path: |
dist/realm-studio-*.tar.gz
dist/Realm Studio-*.AppImage
dist/latest-linux*.yml
- name: Archive Windows installers
uses: actions/upload-artifact@v3
with:
name: Windows
path: |
dist/Realm Studio *.exe
dist/Realm Studio-*-win.zip
dist/*.blockmap
dist/latest.yml
# most of that could be done on a Linux worker to speed things up, but
# - universal binary building is currently only supported on macOS
# - dmg building via electron builder only works on macOS; theoretically
# a dmg can be manually built on Linux, but it's a hacky mess
build_sign_m:
name: Build MacOS
runs-on: macOS-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Store package version in environment
run: |
PACKAGE_VERSION=`jq -r '.version' package.json`
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV
# the signing endpoint requires whitelisting IPs - we use wireguard to
# make sure we exit with a known IP. To make things easier the secret
# should contain the full client config, including the client secret
# key
- name: Configure wireguard
run: |
brew install wireguard-go wireguard-tools
echo "${{ secrets.WG_CONFIG }}" | base64 -d | sudo tee /usr/local/etc/wireguard/wg0.conf >/dev/null
sudo wg-quick up wg0
sudo wg
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Build the bundle
run: npm run build
# Producing universal binaries currently fails due to the native realm.node
# binary, and embedding multi-arch binaries there currently seems to be
# mostly unsupported. Once that has been solved the next few build steps
# can be switched to universal. Doing universal builds changes the name
# of the installers - but still creates an autoupdate file with the same
# name, but new installers referenced - so it should be possible to use
# that to pull existing installations to the universal binary via the
# update mechanism
- name: Prepare installer contents
run: |
npx electron-builder -m --publish never --c.mac.target=zip --c.mac.identity=null
#npx electron-builder -m --publish never --c.mac.target=zip --c.mac.identity=null --universal
# Renaming the .zip to make it easier to distinguish
mv dist/*.zip dist/unsigned-app.zip
- name: Download signer
run: |
wget https://macos-notary-1628249594.s3.amazonaws.com/releases/client/v3.8.1/darwin_amd64.zip
unzip darwin_amd64.zip
- name: Run signer
run: |
./darwin_amd64/macnotary -f dist/unsigned-app.zip -m notarizeAndSign -u https://dev.macos-notary.build.10gen.cc/api -s "${{ secrets.NOTARY_SECRET }}" -k "${{ secrets.NOTARY_KEY_ID }}" -b com.mongodb.realm-studio -o "output.zip" -t app -e resources/entitlements.mac.plist
- name: Extract notarized app in electron builder tree
run: |
unzip -d dist/mac -o output.zip
#unzip -d dist/mac-universal -o output.zip
- name: Build installers
run: |
npx electron-builder -m --publish never --pd "dist/mac/Realm Studio.app"
#npx electron-builder -m --publish never --universal --pd "dist/mac-universal/Realm Studio.app"
- name: Rename yaml files
run: |
ls dist/*.yml
mv dist/major-*-mac.yml dist/latest-mac.yml
- name: Archive macOS artifacts
uses: actions/upload-artifact@v3
with:
name: Mac
path: |
dist/latest-mac.yml
dist/*.dmg
dist/Realm Studio-${{ env.PACKAGE_VERSION }}-mac.zip
#dist/Realm Studio-${{ env.PACKAGE_VERSION }}-universal-mac.zip
upload_release:
name: Upload release artifacts to S3
needs: [ build_sign_m, build_sign_lw ]
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Store package version and release channel in environment
run: |
PACKAGE_VERSION=`jq -r '.version' package.json`
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV
RELEASE_CHANNEL=`jq -r '.build.publish[0].channel' package.json`
echo "RELEASE_CHANNEL=$RELEASE_CHANNEL" >> $GITHUB_ENV
- run: |
env | sort
- name: Pull macOS artifacts
uses: actions/download-artifact@v3
with:
name: Mac
path: dist
- name: Pull Windows artifacts
uses: actions/download-artifact@v3
with:
name: Windows
path: dist
- name: Pull Linux artifacts
uses: actions/download-artifact@v3
with:
name: Linux
path: dist
- run: |
cargo install better-blockmap
# As the Windows installer gets signed after electron builder is done with
# with it the auto updater files will contain the wrong checksums - this
# just fixes the checksums in an existing yaml file
- name: Update Windows auto-update yaml file
run: |
WIN_INSTALLER="dist/Realm Studio Setup ${{env.PACKAGE_VERSION}}.exe"
OLD_WIN_SHA=`awk '/^sha512/ {print $2}' dist/latest.yml`
NEW_WIN_SHA=`openssl dgst -binary -sha512 "$WIN_INSTALLER" | openssl base64 -A`
if [ "$OLD_WIN_SHA" = "$NEW_WIN_SHA" ]; then
echo "Windows installer sha512 matches file"
echo "This should not happen - probably signing failed"
else
echo "Old windows sha512: $OLD_WIN_SHA"
echo "New windows sha512: $NEW_WIN_SHA"
sed -i "s,sha512:.*,sha512: $NEW_WIN_SHA,g" dist/latest.yml
WIN_SIZE=`stat -c %s "$WIN_INSTALLER"`
sed -i "s,size:.*,size: $WIN_SIZE,g" dist/latest.yml
fi
# The blockmap also is obviously wrong, and needs to be regenerated. For
# some reason Windows doesn't have the zip in the autoupdate file, and
# therefore no blockmap for that.
- name: build Windows blockmaps
run: |
better-blockmap --input "dist/Realm Studio Setup ${{env.PACKAGE_VERSION}}.exe" --output "dist/Realm Studio Setup ${{env.PACKAGE_VERSION}}.exe.blockmap"
# Creating the auto-update files from scratch is required when building
# disk images or installer files outside of electron builder. This
# would generate correct yaml files for macOS. The sed operates on
# a template like the following, default in resources/latest-mac.yml:
#
# version: VERSION
# files:
# - url: Realm Studio-VERSION-mac.zip
# sha512: ZIP_SHA
# size: ZIP_SIZE
# blockMapSize: ZIP_BLOCKMAP_SIZE
# - url: Realm Studio-VERSION.dmg
# sha512: DMG_SHA
# size: DMG_SIZE
# path: Realm Studio-VERSION.zip
# sha512: ZIP_SHA
# RELEASE_DATE
#
#- name: create mac auto-update yaml file
# run: |
# RELEASE_DATE=`grep ^releaseDate: dist/latest.yml`
# ZIP_SHA=`openssl dgst -binary -sha512 "dist/Realm Studio-${{env.PACKAGE_VERSION}}-mac.zip" | openssl base64 -A`
# DMG_SHA=`openssl dgst -binary -sha512 "dist/Realm Studio-${{env.PACKAGE_VERSION}}.dmg" | openssl base64 -A`
# ZIP_SIZE=`stat -c %s "dist/Realm Studio-${{env.PACKAGE_VERSION}}-mac.zip"`
# ZIP_BLOCKMAP_SIZE=`stat -c %s "dist/Realm Studio-${{env.PACKAGE_VERSION}}-mac.zip.blockmap"`
# DMG_SIZE=`stat -c %s "dist/Realm Studio-${{env.PACKAGE_VERSION}}.dmg"`
#
# sed -e "s/RELEASE_DATE/$RELEASE_DATE/" \
# -e "s/VERSION/${{env.PACKAGE_VERSION}}/g" \
# -e "s,ZIP_SHA,$ZIP_SHA,g" \
# -e "s/ZIP_SIZE/$ZIP_SIZE/g" \
# -e "s/ZIP_BLOCKMAP_SIZE/$ZIP_BLOCKMAP_SIZE/g" \
# -e "s,DMG_SHA,$DMG_SHA,g" \
# -e "s/DMG_SIZE/$DMG_SIZE/g" \
# resources/latest-mac.yml > dist/latest-mac.yml
#- name: build macOS blockmaps
# run: |
# better-blockmap --input "dist/Realm Studio-${{env.PACKAGE_VERSION}}.dmg" --output "dist/Realm Studio-${{env.PACKAGE_VERSION}}.dmg.blockmap"
# better-blockmap --input "dist/Realm Studio-${{env.PACKAGE_VERSION}}-mac.zip" --output "dist/Realm Studio-${{env.PACKAGE_VERSION}}-mac.zip.blockmap"
- name: Rename and dump auto-update yaml files for control
run: |
echo "** windows"
cat dist/latest.yml
mv dist/latest.yml dist/${{ env.RELEASE_CHANNEL }}.yml
echo "** linux"
cat dist/latest-linux.yml
mv dist/latest-linux.yml dist/${{ env.RELEASE_CHANNEL }}-linux.yml
echo "** mac"
cat dist/latest-mac.yml
mv dist/latest-mac.yml dist/${{ env.RELEASE_CHANNEL }}-mac.yml
- name: Extract latest release notes
run: |
node ./scripts/extract-changelog.mjs > ./RELEASENOTES.md
cat ./RELEASENOTES.md
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY }}
aws-region: us-east-1
# This needs to be adjusted to the actual s3 bucket (which probably also
# could just come via repository secret). Initially this should go to the
# old location, and moved to a new one when we're sure we can move
# existing installations over via the auto update system
- name: Override the S3 bucket when dry running
if: ${{ inputs.dry_run }}
run: |
echo "S3_BUCKET=s3://static.realm.io/ci/test/$PACKAGE_VERSION" >> $GITHUB_ENV
- name: Upload release
run: |
aws s3 sync --acl public-read dist ${{ env.S3_BUCKET }}
- name: Find Release PR
uses: juliangruber/find-pull-request-action@v1.7.0
id: find-pull-request
with:
branch: ${{ github.ref }}
- name: Merge Pull Request
uses: juliangruber/merge-pull-request-action@8a13f2645ad8b6ada32f829b2fae9c0955a5265d
if: ${{ inputs.dry_run == false }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
number: ${{ steps.find-pull-request.outputs.number }}
method: squash
- name: Checkout base branch (after merge)
uses: actions/checkout@v3
if: ${{ inputs.dry_run == false }}
with:
submodules: recursive
ref: ${{ steps.find-pull-request.outputs.base-ref }}
- name: Publish Github Release
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5
if: ${{ inputs.dry_run == false }}
with:
artifacts: "dist/*.exe,dist/*.dmg,dist/*.zip,dist/*.AppImage"
bodyFile: ./RELEASENOTES.md
tag: v${{ env.PACKAGE_VERSION }}
token: ${{ secrets.GITHUB_TOKEN }}
draft: false
- name: 'Post to Slack'
uses: realm/ci-actions/release-to-slack@fa20eb972b9f018654fdb4e2c7afb52b0532f907
if: ${{ inputs.dry_run == false }}
with:
changelog: ./RELEASENOTES.md
sdk: realm-studio
webhook-url: ${{ secrets.SLACK_RELEASE_WEBHOOK }}
version: ${{ env.PACKAGE_VERSION }}
# This job might fail due to failed markdown-to-slack conversion.
continue-on-error: true
- name: Update Changelog
run: |
echo "## vNext (TBD)
### Enhancements
* None
### Fixed
* None
### Internals
* None
" | cat - CHANGELOG.md >> temp
mv temp CHANGELOG.md
shell: bash
- name: Create vNext PR
if: ${{ inputs.dry_run == false }}
id: vnext-pr
uses: peter-evans/create-pull-request@6c704eb7a8ba1daa13da0dcea9bb93a4fe530275
with:
branch: prepare-vnext
title: Prepare for vNext
body: Update Changelog for vNext
delete-branch: true
base: main
commit-message: Prepare for vNext
assignees: ${{ github.event.sender.login }}
labels: no-jira-ticket
- name: Merge Pull Request
uses: juliangruber/merge-pull-request-action@333730196b34b74936aad75a4e31c23a57582d14
if: ${{ inputs.dry_run == false }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
number: ${{ steps.vnext-pr.outputs.pull-request-number }}
method: squash