packaging: allow toggling to user scope in Windows installer (#2233)

This commit is contained in:
Clement Tsang
2026-09-06 00:14:41 -04:00
committed by GitHub
parent 16ad7783a2
commit a64b7a900f
3 changed files with 164 additions and 155 deletions
+7 -6
View File
@@ -355,10 +355,12 @@ jobs:
run: |
choco install dotnet-sdk --pre -y --no-progress;
- name: Install wixtoolset
- name: Install WiX Toolset
shell: powershell
run: |
choco install -y wixtoolset --no-progress;
dotnet tool install --global wix --version 4.0.6
"$env:USERPROFILE\.dotnet\tools" | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8
wix extension add --global WixToolset.UI.wixext/4.0.6
- name: Read Rust version
shell: bash
@@ -376,16 +378,15 @@ jobs:
- name: Install cargo-wix
shell: powershell
run: |
cargo install cargo-wix --version 0.3.8 --locked
# We use a git version as the newest stable version doesn't support WiX 4 unfortunately.
cargo install cargo-wix --git https://github.com/volks73/cargo-wix --rev 9a8ed9486637e1fb839f209730eda6c95fd12d88 --locked
- name: Build MSI file
shell: powershell
env:
BTM_GENERATE: true
run: |
Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1"
refreshenv
cargo wix --nocapture
cargo wix --toolset modern --nocapture
mv bottom_installer.msi ${{ matrix.info.output }}
- name: Generate artifact attestation for file
@@ -45,13 +45,14 @@ Some builds use [`cross`](https://github.com/cross-rs/cross) to do cross-compila
## MSI
This builds a full Windows installer using [`cargo-wix`](https://github.com/volks73/cargo-wix). This requires some setup beforehand with some dependencies:
This builds a full Windows installer using [`cargo-wix`](https://github.com/volks73/cargo-wix) and [WiX Toolset 4](https://github.com/wixtoolset/wix).
This requires some setup beforehand with some dependencies:
- Net-Framework-Core (handled by Powershell)
- wixtoolset (handled by chocolatey)
- WiX Toolset 4 (needs to be separately installed on GitHub runners as a .NET tool)
- Rust toolchain
After that, cache is enabled, and `cargo wix` takes care of the rest.
After that, `cargo wix` takes care of the rest.
## `.deb`
+153 -146
View File
@@ -1,4 +1,4 @@
<?xml version='1.0' encoding='windows-1252'?>
<?xml version='1.0' encoding='utf-8'?>
<!--
Copyright (C) 2017 Christopher R. Field.
@@ -16,66 +16,41 @@
-->
<!--
The "cargo wix" subcommand provides a variety of predefined variables available
for customization of this template. The values for each variable are set at
installer creation time. The following variables are available:
The release workflow provides the following variables at installer build time:
TargetTriple = The rustc target triple name.
TargetEnv = The rustc target environment. This is typically either
"msvc" or "gnu" depending on the toolchain downloaded and
installed.
TargetVendor = The rustc target vendor. This is typically "pc", but Rust
does support other vendors, like "uwp".
CargoTargetBinDir = The complete path to the directory containing the
binaries (exes) to include. The default would be
"target\release\". If an explicit rustc target triple is
used, i.e. cross-compiling, then the default path would
be "target\<CARGO_TARGET>\<CARGO_PROFILE>",
where "<CARGO_TARGET>" is replaced with the "CargoTarget"
variable value and "<CARGO_PROFILE>" is replaced with the
value from the "CargoProfile" variable. This can also
be overridden manually with the "target-bin-dir" flag.
binaries to include.
CargoTargetDir = The path to the directory for the build artifacts, i.e.
"target".
CargoProfile = The cargo profile used to build the binaries
(usually "debug" or "release").
Version = The version for the installer. The default is the
"Major.Minor.Fix" semantic versioning number of the Rust
package.
Version = The version of the Rust package.
-->
<!--
Please do not remove these pre-processor If-Else blocks. These are used with
the `cargo wix` subcommand to automatically determine the installation
destination for 32-bit versus 64-bit installers. Removal of these lines will
cause installation errors.
-->
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>
<Wix
xmlns='http://wixtoolset.org/schemas/v4/wxs'
xmlns:ui='http://wixtoolset.org/schemas/v4/wxs/ui'>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product
Id='*'
<!--
Scope='perUserOrMachine' makes this a dual-purpose package: it can install
per-machine (elevated, into Program Files) or per-user (non-elevated, into
%LocalAppData%). winget's user scope drives the per-user path silently
via MSIINSTALLPERUSER=1. See the SetProperty for APPLICATIONFOLDER below,
which redirects the install directory for the per-user case.
-->
<Package
Name='bottom'
UpgradeCode='3C90C27D-8372-4C82-B03C-020393CB983D'
Manufacturer='Clement Tsang'
Language='1033'
Codepage='1252'
Version='$(var.Version)'>
Version='$(var.Version)'
InstallerVersion='500'
Compressed='yes'
Scope='perUserOrMachine'>
<Package Id='*'
<SummaryInformation
Keywords='Installer'
Description='A customizable cross-platform graphical process/system monitor for the terminal. Supports Linux, macOS, and Windows.'
Manufacturer='Clement Tsang'
InstallerVersion='450'
Languages='1033'
Compressed='yes'
InstallScope='perMachine'
SummaryCodepage='1252'
/>
<MajorUpgrade
@@ -85,93 +60,127 @@
<Media Id='1' Cabinet='media1.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'/>
<Property Id='DiskPrompt' Value='bottom Installation'/>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
<Directory Id='APPLICATIONFOLDER' Name='bottom'>
<!--
Disabling the license sidecar file in the installer is a two step process:
<!--
Default install location is Program Files (used for per-machine
installs). For per-user installs the SetProperty below overrides
APPLICATIONFOLDER to point at %LocalAppData%\Programs\bottom before
costing, so a non-elevated user can write to it.
-->
<StandardDirectory Id='ProgramFiles6432Folder'>
<Directory Id='APPLICATIONFOLDER' Name='bottom'>
<!--
Disabling the license sidecar file in the installer is a two step process:
1. Comment out or remove the `Component` tag along with its contents.
2. Comment out or remove the `ComponentRef` tag with the "License" Id
attribute value further down in this file.
1. Comment out or remove the `Component` tag along with its contents.
2. Comment out or remove the `ComponentRef` tag with the "License" Id
attribute value further down in this file.
-->
<Component Id='License' Guid='*'>
<File Id='LicenseFile'
DiskId='1'
Source='wix\License.rtf'
KeyPath='yes'/>
</Component>
<Directory Id='Completions' Name='completions'>
<Component Id='btmPowershell' Guid='*'>
<File
Id='btmPs1'
Name='_btm.ps1'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\_btm.ps1'
KeyPath='yes'/>
</Component>
<Component Id='btmNu' Guid='*'>
<File
Id='btmNu'
Name='btm.nu'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\btm.nu'
KeyPath='yes'/>
</Component>
<Component Id='btmFish' Guid='*'>
<File
Id='btmFish'
Name='btm.fish'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\btm.fish'
KeyPath='yes'/>
</Component>
<Component Id='btmBash' Guid='*'>
<File
Id='btmBash'
Name='btm.bash'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\btm.bash'
KeyPath='yes'/>
</Component>
<Component Id='btmZsh' Guid='*'>
<File
Id='btmZsh'
Name='_btm'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\_btm'
KeyPath='yes'/>
</Component>
</Directory>
<Directory Id='Bin' Name='bin'>
<!--
Two PATH components, gated on scope:
- Path (per-machine): writes the system PATH; requires elevation.
- UserPath (per-user): writes the user PATH; no elevation needed.
ALLUSERS resolves to 1 for per-machine installs and empty for
per-user installs, so exactly one of these is installed.
-->
<Component Id='License' Guid='*'>
<File Id='LicenseFile'
<Component Id='Path' Guid='15D841CF-0363-4DBB-BF55-ECCB43B9EB03' KeyPath='yes' Condition='ALLUSERS'>
<Environment
Id='PATH'
Name='PATH'
Value='[Bin]'
Permanent='no'
Part='last'
Action='set'
System='yes'/>
</Component>
<Component Id='UserPath' Guid='9A690C7B-4694-4DBF-9846-676943D0D166' KeyPath='yes' Condition='NOT ALLUSERS'>
<Environment
Id='UserPATH'
Name='PATH'
Value='[Bin]'
Permanent='no'
Part='last'
Action='set'
System='no'/>
</Component>
<Component Id='binary0' Guid='*'>
<File
Id='exe0'
Name='btm.exe'
DiskId='1'
Source='wix\License.rtf'
Source='$(var.CargoTargetBinDir)\btm.exe'
KeyPath='yes'/>
</Component>
<Directory Id='Completions' Name='completions'>
<Component Id='btmPowershell' Guid='*'>
<File
Id='btmPs1'
Name='_btm.ps1'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\_btm.ps1'
KeyPath='yes'/>
</Component>
<Component Id='btmNu' Guid='*'>
<File
Id='btmNu'
Name='btm.nu'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\btm.nu'
KeyPath='yes'/>
</Component>
<Component Id='btmFish' Guid='*'>
<File
Id='btmFish'
Name='btm.fish'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\btm.fish'
KeyPath='yes'/>
</Component>
<Component Id='btmBash' Guid='*'>
<File
Id='btmBash'
Name='btm.bash'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\btm.bash'
KeyPath='yes'/>
</Component>
<Component Id='btmZsh' Guid='*'>
<File
Id='btmZsh'
Name='_btm'
DiskId='1'
Source='$(var.CargoTargetDir)\tmp\bottom\completion\_btm'
KeyPath='yes'/>
</Component>
</Directory>
<Directory Id='Bin' Name='bin'>
<Component Id='Path' Guid='15D841CF-0363-4DBB-BF55-ECCB43B9EB03' KeyPath='yes'>
<Environment
Id='PATH'
Name='PATH'
Value='[Bin]'
Permanent='no'
Part='last'
Action='set'
System='yes'/>
</Component>
<Component Id='binary0' Guid='*'>
<File
Id='exe0'
Name='btm.exe'
DiskId='1'
Source='$(var.CargoTargetBinDir)\btm.exe'
KeyPath='yes'/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</StandardDirectory>
<!--
Redirect the install directory to a user-writable location for per-user
installs (ALLUSERS is empty when installing per-user). Must run before
CostFinalize so the new path is used for costing and file layout, and it
is sequenced in both the UI and execute sequences so it also applies to
silent installs (e.g. winget user-scope installs).
-->
<SetProperty Id='APPLICATIONFOLDER'
Value='[LocalAppDataFolder]Programs\bottom'
Before='CostFinalize'
Sequence='both'
Condition='NOT ALLUSERS'/>
<Feature
Id='Binaries'
@@ -181,13 +190,13 @@
ConfigurableDirectory='APPLICATIONFOLDER'
AllowAdvertise='no'
Display='expand'
Absent='disallow'>
AllowAbsent='no'>
<!--
Comment out or remove the following `ComponentRef` tag to remove
the license sidecar file from the installer.
-->
<ComponentRef Id='License'/>
<ComponentRef Id='btmPowershell'/>
<ComponentRef Id='btmNu'/>
<ComponentRef Id='btmFish'/>
@@ -199,16 +208,17 @@
<Feature
Id='Environment'
Title='PATH Environment Variable'
Description='Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.'
Description='Add the install location of the [ProductName] executable to the PATH environment variable. This allows the [ProductName] executable to be called from any location.'
Level='1'
Absent='allow'>
AllowAbsent='yes'>
<ComponentRef Id='Path'/>
<ComponentRef Id='UserPath'/>
</Feature>
</Feature>
<SetProperty Id='ARPINSTALLLOCATION' Value='[APPLICATIONFOLDER]' After='CostFinalize'/>
<!--
Uncomment the following `Icon` and `Property` tags to change the product icon.
@@ -219,28 +229,25 @@
<!--<Property Id='ARPPRODUCTICON' Value='ProductICO' />-->
<Property Id='ARPHELPLINK' Value='https://bottom.pages.dev/stable'/>
<UI>
<UIRef Id='WixUI_FeatureTree'/>
<!--
Disabling the EULA dialog in the installer is a two step process:
1. Uncomment the following two `Publish` tags
2. Comment out or remove the `<WiXVariable Id='WixUILicenseRtf'...` tag further down
<ui:WixUI Id='WixUI_FeatureTree'/>
<!--
Disabling the EULA dialog in the installer is a two step process:
-->
<!--<Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>-->
<!--<Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>-->
</UI>
1. Uncomment the following two `Publish` tags
2. Comment out or remove the `<WiXVariable Id='WixUILicenseRtf'...` tag further down
-->
<!--<Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>-->
<!--<Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>-->
<!--
Disabling the EULA dialog in the installer requires commenting out
or removing the following `WixVariable` tag
-->
<WixVariable Id='WixUILicenseRtf' Value='wix\License.rtf'/>
<!--
Uncomment the next `WixVariable` tag to customize the installer's
Graphical User Interface (GUI) and add a custom banner image across
@@ -251,7 +258,7 @@
-->
<!--<WixVariable Id='WixUIBannerBmp' Value='wix\Banner.bmp'/>-->
<!--
Uncomment the next `WixVariable` tag to customize the installer's
Graphical User Interface (GUI) and add a custom image to the first
@@ -262,6 +269,6 @@
-->
<!--<WixVariable Id='WixUIDialogBmp' Value='wix\Dialog.bmp'/>-->
</Product>
</Package>
</Wix>