v1.19.14
[etcher.git] / forge.config.ts
blobf45cd36786b6483eea02d4f72b4a436558ca6fa9
1 import type { ForgeConfig } from '@electron-forge/shared-types';
2 import { MakerSquirrel } from '@electron-forge/maker-squirrel';
3 import { MakerZIP } from '@electron-forge/maker-zip';
4 import { MakerDeb } from '@electron-forge/maker-deb';
5 import { MakerRpm } from '@electron-forge/maker-rpm';
6 import { MakerDMG } from '@electron-forge/maker-dmg';
7 import { MakerAppImage } from '@reforged/maker-appimage';
8 import { AutoUnpackNativesPlugin } from '@electron-forge/plugin-auto-unpack-natives';
9 import { WebpackPlugin } from '@electron-forge/plugin-webpack';
10 import { exec } from 'child_process';
12 import { mainConfig, rendererConfig } from './webpack.config';
13 import * as sidecar from './forge.sidecar';
15 import { hostDependencies, productDescription } from './package.json';
17 const osxSigningConfig: any = {};
18 let winSigningConfig: any = {};
20 if (process.env.NODE_ENV === 'production') {
21         osxSigningConfig.osxNotarize = {
22                 tool: 'notarytool',
23                 appleId: process.env.XCODE_APP_LOADER_EMAIL,
24                 appleIdPassword: process.env.XCODE_APP_LOADER_PASSWORD,
25                 teamId: process.env.XCODE_APP_LOADER_TEAM_ID,
26         };
28         winSigningConfig = {
29                 signWithParams: `-sha1 ${process.env.SM_CODE_SIGNING_CERT_SHA1_HASH} -tr ${process.env.TIMESTAMP_SERVER} -td sha256 -fd sha256 -d balena-etcher`,
30         };
33 const config: ForgeConfig = {
34         packagerConfig: {
35                 asar: true,
36                 icon: './assets/icon',
37                 executableName:
38                         process.platform === 'linux' ? 'balena-etcher' : 'balenaEtcher',
39                 appBundleId: 'io.balena.etcher',
40                 appCategoryType: 'public.app-category.developer-tools',
41                 appCopyright: 'Copyright 2016-2023 Balena Ltd',
42                 darwinDarkModeSupport: true,
43                 protocols: [{ name: 'etcher', schemes: ['etcher'] }],
44                 extraResource: [
45                         'lib/shared/sudo/sudo-askpass.osascript-zh.js',
46                         'lib/shared/sudo/sudo-askpass.osascript-en.js',
47                 ],
48                 osxSign: {
49                         optionsForFile: () => ({
50                                 entitlements: './entitlements.mac.plist',
51                                 hardenedRuntime: true,
52                         }),
53                 },
54                 ...osxSigningConfig,
55         },
56         rebuildConfig: {
57                 onlyModules: [], // prevent rebuilding *any* native modules as they won't be used by electron but by the sidecar
58         },
59         makers: [
60                 new MakerZIP(),
61                 new MakerSquirrel({
62                         setupIcon: 'assets/icon.ico',
63                         loadingGif: 'assets/icon.png',
64                         ...winSigningConfig,
65                 }),
66                 new MakerDMG({
67                         background: './assets/dmg/background.tiff',
68                         icon: './assets/icon.icns',
69                         iconSize: 110,
70                         contents: ((opts: { appPath: string }) => {
71                                 return [
72                                         { x: 140, y: 250, type: 'file', path: opts.appPath },
73                                         { x: 415, y: 250, type: 'link', path: '/Applications' },
74                                 ];
75                         }) as any, // type of MakerDMGConfig omits `appPath`
76                         additionalDMGOptions: {
77                                 window: {
78                                         size: {
79                                                 width: 540,
80                                                 height: 425,
81                                         },
82                                         position: {
83                                                 x: 400,
84                                                 y: 500,
85                                         },
86                                 },
87                         },
88                 }),
89                 new MakerAppImage({
90                         options: {
91                                 icon: './assets/icon.png',
92                                 categories: ['Utility'],
93                         },
94                 }),
95                 new MakerRpm({
96                         options: {
97                                 icon: './assets/icon.png',
98                                 categories: ['Utility'],
99                                 productDescription,
100                                 requires: ['util-linux'],
101                         },
102                 }),
103                 new MakerDeb({
104                         options: {
105                                 icon: './assets/icon.png',
106                                 categories: ['Utility'],
107                                 section: 'utils',
108                                 priority: 'optional',
109                                 productDescription,
110                                 scripts: {
111                                         postinst: './after-install.tpl',
112                                 },
113                                 depends: hostDependencies['debian'],
114                         },
115                 }),
116         ],
117         plugins: [
118                 new AutoUnpackNativesPlugin({}),
119                 new WebpackPlugin({
120                         mainConfig,
121                         renderer: {
122                                 config: rendererConfig,
123                                 nodeIntegration: true,
124                                 entryPoints: [
125                                         {
126                                                 html: './lib/gui/app/index.html',
127                                                 js: './lib/gui/app/renderer.ts',
128                                                 name: 'main_window',
129                                                 preload: {
130                                                         js: './lib/gui/app/preload.ts',
131                                                 },
132                                         },
133                                 ],
134                         },
135                 }),
136                 new sidecar.SidecarPlugin(),
137         ],
138         hooks: {
139                 readPackageJson: async (_config, packageJson) => {
140                         packageJson.analytics = {};
142                         if (process.env.SENTRY_TOKEN) {
143                                 packageJson.analytics.sentry = {
144                                         token: process.env.SENTRY_TOKEN,
145                                 };
146                         }
148                         if (process.env.AMPLITUDE_TOKEN) {
149                                 packageJson.analytics.amplitude = {
150                                         token: 'balena-etcher',
151                                 };
152                         }
154                         // packageJson.packageType = 'dmg' | 'AppImage' | 'rpm' | 'deb' | 'zip' | 'nsis' | 'portable'
156                         return packageJson;
157                 },
158                 postPackage: async (_forgeConfig, options) => {
159                         if (options.platform === 'linux') {
160                                 // symlink the etcher binary from balena-etcher to balenaEtcher to ensure compatibility with the wdio suite and the old name
161                                 await new Promise<void>((resolve, reject) => {
162                                         exec(
163                                                 `ln -s "${options.outputPaths}/balena-etcher" "${options.outputPaths}/balenaEtcher"`,
164                                                 (err) => {
165                                                         if (err) {
166                                                                 reject(err);
167                                                         } else {
168                                                                 resolve();
169                                                         }
170                                                 },
171                                         );
172                                 });
173                         }
174                 },
175         },
178 export default config;