Skip to content

Commit

Permalink
feat: Windows installer (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
baszalmstra authored Jun 19, 2023
1 parent 7a87762 commit 195f674
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 7 deletions.
50 changes: 45 additions & 5 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ jobs:
- { name: "macOS-x86_64", target: x86_64-apple-darwin, os: macOS-latest }
- { name: "macOS-aarch64", target: aarch64-apple-darwin, os: macOS-latest, skip-tests: true }

- { name: "Windows-x86_64", target: x86_64-pc-windows-msvc, os: windows-2019 }
- { name: "Windows-x86_64", target: x86_64-pc-windows-msvc, os: windows-latest }
include:
- os: windows-latest
rustflags: -C target-feature=+crt-static
env:
BUILD_CMD: cargo # The build and test command to use if not overwritten
RUSTFLAGS: ${{ matrix.rustflags || '' }} -D warnings
steps:
- name: Checkout source code
uses: actions/checkout@v3
Expand All @@ -114,6 +118,15 @@ jobs:
with:
target: ${{ matrix.job.target }}

- name: Setup | Install cargo-wix [Windows]
continue-on-error: true
# aarch64 is only supported in wix 4.0 development builds
if: matrix.os == 'windows-latest' && matrix.target != 'aarch64-pc-windows-msvc'
run: cargo install --version 0.3.4 cargo-wix
env:
# cargo-wix does not require static crt
RUSTFLAGS: ""

- name: Install cross
if: matrix.job.use-cross
uses: taiki-e/install-action@v2
Expand Down Expand Up @@ -183,19 +196,20 @@ jobs:
shell: bash
run: |
# Figure out suffix of binary
EXE_suffix=""
EXE_SUFFIX=""
case ${{ matrix.job.target }} in
*-pc-windows-*) EXE_suffix=".exe" ;;
*-pc-windows-*) EXE_SUFFIX=".exe" ;;
esac;
# Setup paths
BUILD_TARGET_FOLDER="${{ steps.build-options.outputs.BUILD_TARGET_FOLDER }}"
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}"
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_SUFFIX}"
BIN_PATH="target/${{ matrix.job.target }}/${BUILD_TARGET_FOLDER}/${BIN_NAME}"
# Let subsequent steps know where to find the binary
echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT
echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT
echo "EXE_SUFFIX=${EXE_SUFFIX}" >> $GITHUB_OUTPUT
- name: Set testing options
id: test-options
Expand All @@ -215,6 +229,14 @@ jobs:
command: test
args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} ${{ steps.build-options.outputs.CARGO_BUILD_OPTIONS}}

- name: Build Installer
continue-on-error: true
if: matrix.os == 'windows-latest' && matrix.target != 'aarch64-pc-windows-msvc'
run: >
cargo wix -v --no-build --nocapture -I install/windows/main.wxs
--target ${{ matrix.job.target }}
--output target/wix/pixi-${{ matrix.job.target }}.msi
- name: Create tarball
id: package
shell: bash
Expand All @@ -240,22 +262,40 @@ jobs:
*) tar czf "${PKG_NAME}" ./* ;;
esac;
popd >/dev/null
cp "${{ steps.bin.outputs.BIN_PATH }}" "$PKG_STAGING/pixi-${{ matrix.job.target }}${{ steps.bin.outputs.EXE_SUFFIX }}"
# Let subsequent steps know where to find the compressed package
echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT
echo "BIN_PATH=$PKG_STAGING/pixi-${{ matrix.job.target }}${{ steps.bin.outputs.EXE_SUFFIX }}" >> $GITHUB_OUTPUT
- name: "Artifact upload: tarball"
uses: actions/upload-artifact@master
with:
name: ${{ steps.package.outputs.PKG_NAME }}
path: ${{ steps.package.outputs.PKG_PATH }}

- name: "Artifact upload: binary"
uses: actions/upload-artifact@master
with:
name: pixi-${{ matrix.job.target }}${{ steps.bin.outputs.EXE_SUFFIX }}
path: ${{ steps.package.outputs.BIN_PATH }}

- name: "Artifact upload: windows installer"
continue-on-error: true
if: matrix.os == 'windows-latest' && matrix.job.target != 'aarch64-pc-windows-msvc'
uses: actions/upload-artifact@v3
with:
name: pixi-${{ matrix.job.target }}.msi
path: target/wix/pixi-${{ matrix.job.target }}.msi

- name: Publish packages
uses: softprops/action-gh-release@v1
if: steps.is-release.outputs.IS_RELEASE
with:
files: |
${{ steps.package.outputs.PKG_PATH }}
${{ steps.debian-package.outputs.DPKG_PATH }}
${{ steps.package.outputs.BIN_PATH }}
target/wix/pixi-${{ matrix.job.target }}.msi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ If this directory does not already exist, the script will create it.
## macOS and Linux
To install Pixi on macOS and Linux, open a terminal and run the following command:
```bash
curl -fsSL https://raw.githubusercontent.com/prefix-dev/pixi/main/scripts/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/prefix-dev/pixi/main/install/install.sh | bash
```
The script will also update your ~/.bash_profile to include ~/.pixi/bin in your PATH, allowing you to invoke the pixi command from anywhere.
You might need to restart your terminal or source your shell for the changes to take effect.
Expand All @@ -76,7 +76,7 @@ You might need to restart your terminal or source your shell for the changes to
To install Pixi on Windows, open a PowerShell terminal (you may need to run it as an administrator) and run the following command:

```powershell
iwr -useb https://raw.githubusercontent.com/prefix-dev/pixi/main/scripts/install.ps1 | iex
iwr -useb https://raw.githubusercontent.com/prefix-dev/pixi/main/install/install.ps1 | iex
```
The script will inform you once the installation is successful and add the ~/.pixi/bin directory to your PATH, which will allow you to run the pixi command from any location.

Expand Down
File renamed without changes.
File renamed without changes.
251 changes: 251 additions & 0 deletions install/windows/main.wxs
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
<?xml version='1.0' encoding='windows-1252'?>
<!--
Copyright (C) 2017 Christopher R. Field.
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.
-->

<!--
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:
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 binary (exe). The default would
be "target\release\<BINARY_NAME>.exe" where
"<BINARY_NAME>" is replaced with the name of each binary
target defined in the package's manifest (Cargo.toml). If
a different rustc target triple is used than the host,
i.e. cross-compiling, then the default path would be
"target\<CARGO_TARGET>\<CARGO_PROFILE>\<BINARY_NAME>.exe",
where "<CARGO_TARGET>" is replaced with the "CargoTarget"
variable value and "<CARGO_PROFILE>" is replaced with the
value from the `CargoProfile` variable.
CargoTargetDir = The path to the directory for the build artifacts, i.e.
"target".
CargoProfile = Either "debug" or `release` depending on the build
profile. The default is "release".
Version = The version for the installer. The default is the
"Major.Minor.Fix" semantic versioning number 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://schemas.microsoft.com/wix/2006/wi'>

<Product
Id='*'
Name='pixi'
UpgradeCode='D983A0B8-0183-4F99-BA13-A1C49BD8E46F'
Manufacturer='pixi contributors'
Language='1033'
Codepage='1252'
Version='$(var.Version)'>

<Package Id='*'
Keywords='Installer'
Description='A package management and workflow tool'
Manufacturer='pixi contributors'
InstallerVersion='450'
Languages='1033'
Compressed='yes'
InstallScope='perMachine'
SummaryCodepage='1252'
/>

<MajorUpgrade
Schedule='afterInstallInitialize'
DowngradeErrorMessage='A newer version of [ProductName] is already installed. Setup will now exit.'/>

<Media Id='1' Cabinet='media1.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'/>
<Property Id='DiskPrompt' Value='pixi Installation'/>

<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id="LocalAppDataFolder">
<Directory Id="APPLICATIONFOLDER" Name="pixi" >

<!--
Enabling the license sidecar file in the installer is a four step process:
1. Uncomment the `Component` tag and its contents.
2. Change the value for the `Source` attribute in the `File` tag to a path
to the file that should be included as the license sidecar file. The path
can, and probably should be, relative to this file.
3. Change the value for the `Name` attribute in the `File` tag to the
desired name for the file when it is installed alongside the `bin` folder
in the installation directory. This can be omitted if the desired name is
the same as the file name.
4. Uncomment the `ComponentRef` tag with the Id attribute value of "License"
further down in this file.
-->
<Component Id='License' Guid='0ab111aa-4a6e-4322-a256-5d69a69dfb9e'>
<File Id='LicenseFile' Name='LICENSE' DiskId='1' Source='LICENSE' />

<RegistryKey Root="HKCU" Key="Software\Prefix GmbH\pixi">
<RegistryValue Name="License" Value="1" Type="string" KeyPath="yes" />
</RegistryKey>
</Component>

<Directory Id='Bin' Name='bin'>
<Component Id='Path' Guid='AA248D99-6E0E-4590-B029-3636DE5E41CE'>
<RegistryKey Root="HKCU" Key="Software\Prefix GmbH\pixi">
<RegistryValue Name="Env" Value="1" Type="string" KeyPath="yes" />
</RegistryKey>

<Environment
Id='PATH'
Name='PATH'
Value='[Bin]'
Permanent='no'
Part='last'
Action='set'
System='no'/>
<Environment
Id='PIXI_BIN_PATH'
Name='PATH'
Value='%UserProfile%/.pixi/bin'
Permanent='no'
Part='last'
Action='set'
System='no'/>
</Component>
<Component Id='binary0' Guid='f663c04b-5015-4f3d-b765-0541d9d6e7b6'>

<RegistryKey Root="HKCU" Key="Software\Prefix GmbH\pixi">
<RegistryValue Name="Flag" Value="1" Type="string" KeyPath="yes" />
</RegistryKey>

<RemoveFolder Id="RemoveBin" Directory="Bin" On="uninstall" />
<RemoveFolder Id="RemoveINSTALLFOLDER" Directory="APPLICATIONFOLDER" On="uninstall" />

<File
Id='exe0'
Name='pixi.exe'
DiskId='1'
Source='$(var.CargoTargetBinDir)\pixi.exe'/>
</Component>

</Directory>
</Directory>
</Directory>
</Directory>

<Feature
Id='Binaries'
Title='Application'
Description='Installs all binaries and the license.'
Level='1'
ConfigurableDirectory='APPLICATIONFOLDER'
AllowAdvertise='no'
Display='expand'
Absent='disallow'>

<!--
Uncomment the following `ComponentRef` tag to add the license
sidecar file to the installer.
-->
<ComponentRef Id='License'/>

<ComponentRef Id='binary0'/>

<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.'
Level='1'
Absent='allow'>
<ComponentRef Id='Path'/>
</Feature>
</Feature>

<SetProperty Id='ARPINSTALLLOCATION' Value='[APPLICATIONFOLDER]' After='CostFinalize'/>


<!--
Uncomment the following `Icon` and `Property` tags to change the product icon.
The product icon is the graphic that appears in the Add/Remove
Programs control panel for the application.
-->
<!--<Icon Id='ProductICO' SourceFile='wix\Product.ico'/>-->
<!--<Property Id='ARPPRODUCTICON' Value='ProductICO' />-->

<Property Id='ARPHELPLINK' Value='https://github.com/prefix-dev/pixi'/>

<UI>
<UIRef Id='WixUI_FeatureTree'/>

<!--
Enabling the EULA dialog in the installer is a three step process:
1. Comment out or remove the two `Publish` tags that follow the
`WixVariable` tag.
2. Uncomment the `<WixVariable Id='WixUILicenseRtf' Value='Path\to\Eula.rft'>` tag futher down
3. Replace the `Value` attribute of the `WixVariable` tag with
the path to a RTF file that will be used as the EULA and
displayed in the license agreement dialog.
-->
<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>


<!--
Enabling the EULA dialog in the installer requires uncommenting
the following `WixUILicenseRTF` tag and changing the `Value`
attribute.
-->
<WixVariable Id='WixUILicenseRtf' Value='install\windows\resources\license.rtf'/>


<!--
Uncomment the next `WixVariable` tag to customize the installer's
Graphical User Interface (GUI) and add a custom banner image across
the top of each screen. See the WiX Toolset documentation for details
about customization.
The banner BMP dimensions are 493 x 58 pixels.
-->
<WixVariable Id='WixUIBannerBmp' Value='install\windows\resources\Banner.bmp'/>


<!--
Uncomment the next `WixVariable` tag to customize the installer's
Graphical User Interface (GUI) and add a custom image to the first
dialog, or screen. See the WiX Toolset documentation for details about
customization.
The dialog BMP dimensions are 493 x 312 pixels.
-->
<WixVariable Id='WixUIDialogBmp' Value='install\windows\resources\Dialog.bmp'/>

</Product>

</Wix>
Binary file added install/windows/resources/Banner.bmp
Binary file not shown.
Binary file added install/windows/resources/Dialog.bmp
Binary file not shown.
7 changes: 7 additions & 0 deletions install/windows/resources/LICENSE.rtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{\pard \ql \f0 \sa180 \li0 \fi0 BSD 3-Clause License\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Copyright (c) 2023, prefix.dev GmbH\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\par}
{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\par}
{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\par}
{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \u8220"AS IS\u8221" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\par}

0 comments on commit 195f674

Please sign in to comment.