mirror of
https://github.com/nushell/nushell.git
synced 2025-06-10 12:06:51 +02:00
<!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Publishing Nushell to winget has always been a challenge for us, and to this day, many issues remain unresolved—and some seem almost impossible to fix. The road to solving these problems may be winding and long, but it's time for us to set out on this journey. This PR try to fix the Windows arm64 release binaries and some `winget` related issues: - [x] Fixes https://github.com/nushell/nushell/issues/14815: build Windows arm64 binaries by Windows arm64 runner - [x] Upgrade WiX Toolset to latest 6.0 version: WiX 3 we used currently doesn't support arm64 arch and [WiX v4 Security Fixes End Date is 2025/02/05](https://docs.firegiant.com/wix/) - [x] Update the **nightly** workflow to make it work for all future releases - [x] Update the **release** workflow to make it work for all future releases - [x] Fixes https://github.com/nushell/nushell/issues/15698 - [x] Fixes https://github.com/nushell/nushell/issues/13719 so that Nushell should be possible to be installed via winget with both user and machine scope - [x] Fixes https://github.com/nushell/nushell/issues/5927 - [x] Try to fix https://github.com/nushell/nushell/issues/14786 - [x] Fixes https://github.com/nushell/nushell/issues/9537 ## Related but not planed issues: - Related https://github.com/nushell/nushell/issues/13017 - Related https://github.com/nushell/nushell/issues/8053 # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> - Nushell should be possible to be installed via winget with both user and machine scope and The default should be user scope - User scope install by winget: `winget install Nushell.Nushell` - User scope install by msiexec: `msiexec /i nu-0.104.1-x86_64-pc-windows-msvc.msi /quiet /qn` - Machine scope install by winget: `winget install Nushell.Nushell --override 'ALLUSERS=1'` - Machine scope install by msiexec: `msiexec /i nu-0.104.1-x86_64-pc-windows-msvc.msi ALLUSERS=1` - Note that `--scope` flag for `winget install` does not work use `--override` instead - Default user scope install dir: `$'($nu.home-path)\AppData\Local\Programs\nu\'` - Default machine scope install dir: `C:\Program Files\nu\` - When a standard user runs the installer and selects "Install for everyone" (per-machine installation), Windows will automatically trigger a UAC prompt, the user can enter admin credentials and the installation will proceed with elevated privileges - [hustcer/setup-nu](https://github.com/hustcer/setup-nu) should work for `windows-11-arm` runners # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> The latest MSI builds are available here: https://github.com/nushell/nightly/releases/tag/v0.104.1 Actually all the nightly releases were built with latest changes included: https://github.com/nushell/nightly/releases `winget` and `msiexec` install tests goes here: https://github.com/nushell/integrations/pull/49 https://github.com/nushell/integrations/actions/runs/14974621061 https://github.com/nushell/integrations/actions/runs/14974621054 ### Test winget install locally: - git clone git@github.com:nushell/integrations.git - User scope install: `winget install -m manifests\n\Nushell\Nushell\0.104.1\` - Run: `use tests\common.nu *; check-user-install` - Machine scope install: `winget install -m manifests\n\Nushell\Nushell\0.104.1\ --override 'ALLUSERS=1'` - Run: `use tests\common.nu *; check-local-machine-install` # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> @fdncred I suggest releasing a patch version after merging this PR (only the changes of this PR will be included) to ensure that the winget release process works properly. This way, we can be more confident when releasing version 0.105.0. References: - https://learn.microsoft.com/en-us/windows/win32/msi/single-package-authoring - https://learn.microsoft.com/en-us/windows/package-manager/winget/source#add - https://github.com/microsoft/winget-pkgs/blob/master/doc/tools/SandboxTest.md - https://docs.firegiant.com/quick-start/ - https://docs.firegiant.com/wix3/tutorial/getting-started/putting-it-to-use/#_top - https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/msiexec#set-public-properties
298 lines
14 KiB
XML
298 lines
14 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<!--
|
|
- https://learn.microsoft.com/en-us/windows/win32/msi/single-package-authoring
|
|
- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/msiexec
|
|
-->
|
|
|
|
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
|
|
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui"
|
|
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
|
|
|
<?define ProductName = "Nushell" ?>
|
|
<?define ApplicationFolderName = "nu" ?>
|
|
<?define ProductVersion = "$(env.NU_RELEASE_VERSION)" ?>
|
|
<?define Manufacturer = "The Nushell Project Developers" ?>
|
|
<?define UpgradeCode = "82D756D2-19FA-4F09-B10F-64942E89F364" ?>
|
|
|
|
<!-- https://docs.firegiant.com/wix/schema/wxs/package/ -->
|
|
<Package
|
|
Compressed="yes"
|
|
Id="Nushell.Nushell"
|
|
InstallerVersion="500"
|
|
Scope="perUserOrMachine"
|
|
Name="$(var.ProductName)"
|
|
Version="$(var.ProductVersion)"
|
|
UpgradeCode="$(var.UpgradeCode)"
|
|
Manufacturer="$(var.Manufacturer)" >
|
|
|
|
<MajorUpgrade
|
|
MigrateFeatures="yes"
|
|
Schedule="afterInstallInitialize"
|
|
DowngradeErrorMessage="A newer version of [ProductName] is already installed. Setup will now exit." />
|
|
|
|
<!-- Embed cab media to MSI file -->
|
|
<Media Id="1" Cabinet="cab1.cab" EmbedCab="yes" />
|
|
|
|
<!-- Allow install for Current User Or Machine -->
|
|
<Property Id="WixUISupportPerUser" Value="1" />
|
|
<Property Id="WixUISupportPerMachine" Value="1" />
|
|
<!-- Install for PerUser by default -->
|
|
<!-- If set to WixPerMachineFolder will install for PerMachine by default -->
|
|
<Property Id="WixAppFolder" Value="WixLocalAppDataFolder" />
|
|
|
|
<!--
|
|
Support for winget install `——scope machine`:
|
|
Winget doesn't directly pass ALLUSERS=1 to the MSI installer when using
|
|
——scope machine. Instead, it passes a property called INSTALLSCOPEMACHINE=1
|
|
This converts the winget parameter to the standard MSI parameter.
|
|
FIXME: However, this doesn't seem to work...
|
|
-->
|
|
<SetProperty Id="ALLUSERS" Value="1" After="LaunchConditions" Condition="INSTALLSCOPEMACHINE=1" />
|
|
<!-- This ensures the per-user flag is turned off when installing for all users. -->
|
|
<SetProperty Id="MSIINSTALLPERUSER" Value="0" After="LaunchConditions" Condition="INSTALLSCOPEMACHINE=1" />
|
|
|
|
<!-- Workaround Wix Bug: https://github.com/wixtoolset/issues/issues/2165 -->
|
|
<!-- The suggested folder in the dest folder dialog should be C:\Program Files\nu -->
|
|
<CustomAction Id="Overwrite_WixSetDefaultPerMachineFolder" Property="WixPerMachineFolder"
|
|
Value="[ProgramFiles64Folder][ApplicationFolderName]" Execute="immediate" />
|
|
<CustomAction Id="Overwrite_ARPINSTALLLOCATION" Property="ARPINSTALLLOCATION"
|
|
Value="[ProgramFiles64Folder][ApplicationFolderName]" Execute="immediate" />
|
|
<InstallUISequence>
|
|
<Custom Action="Overwrite_WixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />
|
|
</InstallUISequence>
|
|
<InstallExecuteSequence>
|
|
<Custom Action="Overwrite_WixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />
|
|
<Custom Action="Overwrite_ARPINSTALLLOCATION" After="InstallValidate"/>
|
|
</InstallExecuteSequence>
|
|
|
|
<!-- Enable UAC prompt when installing for all users -->
|
|
<!-- <Property Id="MSIUSEREALADMINDETECTION" Value="1" /> -->
|
|
|
|
<Icon Id="ProductIconId" SourceFile="$(var.ProjectDir)/nu.ico"/>
|
|
<Property Id="ARPPRODUCTICON" Value="ProductIconId" />
|
|
<Property Id='ARPHELPLINK' Value='https://www.nushell.sh/book/' />
|
|
<Property Id="ApplicationFolderName" Value="$(var.ApplicationFolderName)" />
|
|
|
|
<!-- INSTALLDIR is the logical target directory whose path will be set by the INSTALLDIR property. -->
|
|
<Directory Id="INSTALLDIR" Name="$(var.ApplicationFolderName)">
|
|
<!-- LOGICAL_BINDIR's path will be set by the LOGICAL_BINDIR property -->
|
|
<Directory Id="LOGICAL_BINDIR" Name="bin" />
|
|
</Directory>
|
|
|
|
<!-- Per Machine Install - these are the definitions of the physical locations -->
|
|
<StandardDirectory Id="ProgramFiles64Folder">
|
|
<Directory Id="APPLICATIONFOLDER" Name="$(var.ApplicationFolderName)">
|
|
<Directory Id="BINDIR" Name="bin">
|
|
<!-- Per-machine PATH component -->
|
|
<Component Id="EnvironmentPathMachine" Guid="*" Condition="ALLUSERS=1 AND NOT MSIINSTALLPERUSER=1">
|
|
<!-- The value MUST BE [LOGICAL_BINDIR] to make sure the env been removed for a custom dir installation -->
|
|
<Environment Id="PATHMachine"
|
|
Name="PATH"
|
|
Value="[LOGICAL_BINDIR]"
|
|
Permanent="no"
|
|
Part="last"
|
|
Action="set"
|
|
System="yes" />
|
|
<RegistryValue Root="HKLM"
|
|
Key="Software\nu"
|
|
Name="installed"
|
|
Type="integer"
|
|
Value="1"
|
|
KeyPath="yes" />
|
|
</Component>
|
|
</Directory>
|
|
</Directory>
|
|
</StandardDirectory>
|
|
|
|
<!-- Install for Current User - these are the definitions of the physical locations -->
|
|
<StandardDirectory Id="LocalAppDataFolder">
|
|
<Directory Id="LocalAppProgramsFolder" Name="Programs">
|
|
<Directory Id="INSTALLDIR_USER" Name="$(var.ApplicationFolderName)">
|
|
<Directory Id="BINDIR_USER" Name="bin">
|
|
<!-- Per-user PATH component -->
|
|
<Component Id="EnvironmentPathUser" Guid="*" Condition="MSIINSTALLPERUSER=1">
|
|
<Environment Id="PATHUser"
|
|
Name="PATH"
|
|
Value="[BINDIR_USER]"
|
|
Permanent="no"
|
|
Part="last"
|
|
Action="set"
|
|
System="no" />
|
|
<RegistryValue Root="HKCU"
|
|
Key="Software\nu"
|
|
Name="installed"
|
|
Type="integer"
|
|
Value="1"
|
|
KeyPath="yes" />
|
|
</Component>
|
|
</Directory>
|
|
</Directory>
|
|
</Directory>
|
|
|
|
<!-- Windows Terminal Profile Directories -->
|
|
<Directory Id="AppDataMicrosoftFolder" Name="Microsoft">
|
|
<Directory Id="AppDataWindowsTerminalFolder" Name="Windows Terminal">
|
|
<Directory Id="WindowsTerminalProfileFolder" Name="Fragments">
|
|
<Directory Id="WindowsTerminalProfileAppFolder" Name="$(var.ApplicationFolderName)">
|
|
<Component Id="WindowsTerminalProfile" Guid="*">
|
|
<File Id="WindowsTerminalProfileFile"
|
|
Name="nu.json"
|
|
KeyPath="yes"
|
|
Source="$(var.ProjectDir)\windows-terminal-profile.json" />
|
|
<RegistryValue Root="HKCU"
|
|
Key="Software\nu"
|
|
Name="WindowsTerminalProfile"
|
|
Value="1"
|
|
Type="integer" />
|
|
<RemoveFolder Id="RemoveWindowsTerminalProfileFolderA" Directory="WindowsTerminalProfileAppFolder" On="uninstall" />
|
|
<RemoveFolder Id="RemoveWindowsTerminalProfileFolderB" Directory="WindowsTerminalProfileFolder" On="uninstall" />
|
|
<RemoveFolder Id="RemoveWindowsTerminalProfileFolderC" Directory="AppDataWindowsTerminalFolder" On="uninstall" />
|
|
<RemoveFolder Id="RemoveWindowsTerminalProfileFolderD" Directory="AppDataMicrosoftFolder" On="uninstall" />
|
|
</Component>
|
|
</Directory>
|
|
</Directory>
|
|
</Directory>
|
|
</Directory>
|
|
</StandardDirectory>
|
|
|
|
<ComponentGroup Id="NushellBinaries" Directory="LOGICAL_BINDIR">
|
|
<Component Id="Nu_Main" Guid="*">
|
|
<File Id="nu.exe" Source="$(var.SourceDir)\nu.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Less" Guid="*">
|
|
<File Id="less.exe" Source="$(var.SourceDir)\less.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_Plugin_Inc" Guid="*">
|
|
<File Id="nu_plugin_inc.exe" Source="$(var.SourceDir)\nu_plugin_inc.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_Plugin_Gstat" Guid="*">
|
|
<File Id="nu_plugin_gstat.exe" Source="$(var.SourceDir)\nu_plugin_gstat.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_Plugin_Query" Guid="*">
|
|
<File Id="nu_plugin_query.exe" Source="$(var.SourceDir)\nu_plugin_query.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_Plugin_Polars" Guid="*">
|
|
<File Id="nu_plugin_polars.exe" Source="$(var.SourceDir)\nu_plugin_polars.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_Plugin_Formats" Guid="*">
|
|
<File Id="nu_plugin_formats.exe" Source="$(var.SourceDir)\nu_plugin_formats.exe" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Less_License" Guid="*">
|
|
<File Id="LICENSE_for_less.txt" Source="$(var.SourceDir)\LICENSE-for-less.txt" KeyPath="yes" />
|
|
</Component>
|
|
</ComponentGroup>
|
|
|
|
<!-- License and Icon in main installation directory -->
|
|
<ComponentGroup Id="NushellResources" Directory="INSTALLDIR">
|
|
<Component Id="Nu_Icon" Guid="*">
|
|
<File Id="nu.ico" Source="$(var.ProjectDir)\nu.ico" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_Readme" Guid="*">
|
|
<File Id="README.txt" Source="$(var.ProjectDir)\README.txt" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="Nu_License" Guid="*">
|
|
<File Id="License.rtf" Source="$(var.ProjectDir)\License.rtf" KeyPath="yes" />
|
|
</Component>
|
|
</ComponentGroup>
|
|
|
|
<!-- Main feature set -->
|
|
<Feature Id="ProductFeature"
|
|
Level="1"
|
|
Title="Nushell"
|
|
Description="Install $(var.ProductName) and plugins.">
|
|
<ComponentGroupRef Id="NushellBinaries" />
|
|
<ComponentGroupRef Id="NushellResources" />
|
|
<ComponentRef Id="EnvironmentPathUser" />
|
|
<ComponentRef Id="EnvironmentPathMachine" />
|
|
</Feature>
|
|
|
|
<!-- Windows Terminal Profile Feature -->
|
|
<Feature Id="WindowsTerminalProfileFeature"
|
|
Level="1"
|
|
Title="Windows Terminal Profile"
|
|
Description="Add $(var.ProductName) profile to Windows Terminal.">
|
|
<ComponentRef Id="WindowsTerminalProfile" />
|
|
</Feature>
|
|
|
|
<!-- Load Advanced UI -->
|
|
<WixVariable Id="WixUILicenseRtf" Value="$(var.ProjectDir)\License.rtf" />
|
|
<ui:WixUI Id="WixUI_Advanced" />
|
|
|
|
<!-- Windows Version Check -->
|
|
<Launch Condition="VersionNT >= 601" Message="This application requires Windows 7 or later." />
|
|
|
|
<!-- Arch checking -->
|
|
<?if $(sys.BUILDARCH) = x64 ?>
|
|
<Launch Condition="VersionNT64" Message="This installation package is only supported on 64-bit Windows." />
|
|
<?endif?>
|
|
|
|
<?if $(sys.BUILDARCH) = arm64 ?>
|
|
<Launch Condition="ProcessorArchitecture = 'ARM64'" Message="This installation package is only supported on ARM64 Windows." />
|
|
<?endif?>
|
|
|
|
<!-- If installing per-user (MSIINSTALLPERUSER=1), this sets INSTALLDIR and BINDIR to point to user-specific paths -->
|
|
<SetProperty Id="INSTALLDIR"
|
|
Action="SetINSTALLDIR_User"
|
|
Value="[LocalAppDataFolder]Programs\$(var.ApplicationFolderName)"
|
|
After="LaunchConditions"
|
|
Condition="MSIINSTALLPERUSER=1"
|
|
Sequence="both" />
|
|
<SetProperty Id="BINDIR"
|
|
Action="SetBINDIR_User"
|
|
Value="[LocalAppDataFolder]Programs\$(var.ApplicationFolderName)\bin"
|
|
After="LaunchConditions"
|
|
Condition="MSIINSTALLPERUSER=1"
|
|
Sequence="both" />
|
|
|
|
<!-- If installing per-machine (ALLUSERS=1 AND NOT MSIINSTALLPERUSER=1), this sets INSTALLDIR and BINDIR to point to machine-wide (Program Files) paths -->
|
|
<SetProperty Id="INSTALLDIR"
|
|
Action="SetINSTALLDIR_Machine"
|
|
Value="[APPLICATIONFOLDER]"
|
|
After="LaunchConditions"
|
|
Condition="ALLUSERS=1 AND NOT MSIINSTALLPERUSER=1"
|
|
Sequence="both" />
|
|
|
|
<!-- Override APPLICATIONFOLDER for 64-bit installations -->
|
|
<?if $(sys.BUILDARCH) = x64 OR $(sys.BUILDARCH) = arm64 ?>
|
|
<SetProperty Id="APPLICATIONFOLDER"
|
|
Value="[ProgramFiles64Folder]$(var.ApplicationFolderName)"
|
|
After="LaunchConditions"
|
|
Condition="ALLUSERS=1 AND NOT MSIINSTALLPERUSER=1"
|
|
Sequence="both" />
|
|
<?endif?>
|
|
|
|
<SetProperty Id="BINDIR"
|
|
Action="SetBINDIR_Machine"
|
|
Value="[BINDIR]"
|
|
After="LaunchConditions"
|
|
Condition="ALLUSERS=1 AND NOT MSIINSTALLPERUSER=1"
|
|
Sequence="both" />
|
|
|
|
<!-- Set the LOGICAL_BINDIR property to the resolved BINDIR path -->
|
|
<!-- This line MUST NOT be removed in order to set a custom folder for PerMachine installation -->
|
|
<SetProperty Id="LOGICAL_BINDIR" Value="[BINDIR]" After="LaunchConditions" Sequence="both" />
|
|
|
|
<!-- Property that defines the command executed by the Windows Terminal Profile custom action -->
|
|
<!-- for Value, see https://learn.microsoft.com/en-ca/windows/win32/msi/formatted -->
|
|
<SetProperty Id="ReplacePathsInWindowsTerminalProfile"
|
|
Sequence="execute"
|
|
After="CostFinalize"
|
|
Value=""[#nu.exe]" -c "let doc = (open `[#WindowsTerminalProfileFile]` | update profiles.commandline `[#nu.exe]` | update profiles.icon `[#nu.ico]`); $doc | save -f `[#WindowsTerminalProfileFile]`""
|
|
Condition="&WindowsTerminalProfileFeature=3" />
|
|
|
|
<!-- Defines the custom action that updates paths in the Windows Terminal profile JSON file -->
|
|
<CustomAction Id="ReplacePathsInWindowsTerminalProfile"
|
|
Return="check"
|
|
Impersonate="yes"
|
|
Execute="deferred"
|
|
DllEntry="WixQuietExec"
|
|
BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
|
|
|
|
<InstallExecuteSequence>
|
|
<Custom Action="ReplacePathsInWindowsTerminalProfile" Before="InstallFinalize"
|
|
Condition="&WindowsTerminalProfileFeature=3" />
|
|
</InstallExecuteSequence>
|
|
</Package>
|
|
</Wix>
|