Skip to content

Commit

Permalink
Merge pull request #1103 from nextcloud/build/windows-msi
Browse files Browse the repository at this point in the history
build: windows .msi via WiX
  • Loading branch information
ShGKme authored Feb 17, 2025
2 parents ba6d52e + fe29b48 commit 354be6e
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 25 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@

All binaries and `beta` releases are available on [Nextcloud Releases](https://github.com/nextcloud-releases/talk-desktop/releases).

| Platform (arch) | Distribution type | Download link |
|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| **🐧 Linux** (x64) | [Flatpak](https://flatpak.org) single file (recommended) | [Nextcloud.Talk-linux-x64.flatpak](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-linux-x64.flatpak) |
| **🐧 Linux** (x64) | ZIP archive | [Nextcloud.Talk-linux-x64.zip](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-linux-x64.zip) |
| **🍎 macOS** (Universal) | Disc Image | [Nextcloud.Talk-macos-universal.dmg](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-macos-universal.dmg) |
| **🪟 Windows** (x64) | Non-admin single-user one-click installer (recommended) | [Nextcloud.Talk-windows-x64.exe](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-windows-x64.exe) |
| **🪟 Windows** (x64) | [MSI Deployment Tool](https://github.com/Squirrel/Squirrel.Windows/blob/develop/docs/using/machine-wide-installs.md) (for administrated environments, experimental) | [Nextcloud.Talk-windows-x64.msi](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-windows-x64.msi) |
| Platform (arch) | Distribution type | Download link |
|--------------------------|-----------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| **🐧 Linux** (x64) | [Flatpak](https://flatpak.org) single file (recommended) | [Nextcloud.Talk-linux-x64.flatpak](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-linux-x64.flatpak) |
| **🐧 Linux** (x64) | ZIP archive | [Nextcloud.Talk-linux-x64.zip](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-linux-x64.zip) |
| **🍎 macOS** (Universal) | Disc Image | [Nextcloud.Talk-macos-universal.dmg](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-macos-universal.dmg) |
| **🪟 Windows** (x64) | Non-admin single-user one-click installer (recommended) | [Nextcloud.Talk-windows-x64.exe](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-windows-x64.exe) |
| **🪟 Windows** (x64) | [MSI](https://github.com/electron-userland/electron-wix-msi/blob/master/guides/enduser.md) (for administrated environments) | [Nextcloud.Talk-windows-x64.msi](https://github.com/nextcloud-releases/talk-desktop/releases/latest/download/Nextcloud.Talk-windows-x64.msi) |

### via Package manager

Expand Down
6 changes: 6 additions & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ SPDX-FileCopyrightText = "2024 Nextcloud GmbH"
SPDX-License-Identifier = "CC-BY-SA-4.0"
SPDX-FileAttributionText = "Modified jenna-kim-the-globe.webp with app icon placeholders and an arrow on top to use as a background image for the macOS DMG installer"

[[annotations]]
path = ["img/wix-background.bmp", "img/wix-banner.bmp"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2025 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "LicenseRef-NextcloudTrademarks"

[[annotations]]
path = "resources/vue-devtools.crx"
precedence = "aggregate"
Expand Down
99 changes: 91 additions & 8 deletions forge.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { MakerSquirrel } = require('@electron-forge/maker-squirrel')
const { MakerDMG } = require('@electron-forge/maker-dmg')
const { MakerFlatpak } = require('@electron-forge/maker-flatpak')
const { MakerZIP } = require('@electron-forge/maker-zip')
const { MakerWix } = require('@electron-forge/maker-wix')
const packageJSON = require('./package.json')
const { MIN_REQUIRED_BUILT_IN_TALK_VERSION } = require('./src/constants.js')

Expand All @@ -25,7 +26,8 @@ const CONFIG = {
// macOS
appleAppBundleId: 'com.nextcloud.talk.mac',
// Windows
winAppId: 'NextcloudTalk',
winSquirrelAppId: 'NextcloudTalk', // Squirrel.Windows will transform it to com.squirrel.{AppId}.{AppId}
winAppId: 'com.nextcloud.talk',
// Linux
linuxAppId: 'com.nextcloud.talk',
}
Expand Down Expand Up @@ -73,8 +75,8 @@ function fixArtifactName(artifactPath, platform, arch) {
const artifactName = path.basename(artifactPath)
const ext = path.extname(artifactName)

// For Windows names are configurable in Squirrel distribution
if (platform === 'win32') {
// For Squirrel.Windows names are configurable in the maker
if (platform === 'win32' && ext === '.exe') {
return artifactPath
}

Expand All @@ -87,6 +89,59 @@ function fixArtifactName(artifactPath, platform, arch) {
return output
}

/**
* Convert signWithParams string to @electron/windows-sign options
* to fix issues of @electron/windows-sign
* @param {string} signWithParams - @electron/windows-sign's signWithParams string
* @return {object} - @electron/windows-sign options
*/
function signWithParamsToWindowsSignOptions(signWithParams) {
// @electron/windows-sign options
const windowsSign = {}

// Split args values without quotes wrap
// Otherwise @electron/windows-sign will treat double quotes as part of the value
// See: https://github.com/electron/windows-sign/issues/45
const parsed = [...signWithParams.matchAll(/(?:([^\s"]+)|"([^"]*)")+/g)].map((matched) => matched[1] || matched[2])

// @electron/windows-sign has some default options that define signtool params.
// Duplicating any param leads to an error in the signtool.
// So avoid this, any param that can be defined in options must be set as an option
// and removed from params string.
// See: https://github.com/electron/windows-sign/issues/46
// Note: multiple hashes is not supported

const extractOption = (param, option) => {
const index = parsed.indexOf(param)
if (index !== -1) {
const withValue = parsed[index + 1] && !parsed[index + 1].startsWith('/')
windowsSign[option] = withValue ? parsed[index + 1] : true
parsed.splice(index, withValue ? 2 : 1)
}
}

extractOption('/a', 'automaticallySelectCertificate')
extractOption('/as', 'appendSignature')
extractOption('/tr', 'timestampServer')
extractOption('/td', 'hashes')
extractOption('/t', 'timestampServer')
extractOption('/f', 'certificateFile')
extractOption('/p', 'certificatePassword')
extractOption('/fd', 'hashes')
extractOption('/d', 'description')
extractOption('/du', 'website')
extractOption('/debug', 'debug')
if (windowsSign.hashes) {
// @electron/window-sign only supports lower case hash
windowsSign.hashes = windowsSign.hashes.toLowerCase()
}

// Set parsed to an array to avoid quoting issues
windowsSign.signWithParams = parsed

return windowsSign
}

const hasMacosSign = !!(process.env.APPLE_ID && process.env.APPLE_ID_PASSWORD && process.env.APPLE_TEAM_ID)
const hasWindowsSign = !!process.env.WINDOWS_SIGN_PARAMS

Expand Down Expand Up @@ -149,7 +204,7 @@ module.exports = {
// Common
name: CONFIG.applicationName,
icon: path.join(__dirname, './img/icons/icon'),
appCopyright: `Copyright © ${YEAR} ${CONFIG.companyName}`,
appCopyright: `Copyright (c) ${YEAR} ${CONFIG.companyName}`,
asar: true,

// Windows
Expand All @@ -172,17 +227,45 @@ module.exports = {
},

makers: [
// https://github.com/electron-userland/electron-wix-msi/
// https://js.electronforge.io/interfaces/_electron_forge_maker_wix.MakerWixConfig.html
// https://github.com/bitdisaster/Squirrel.Msi/
// Prerequisites:
// 1. winget install WiXToolset.WiXToolset
// 2. Add C:\Program Files (x86)\WiX Toolset v3.14\bin\ to PATH
new MakerWix({
appUserModelId: CONFIG.winAppId,
description: CONFIG.description,
exe: `${CONFIG.applicationName}.exe`,
name: CONFIG.applicationName,
icon: path.join(__dirname, 'img/icons/icon.ico'),
manufacturer: CONFIG.companyName,
shortName: CONFIG.applicationNameSanitized,
arch: 'x64', // electron-wix-msi defaults to x86
// Pass the version explicitly
// otherwise MakerWix makes versions with prerelease tags invalid semantic version
// which breaks app launch via stub executable
// See: https://github.com/electron/forge/issues/3805
version: packageJSON.version,
ui: {
images: {
background: path.join(__dirname, 'img/wix-background.bmp'),
banner: path.join(__dirname, 'img/wix-banner.bmp'),
},
},
windowsSign: hasWindowsSign && signWithParamsToWindowsSignOptions(process.env.WINDOWS_SIGN_PARAMS),
}),

// https://github.com/squirrel/squirrel.windows
// https://js.electronforge.io/interfaces/_electron_forge_maker_squirrel.InternalOptions.SquirrelWindowsOptions.html#setupExe
new MakerSquirrel({
// App/Filenames
name: CONFIG.winAppId,
name: CONFIG.winSquirrelAppId,
setupExe: generateDistName('win32', 'x64', '.exe'),
setupMsi: generateDistName('win32', 'x64', '.msi'),
exe: `${CONFIG.applicationName}.exe`,

// Add MSI for administrated environments
noMsi: false,
// Covered by WiX
noMsi: true,

// Meta
title: CONFIG.applicationName,
Expand Down
Binary file added img/wix-background.bmp
Binary file not shown.
Binary file added img/wix-banner.bmp
Binary file not shown.
Loading

0 comments on commit 354be6e

Please sign in to comment.