forked from gravitational/teleport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathelectron-builder-config.js
235 lines (226 loc) · 8.58 KB
/
electron-builder-config.js
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
const { env, platform } = require('process');
const fs = require('fs');
const { spawnSync } = require('child_process');
const isMac = platform === 'darwin';
const isWindows = platform === 'win32';
// The following checks make no sense when cross-building because they check the platform of the
// host and not the platform we're building for.
//
// However, at the moment we don't cross-build Connect and these checks protect us from undesired
// behavior.
//
// Also, we just want to make sure that those are explicitly set but they can be empty. That's why
// we check for undefined only and not for falsy values.
//
// Setting one of the env vars to an empty string is useful in environments where we don't intend to
// build a fully-fledged Connect version but rather want to just check that the packaging step is
// working, for example in CI.
if (
isMac &&
(env.CONNECT_TSH_APP_PATH === undefined) ===
(env.CONNECT_TSH_BIN_PATH === undefined)
) {
throw new Error(
'You must provide CONNECT_TSH_APP_PATH xor CONNECT_TSH_BIN_PATH'
);
}
if (!isMac && env.CONNECT_TSH_BIN_PATH === undefined) {
throw new Error('You must provide CONNECT_TSH_BIN_PATH');
}
if (isWindows && env.CONNECT_WINTUN_DLL_PATH === undefined) {
throw new Error('You must provide CONNECT_WINTUN_DLL_PATH');
}
// Holds tsh.app Info.plist during build. Used in afterPack.
let tshAppPlist;
// appId must be a reverse DNS string since it's also used as CFBundleURLName on macOS, see
// protocols.name below.
const appId = 'gravitational.teleport.connect';
/**
* @type { import('electron-builder').Configuration }
*/
module.exports = {
appId,
asar: true,
asarUnpack: '**\\*.{node,dll}',
// TODO(ravicious): Migrate from custom notarize.js script to using the notarize field of the
// mac target.
afterSign: 'notarize.js',
afterPack: packed => {
// @electron-universal adds the `ElectronAsarIntegrity` key to every .plist
// file it finds, causing signature verification to fail for tsh.app that gets
// embedded in Teleport Connect. This causes the error "invalid Info.plist (plist
// or signature have been modified)".
// Workaround this by copying the tsp.app plist file before adding the key and
// replace it after it is done.
if (!env.CONNECT_TSH_APP_PATH) {
// Not embedding tsh.app
return;
}
const path = `${packed.appOutDir}/Teleport Connect.app/Contents/MacOS/tsh.app/Contents/Info.plist`;
if (packed.appOutDir.endsWith('mac-universal-x64-temp')) {
tshAppPlist = fs.readFileSync(path);
}
if (packed.appOutDir.endsWith('mac-universal')) {
if (!tshAppPlist) {
throw new Error(
'Failed to copy tsh.app Info.plist file from the x64 build. Check if the path "mac-universal-x64-temp" was not changed by electron-builder.'
);
}
fs.writeFileSync(path, tshAppPlist);
}
},
files: ['build/app'],
protocols: [
{
// name ultimately becomes CFBundleURLName which is the URL identifier. [1] Apple recommends
// to set it to a reverse DNS string. [2]
//
// [1] https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleurltypes/cfbundleurlname
// [2] https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app#Register-your-URL-scheme
name: appId,
schemes: ['teleport'],
// Not much documentation is available on the role attribute. It ultimately gets mapped to
// CFBundleTypeRole in Info.plist.
//
// It seems that this field is largely related to how macOS thinks of "documents". Since Connect
// doesn't let you really edit anything and we won't be passing any docs, let's just set it to
// 'Viewer'.
//
// https://cocoadev.github.io/CFBundleTypeRole/
role: 'Viewer',
},
],
mac: {
target: 'dmg',
category: 'public.app-category.developer-tools',
type: 'distribution',
// TODO(ravicious): Migrate from custom notarize.js script to using the notarize field of the
// mac target.
notarize: false,
hardenedRuntime: true,
gatekeeperAssess: false,
// If CONNECT_TSH_APP_PATH is provided, we assume that tsh.app is already signed.
signIgnore: env.CONNECT_TSH_APP_PATH && ['tsh.app'],
icon: 'build_resources/icon-mac.png',
// x64ArchFiles is for x64 and universal files (lipo tool should skip them)
x64ArchFiles: 'Contents/MacOS/tsh.app/Contents/MacOS/tsh',
// On macOS, helper apps (such as tsh.app) should be under Contents/MacOS, hence using
// `extraFiles` instead of `extraResources`.
// https://developer.apple.com/documentation/bundleresources/placing_content_in_a_bundle
// https://developer.apple.com/forums/thread/128166
extraFiles: [
// CONNECT_TSH_APP_PATH is for environments where we want to copy over the whole signed
// version of tsh.app for Touch ID support.
env.CONNECT_TSH_APP_PATH && {
from: env.CONNECT_TSH_APP_PATH,
to: './MacOS/tsh.app',
},
// CONNECT_TSH_BIN_PATH is for environments where we just need a regular tsh binary. We still
// copy it to the same location that it would be at in a real tsh.app to avoid conditional
// logic elsewhere.
env.CONNECT_TSH_BIN_PATH && {
from: env.CONNECT_TSH_BIN_PATH,
to: './MacOS/tsh.app/Contents/MacOS/tsh',
},
].filter(Boolean),
},
dmg: {
artifactName: '${productName}-${version}-${arch}.${ext}',
// Turn off blockmaps since we don't support automatic updates.
// https://github.com/electron-userland/electron-builder/issues/2900#issuecomment-730571696
writeUpdateInfo: false,
contents: [
{
x: 130,
y: 220,
},
{
x: 410,
y: 220,
type: 'link',
path: '/Applications',
},
],
},
win: {
target: ['nsis'],
// The algorithm passed here is not used, it only prevents the signing function from being called twice for each file.
// https://github.com/electron-userland/electron-builder/issues/3995#issuecomment-505725704
signingHashAlgorithms: ['sha256'],
sign: customSign => {
if (process.env.CI !== 'true') {
console.warn('Not running in CI pipeline: signing will be skipped');
return;
}
spawnSync(
'powershell',
[
'-noprofile',
'-executionpolicy',
'bypass',
'-c',
"$ProgressPreference = 'SilentlyContinue'; " +
"$ErrorActionPreference = 'Stop'; " +
'. ../../../build.assets/windows/build.ps1; ' +
`Invoke-SignBinary -UnsignedBinaryPath "${customSign.path}"`,
],
{ stdio: 'inherit' }
);
},
artifactName: '${productName} Setup-${version}.${ext}',
icon: 'build_resources/icon-win.ico',
extraResources: [
env.CONNECT_TSH_BIN_PATH && {
from: env.CONNECT_TSH_BIN_PATH,
to: './bin/tsh.exe',
},
env.CONNECT_WINTUN_DLL_PATH && {
from: env.CONNECT_WINTUN_DLL_PATH,
to: './bin/wintun.dll',
},
].filter(Boolean),
},
nsis: {
// Turn off blockmaps since we don't support automatic updates.
// https://github.com/electron-userland/electron-builder/issues/2900#issuecomment-730571696
differentialPackage: false,
// Use a per-machine installation to support VNet.
// VNet installs a Windows service per-machine, and tsh.exe must be
// installed in a path that is not user-writable.
perMachine: true,
},
rpm: {
artifactName: '${name}-${version}.${arch}.${ext}',
afterInstall: 'build_resources/linux/after-install.tpl',
afterRemove: 'build_resources/linux/after-remove.tpl',
// --rpm-rpmbuild-define "_build_id_links none" fixes the problem with not being able to install
// Connect's rpm next to other Electron apps.
// https://github.com/gravitational/teleport/issues/18859
fpm: ['--rpm-rpmbuild-define', '_build_id_links none'],
},
deb: {
artifactName: '${name}_${version}_${arch}.${ext}',
afterInstall: 'build_resources/linux/after-install.tpl',
afterRemove: 'build_resources/linux/after-remove.tpl',
},
linux: {
target: ['tar.gz', 'rpm', 'deb'],
artifactName: '${name}-${version}-${arch}.${ext}', // tar.gz
category: 'Development',
icon: 'build_resources/icon-linux',
extraResources: [
env.CONNECT_TSH_BIN_PATH && {
from: env.CONNECT_TSH_BIN_PATH,
to: './bin/tsh',
},
{
from: 'build_resources/linux/apparmor-profile',
to: './apparmor-profile',
},
].filter(Boolean),
},
directories: {
buildResources: 'build_resources',
output: 'build/release',
},
};