podman-desktop/.electron-builder.config.cjs
Florent BENOIT 67b91164ae
chore(deps): update electron-builder from v26.0.12 to v26.7.0 (#16166)
* chore(deps): update electron-builder from v26.0.12 to v26.7.0

- remove the patch we had to fix background on macOS v26
- add the non @2x background else the window size is broken
(before there was a bug being fixed now)

Signed-off-by: Florent Benoit <fbenoit@redhat.com>

* chore: handle universal binaries
Signed-off-by: Florent Benoit <fbenoit@redhat.com>

* chore(builder): replace @1x DMG background (#5)

Signed-off-by: Václav Vančura <vancura@users.noreply.github.com>

---------

Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Signed-off-by: Václav Vančura <vancura@users.noreply.github.com>
Co-authored-by: Václav Vančura <vancura@users.noreply.github.com>
2026-02-11 16:17:35 +01:00

353 lines
12 KiB
JavaScript

/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
const { exec, execFile } = require('child_process');
const Arch = require('builder-util').Arch;
const path = require('path');
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses');
const product = require('./product.json');
const fs = require('node:fs');
if (process.env.VITE_APP_VERSION === undefined) {
const now = new Date();
process.env.VITE_APP_VERSION = `${now.getUTCFullYear() - 2000}.${now.getUTCMonth() + 1}.${now.getUTCDate()}-${
now.getUTCHours() * 60 + now.getUTCMinutes()
}`;
}
let macosArches = ['x64', 'arm64', 'universal'];
let artifactNameSuffix = '';
if (process.env.AIRGAP_DOWNLOAD) {
artifactNameSuffix = '-airgap';
// Create dedicated but not universal builds for airgap as it's > 2GB for macOS
macosArches = ['x64', 'arm64'];
}
async function addElectronFuses(context) {
const { electronPlatformName, arch } = context;
const ext = {
darwin: '.app',
win32: '.exe',
linux: [''],
}[electronPlatformName];
const IS_LINUX = context.electronPlatformName === 'linux';
const executableName = IS_LINUX
? context.packager.appInfo.productFilename.toLowerCase().replace('-dev', '').replace(' ', '-')
: context.packager.appInfo.productFilename; // .toLowerCase() to accomodate Linux file named `name` but productFileName is `Name` -- Replaces '-dev' because on Linux the executable name is `name` even for the DEV builds
const electronBinaryPath = path.join(context.appOutDir, `${executableName}${ext}`);
let electronEnableInspect = false;
if (process.env.ELECTRON_ENABLE_INSPECT === 'true') {
electronEnableInspect = true;
}
await flipFuses(electronBinaryPath, {
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: electronEnableInspect,
});
}
/**
* This function will start the script that will bundle the extensions#remote from the `product.json`
* to the extensions-extra folder
*
* @remarks it should be called in the beforePack to populate the folder extensions-extra before electron builder pack them
*/
async function packageRemoteExtensions(context) {
const downloadScript = path.join('packages', 'main', 'dist', 'download-remote-extensions.cjs');
if (!fs.existsSync(downloadScript)) {
console.warn(`${downloadScript} not found, skipping remote extension download`);
return;
}
const destination = path.resolve('./extensions-extra');
await new Promise((resolve, reject) => {
execFile(
'node',
[downloadScript, `--output=${destination}`],
{ maxBuffer: 10 * 1024 * 1024 }, // use 10MB else default size is too small and we get stdout maxBuffer length exceeded
(error, stdout, stderr) => {
console.log(stdout);
console.log(stderr);
if (error) {
reject(error);
} else {
resolve();
}
},
);
});
context.packager.config.extraResources.push('./extensions-extra/**');
}
/**
* @type {import('electron-builder').Configuration}
* @see https://www.electron.build/configuration/configuration
*/
const config = {
productName: product.name,
appId: product.appId,
directories: {
output: 'dist',
buildResources: 'buildResources',
},
buildDependenciesFromSource: false,
npmRebuild: false,
beforePack: async context => {
const DEFAULT_ASSETS = [];
const PODMAN_EXTENSION_ASSETS = 'extensions/podman/packages/extension/assets';
context.packager.config.extraResources = DEFAULT_ASSETS;
// download & package remote extensions
await packageRemoteExtensions(context);
// include product.json
context.packager.config.extraResources.push({
from: 'product.json',
to: 'product.json',
});
// universal build, add both pkg files
// this is hack to avoid issue https://github.com/electron/universal/issues/36
if (
context.appOutDir.endsWith('mac-universal-x64-temp') ||
context.appOutDir.endsWith('mac-universal-arm64-temp')
) {
context.packager.config.extraResources = DEFAULT_ASSETS;
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-installer-macos-universal*.pkg`);
return;
}
if (context.arch === Arch.arm64 && context.electronPlatformName === 'darwin') {
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-installer-macos-aarch64-*.pkg`);
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-image-arm64.zst`);
}
if (context.arch === Arch.x64 && context.electronPlatformName === 'darwin') {
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-installer-macos-amd64-*.pkg`);
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-image-x64.zst`);
}
if (context.electronPlatformName === 'win32') {
// add the win-ca package
context.packager.config.extraResources.push({
from: 'node_modules/win-ca/lib/roots.exe',
to: 'win-ca/roots.exe',
});
// add podman installer
if (context.arch === Arch.x64) {
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-installer-windows-amd64.msi`);
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-image-x64.zst`);
}
if (context.arch === Arch.arm64) {
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-installer-windows-arm64.msi`);
context.packager.config.extraResources.push(`${PODMAN_EXTENSION_ASSETS}/podman-image-arm64.zst`);
}
}
},
afterPack: async context => {
await addElectronFuses(context);
},
files: ['packages/**/dist/**', 'extensions/**/builtin/*.cdix/**', 'packages/main/src/assets/**'],
portable: {
artifactName: `${product.artifactName}${artifactNameSuffix}-\${version}-\${arch}.\${ext}`,
},
nsis: {
artifactName: `${product.artifactName}${artifactNameSuffix}-\${version}-setup-\${arch}.\${ext}`,
oneClick: false,
include: 'buildResources/installer.nsh',
},
win: {
target: [
{
target: 'portable',
arch: ['x64', 'arm64'],
},
{
target: 'nsis',
arch: ['x64', 'arm64'],
},
],
/**
* Use Azure Keyvault to sign the Windows binaries (using Digicert timestamp server and not Azure Trusted Signing).
*/
signtoolOptions: {
sign: configuration => azureKeyvaultSign(configuration.path),
},
},
flatpak: {
license: 'LICENSE',
finishArgs: [
'--socket=wayland',
'--socket=x11',
'--share=ipc',
// Open GL
'--device=dri',
// Read/write home directory access
'--filesystem=home',
// Read-only access to /usr and /etc for managed-configuration support.
// Flatpak sandboxes these directories, so we can't use --filesystem=/usr/share/podman-desktop:ro directly.
// host-os:ro only exposes /usr and parts of /etc (not the full filesystem).
// See: https://github.com/flatpak/flatpak/issues/5575
// See: https://man7.org/linux/man-pages/man5/flatpak-metadata.5.html (host-os section)
'--filesystem=host-os:ro',
// Read podman socket
'--filesystem=xdg-run/podman:create',
// Read/write containers directory access (ability to save the application preferences)
'--filesystem=xdg-run/containers:create',
// Read docker socket
'--filesystem=/run/docker.sock',
// Allow communication with network
'--share=network',
// System notifications with libnotify
'--talk-name=org.freedesktop.Notifications',
// Allow safeStorage access to keyring to encrypt/decrypt file used to store sensitive information
// In Gnome Desktop Environment
'--talk-name=org.freedesktop.secrets',
// In KDE Desktop Environment
'--talk-name=org.kde.kwalletd6',
// Allow registration and management of system tray icons and their associated
// notifications in KDE Desktop Environment
'--talk-name=org.kde.StatusNotifierWatcher',
// Allow to interact with Flatpak system to execute commands outside the application's sandbox
'--talk-name=org.freedesktop.Flatpak',
// required to fix cursor scaling on wayland https://github.com/electron/electron/issues/19810 when the user uses --socket=wayland in their flatpak run
'--env=XCURSOR_PATH=/run/host/user-share/icons:/run/host/share/icons',
'--env=XDG_SESSION_TYPE=x11',
],
useWaylandFlags: 'false',
artifactName: `${product.artifactName}-\${version}.\${ext}`,
runtimeVersion: '25.08',
branch: 'main',
files: [
['.flatpak-appdata.xml', '/share/metainfo/io.podman_desktop.PodmanDesktop.metainfo.xml'],
['buildResources/icon-512x512.png', '/share/icons/hicolor/512x512/apps/io.podman_desktop.PodmanDesktop.png'],
],
},
linux: {
category: 'Development',
icon: './buildResources/icon-512x512.png',
executableName: product.artifactName,
artifactName: `${product.artifactName}${artifactNameSuffix}-\${version}-\${arch}.\${ext}`,
target: ['flatpak', { target: 'tar.gz', arch: ['x64', 'arm64'] }],
},
mac: {
artifactName: `${product.artifactName}${artifactNameSuffix}-\${version}-\${arch}.\${ext}`,
hardenedRuntime: true,
entitlements: './node_modules/electron-builder-notarize/entitlements.mac.inherit.plist',
x64ArchFiles: 'Contents/Resources/app.asar.unpacked/**/*.node',
target: {
target: 'default',
arch: macosArches,
},
},
dmg: {
background: 'buildResources/dmg-background.png',
window: {
width: 540,
height: 380,
},
contents: [
{
x: 410,
y: 166,
type: 'link',
path: '/Applications',
},
{
x: 130,
y: 166,
type: 'file',
},
],
},
protocols: {
name: product.name,
schemes: [product.urlProtocol],
role: 'Editor',
},
publish: {
provider: 'github',
timeout: 10000,
},
/*extraMetadata: {
version: process.env.VITE_APP_VERSION,
},*/
};
// do not publish auto-update files for airgap mode
if (process.env.AIRGAP_DOWNLOAD) {
config.publish = {
publishAutoUpdate: false,
provider: 'github',
};
}
/**
* Use a keyvault instance that has a certificate to sign the Windows binaries.
* @param filePath
* @return {Promise<void>}
*/
const azureKeyvaultSign = filePath => {
if (!process.env.AZURE_KEY_VAULT_URL) {
console.log('Skipping code signing, no environment variables set for that.');
return Promise.resolve();
}
return new Promise((resolve, reject) => {
const {
AZURE_KEY_VAULT_TENANT_ID,
AZURE_KEY_VAULT_CLIENT_ID,
AZURE_KEY_VAULT_SECRET,
AZURE_KEY_VAULT_URL,
AZURE_KEY_VAULT_CERTIFICATE,
} = process.env;
// eslint-disable-next-line no-console
console.log('Signing file', filePath);
const command = `AzureSignTool sign -kvu ${AZURE_KEY_VAULT_URL} -kvi ${AZURE_KEY_VAULT_CLIENT_ID} -kvt ${AZURE_KEY_VAULT_TENANT_ID} -kvs ${AZURE_KEY_VAULT_SECRET} -kvc ${AZURE_KEY_VAULT_CERTIFICATE} -tr http://timestamp.digicert.com -v '${filePath}'`;
exec(command, { shell: 'powershell.exe' }, (e, stdout, stderr) => {
if (e instanceof Error) {
console.log(e);
reject(e);
return;
}
if (stderr) {
reject(new Error(stderr));
return;
}
if (stdout.indexOf('Signing completed successfully') > -1) {
// eslint-disable-next-line no-console
console.log(stdout);
resolve();
} else {
reject(new Error(stdout));
}
});
});
};
module.exports = config;