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 = {
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,
29 signWithParams: `-sha1 ${process.env.SM_CODE_SIGNING_CERT_SHA1_HASH} -tr ${process.env.TIMESTAMP_SERVER} -td sha256 -fd sha256 -d balena-etcher`,
33 const config: ForgeConfig = {
36 icon: './assets/icon',
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'] }],
45 'lib/shared/sudo/sudo-askpass.osascript-zh.js',
46 'lib/shared/sudo/sudo-askpass.osascript-en.js',
49 optionsForFile: () => ({
50 entitlements: './entitlements.mac.plist',
51 hardenedRuntime: true,
57 onlyModules: [], // prevent rebuilding *any* native modules as they won't be used by electron but by the sidecar
62 setupIcon: 'assets/icon.ico',
63 loadingGif: 'assets/icon.png',
67 background: './assets/dmg/background.tiff',
68 icon: './assets/icon.icns',
70 contents: ((opts: { appPath: string }) => {
72 { x: 140, y: 250, type: 'file', path: opts.appPath },
73 { x: 415, y: 250, type: 'link', path: '/Applications' },
75 }) as any, // type of MakerDMGConfig omits `appPath`
76 additionalDMGOptions: {
91 icon: './assets/icon.png',
92 categories: ['Utility'],
97 icon: './assets/icon.png',
98 categories: ['Utility'],
100 requires: ['util-linux'],
105 icon: './assets/icon.png',
106 categories: ['Utility'],
108 priority: 'optional',
111 postinst: './after-install.tpl',
113 depends: hostDependencies['debian'],
118 new AutoUnpackNativesPlugin({}),
122 config: rendererConfig,
123 nodeIntegration: true,
126 html: './lib/gui/app/index.html',
127 js: './lib/gui/app/renderer.ts',
130 js: './lib/gui/app/preload.ts',
136 new sidecar.SidecarPlugin(),
139 readPackageJson: async (_config, packageJson) => {
140 packageJson.analytics = {};
142 if (process.env.SENTRY_TOKEN) {
143 packageJson.analytics.sentry = {
144 token: process.env.SENTRY_TOKEN,
148 if (process.env.AMPLITUDE_TOKEN) {
149 packageJson.analytics.amplitude = {
150 token: 'balena-etcher',
154 // packageJson.packageType = 'dmg' | 'AppImage' | 'rpm' | 'deb' | 'zip' | 'nsis' | 'portable'
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) => {
163 `ln -s "${options.outputPaths}/balena-etcher" "${options.outputPaths}/balenaEtcher"`,
178 export default config;