Skip to content

Commit 1a718ad

Browse files
authored
feat: Add build and deployment tools (#2943)
1 parent 25ce6f5 commit 1a718ad

39 files changed

+2810
-212
lines changed

README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ export LINUX_TARGET=<target>
6767
yarn build:linux
6868
```
6969

70-
Replace `<target>` with your desired target (e.g. `"rpm"`). Have a look at the [documentation for `electron-builder`](https://www.electron.build/configuration/linux) for the available options. Note that we cannot offer support for uncommon targets.
70+
Replace `<target>` with your desired target (e.g. `rpm`). Have a look at the [documentation for `electron-builder`](https://www.electron.build/configuration/linux) for the available targets. Multiple targets can be combined by comma separation (e.g. `rpm,deb`). Note that we cannot offer support for uncommon targets.
71+
72+
Furthermore, you can disable [asar packaging](https://electronjs.org/docs/tutorial/application-packaging) (not recommended, but e.g. needed for target `dir`) by setting `ENABLE_ASAR="false"` before building. Example:
73+
74+
```shell
75+
export ENABLE_ASAR="false"
76+
yarn build:linux
77+
```
7178

7279
### Troubleshooting
7380

bin/bin-utils.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Wire
3+
* Copyright (C) 2019 Wire Swiss GmbH
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see http://www.gnu.org/licenses/.
17+
*/
18+
19+
import {LogFactory, Logger} from '@wireapp/commons/dist/commonjs/LogFactory';
20+
import commander from 'commander';
21+
22+
export const getLogger = (namespace: string, name: string) =>
23+
LogFactory.getLogger(name, {namespace: `@wireapp/${namespace}`, forceEnable: true, separator: '/'});
24+
25+
export function checkCommanderOptions(
26+
commanderInstance: typeof commander,
27+
logdownInstance: Logger,
28+
options: string[],
29+
): void {
30+
options.forEach(option => {
31+
if (!commanderInstance.hasOwnProperty(option)) {
32+
logdownInstance.error(`Required option "${option}" was not provided.`);
33+
commanderInstance.outputHelp();
34+
process.exit(1);
35+
}
36+
});
37+
}
38+
39+
export const logEntries = <T extends Object>(config: T, name: string, callee: string): void => {
40+
const logger = getLogger(callee, 'build-tools');
41+
42+
Object.entries(config).forEach(([key, value]) => {
43+
if (Array.isArray(value)) {
44+
value = value.join(',');
45+
} else if (value instanceof Object) {
46+
logEntries(value, `${name}.${key}`, callee);
47+
} else {
48+
logger.info(`${name}.${key} set to "${value}". `);
49+
}
50+
});
51+
};

bin/build-tools/build-cli.ts

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Wire
3+
* Copyright (C) 2019 Wire Swiss GmbH
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see http://www.gnu.org/licenses/.
17+
*
18+
*/
19+
20+
import {LogFactory} from '@wireapp/commons';
21+
import commander from 'commander';
22+
import path from 'path';
23+
24+
import {logEntries} from '../bin-utils';
25+
import {buildLinuxConfig, buildLinuxWrapper} from './lib/build-linux';
26+
import {buildMacOSConfig, buildMacOSWrapper} from './lib/build-macos';
27+
import {buildWindowsConfig, buildWindowsWrapper} from './lib/build-windows';
28+
import {buildWindowsInstaller, buildWindowsInstallerConfig} from './lib/build-windows-installer';
29+
30+
const toolName = path.basename(__filename).replace('.ts', '');
31+
const logger = LogFactory.getLogger(toolName, {namespace: '@wireapp/build-tools', forceEnable: true});
32+
const appSource = path.join(__dirname, '../../');
33+
34+
commander
35+
.name(toolName)
36+
.description(
37+
'Build the Wire wrapper for your platform.\n\nValid values for platform are: "windows", "windows-installer", "macos", "linux".',
38+
)
39+
.option('-e, --env-file <path>', 'Specify the env file path', path.join(appSource, '.env.defaults'))
40+
.option('-m, --manual-sign', `Manually sign and package the app (i.e. don't use electron-packager, macOS only)`)
41+
.option('-p, --package-json <path>', 'Specify the package.json path', path.join(appSource, 'package.json'))
42+
.option('-w, --wire-json <path>', 'Specify the wire.json path', path.join(appSource, 'electron/wire.json'))
43+
.arguments('<platform>')
44+
.parse(process.argv);
45+
46+
const platform = (commander.args[0] || '').toLowerCase();
47+
48+
new Promise(() => {
49+
switch (platform) {
50+
case 'win':
51+
case 'windows': {
52+
const {packagerConfig} = buildWindowsConfig(commander.wireJson, commander.envFile);
53+
54+
logEntries(packagerConfig, 'packagerConfig', toolName);
55+
56+
return buildWindowsWrapper(packagerConfig, commander.packageJson, commander.wireJson, commander.envFile);
57+
}
58+
59+
case 'windows-installer': {
60+
const {wInstallerOptions} = buildWindowsInstallerConfig(commander.wireJson, commander.envFile);
61+
62+
logEntries(wInstallerOptions, 'wInstallerOptions', toolName);
63+
64+
return buildWindowsInstaller(commander.wireJson, commander.envFile, wInstallerOptions);
65+
}
66+
67+
case 'mac':
68+
case 'macos': {
69+
const {macOSConfig, packagerConfig} = buildMacOSConfig(
70+
commander.wireJson,
71+
commander.envFile,
72+
commander.manualSign,
73+
);
74+
75+
logEntries(packagerConfig, 'builderConfig', toolName);
76+
77+
return buildMacOSWrapper(
78+
packagerConfig,
79+
macOSConfig,
80+
commander.packageJson,
81+
commander.wireJson,
82+
commander.manualSign,
83+
);
84+
}
85+
86+
case 'linux': {
87+
const {linuxConfig, builderConfig} = buildLinuxConfig(commander.wireJson, commander.envFile);
88+
89+
logEntries(builderConfig, 'builderConfig', toolName);
90+
91+
return buildLinuxWrapper(
92+
builderConfig,
93+
linuxConfig,
94+
commander.packageJson,
95+
commander.wireJson,
96+
commander.envFile,
97+
);
98+
}
99+
100+
default: {
101+
logger.error(`Invalid or no platform specified.`);
102+
return commander.help();
103+
}
104+
}
105+
}).catch(error => {
106+
logger.error(error);
107+
process.exit(1);
108+
});

bin/build-tools/lib/Config.ts

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Wire
3+
* Copyright (C) 2019 Wire Swiss GmbH
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see http://www.gnu.org/licenses/.
17+
*
18+
*/
19+
20+
export interface CommonConfig {
21+
adminUrl: string;
22+
appBase: string;
23+
buildDir: string;
24+
buildNumber: string;
25+
copyright: string;
26+
customProtocolName: string;
27+
description: string;
28+
distDir: string;
29+
electronDirectory: string;
30+
enableAsar: boolean;
31+
environment: 'internal' | 'production';
32+
legalUrl: string;
33+
licensesUrl: string;
34+
maximumAccounts: string;
35+
name: string;
36+
nameShort: string;
37+
privacyUrl: string;
38+
raygunApiKey: string;
39+
supportUrl: string;
40+
updateUrl?: string;
41+
version: string;
42+
websiteUrl: string;
43+
}
44+
45+
export interface LinuxConfig {
46+
artifactName: string;
47+
categories: string;
48+
executableName: string;
49+
keywords: string;
50+
targets: string[];
51+
}
52+
53+
export interface MacOSConfig {
54+
bundleId: string;
55+
category: string;
56+
certNameApplication: string | null;
57+
certNameInstaller: string | null;
58+
notarizeAppleId: string | null;
59+
notarizeApplePassword: string | null;
60+
}
61+
62+
export interface WindowsConfig {
63+
installerIconUrl: string;
64+
loadingGif: string;
65+
updateUrl: string;
66+
}
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Wire
3+
* Copyright (C) 2019 Wire Swiss GmbH
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see http://www.gnu.org/licenses/.
17+
*/
18+
19+
import * as assert from 'assert';
20+
import * as path from 'path';
21+
import uuid from 'uuid/v4';
22+
23+
import {buildLinuxConfig} from './build-linux';
24+
25+
const wireJsonPath = path.join(__dirname, '../../../electron/wire.json');
26+
const envFilePath = path.join(__dirname, '../../../.env.defaults');
27+
28+
describe('build-linux', () => {
29+
describe('buildLinuxConfig', () => {
30+
it('honors environment variables', () => {
31+
const categories = uuid();
32+
const keywords = uuid();
33+
const nameShort = uuid();
34+
const targets = [uuid(), uuid()];
35+
36+
process.env.LINUX_CATEGORIES = categories;
37+
process.env.LINUX_KEYWORDS = keywords;
38+
process.env.LINUX_NAME_SHORT = nameShort;
39+
process.env.LINUX_TARGET = targets.join(',');
40+
41+
const {linuxConfig} = buildLinuxConfig(wireJsonPath, envFilePath);
42+
43+
assert.strictEqual(linuxConfig.categories, categories);
44+
assert.strictEqual(linuxConfig.executableName, nameShort);
45+
assert.strictEqual(linuxConfig.keywords, keywords);
46+
assert.deepStrictEqual(linuxConfig.targets, targets);
47+
48+
delete process.env.LINUX_CATEGORIES;
49+
delete process.env.LINUX_NAME_SHORT;
50+
delete process.env.LINUX_KEYWORDS;
51+
delete process.env.LINUX_TARGET;
52+
});
53+
});
54+
});

0 commit comments

Comments
 (0)