From 9a4ef72af7e4c83c8c01a9aaa672647c993cd439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Misty=20De=20M=C3=A9o?= Date: Thu, 12 Dec 2024 14:44:44 -0800 Subject: [PATCH] fix: always cross-compile to windows via xwin Cross-compiling from Windows to Windows using zigbuild is broken; we're getting `zig cc` errors we can't fix. We should always use xwin instead. If we detect Windows cross-compilation, we should always pick an xwin container image, specifically the same one we recommend our users to use. --- cargo-dist/src/backend/ci/github.rs | 33 +- cargo-dist/src/tasks.rs | 6 +- cargo-dist/tests/integration-tests.rs | 2 +- .../tests/snapshots/axolotlsay_cross2.snap | 658 +++++++++++++++++- 4 files changed, 685 insertions(+), 14 deletions(-) diff --git a/cargo-dist/src/backend/ci/github.rs b/cargo-dist/src/backend/ci/github.rs index a6a9e302f..b1abc50b4 100644 --- a/cargo-dist/src/backend/ci/github.rs +++ b/cargo-dist/src/backend/ci/github.rs @@ -2,16 +2,16 @@ //! //! In the future this may get split up into submodules. -use std::collections::BTreeMap; +use std::{collections::BTreeMap, str::FromStr}; use axoasset::{LocalAsset, SourceFile}; use axoprocess::Cmd; use camino::{Utf8Path, Utf8PathBuf}; use cargo_dist_schema::{ - target_lexicon::{self, OperatingSystem, Triple}, - AptPackageName, ChocolateyPackageName, GhaRunStep, GithubGlobalJobConfig, GithubLocalJobConfig, - GithubMatrix, GithubRunnerConfig, GithubRunnerRef, GithubRunners, HomebrewPackageName, - PackageInstallScript, PackageVersion, PipPackageName, TripleNameRef, + target_lexicon::{self, Architecture, OperatingSystem, Triple}, + AptPackageName, ChocolateyPackageName, ContainerImage, GhaRunStep, GithubGlobalJobConfig, + GithubLocalJobConfig, GithubMatrix, GithubRunnerConfig, GithubRunnerRef, GithubRunners, + HomebrewPackageName, PackageInstallScript, PackageVersion, PipPackageName, TripleNameRef, }; use itertools::Itertools; use serde::{Deserialize, Serialize}; @@ -26,7 +26,7 @@ use crate::{ JinjaGithubRepoPair, JobStyle, ProductionMode, PublishStyle, SystemDependencies, }, errors::DistResult, - platform::github_runners::target_for_github_runner_or_default, + platform::{github_runners::target_for_github_runner_or_default, targets}, CargoBuildWrapper, DistError, DistGraph, SortedMap, SortedSet, }; @@ -661,13 +661,32 @@ fn github_runner_for_target( let result = Some(match target_triple.operating_system { OperatingSystem::Linux => runner_to_config(GithubRunnerRef::from_str("ubuntu-20.04")), OperatingSystem::Darwin => runner_to_config(GithubRunnerRef::from_str("macos-13")), - OperatingSystem::Windows => runner_to_config(GithubRunnerRef::from_str("windows-2019")), + OperatingSystem::Windows => { + // Default to cargo-xwin for Windows cross-compiles + if matches!(target_triple.architecture, Architecture::Aarch64(_)) { + cargo_xwin() + } else { + runner_to_config(GithubRunnerRef::from_str("windows-2019")) + } + } _ => return Ok(None), }); Ok(result) } +fn cargo_xwin() -> GithubRunnerConfig { + GithubRunnerConfig { + runner: GithubRunnerRef::from_str("ubuntu-20.04").to_owned(), + host: targets::TARGET_X64_LINUX_GNU.to_owned(), + container: Some(cargo_dist_schema::ContainerConfig { + image: ContainerImage::from_str("messense/cargo-xwin").unwrap(), + host: targets::TARGET_X64_LINUX_MUSL.to_owned(), + package_manager: None, + }), + } +} + fn brewfile_from<'a>(packages: impl Iterator) -> String { packages .map(|p| { diff --git a/cargo-dist/src/tasks.rs b/cargo-dist/src/tasks.rs index 96de9a802..ffd9154a8 100644 --- a/cargo-dist/src/tasks.rs +++ b/cargo-dist/src/tasks.rs @@ -486,10 +486,6 @@ pub fn build_wrapper_for_cross( }, // compiling for Windows (making PE binaries, .dll files, etc.) OperatingSystem::Windows => match host.operating_system { - OperatingSystem::Windows => { - // this is just cross-arch, hopefully no wrappers are needed? - Ok(Some(CargoBuildWrapper::ZigBuild)) - } OperatingSystem::Linux | OperatingSystem::Darwin => { // cargo-xwin is made for that Ok(Some(CargoBuildWrapper::Xwin)) @@ -498,7 +494,7 @@ pub fn build_wrapper_for_cross( Err(DistError::UnsupportedCrossCompile { host: host.clone(), target: target.clone(), - details: format!("no idea how to cross-compile from {host} to windows"), + details: format!("no idea how to cross-compile from {host} to windows with architecture {}", target.architecture), }) } }, diff --git a/cargo-dist/tests/integration-tests.rs b/cargo-dist/tests/integration-tests.rs index a106a710d..4edb243cf 100644 --- a/cargo-dist/tests/integration-tests.rs +++ b/cargo-dist/tests/integration-tests.rs @@ -1997,7 +1997,7 @@ fn axolotlsay_cross2() -> Result<(), miette::Report> { [workspace.metadata.dist] cargo-dist-version = "{dist_version}" installers = ["shell", "powershell"] -targets = ["aarch64-unknown-linux-gnu"] +targets = ["aarch64-unknown-linux-gnu", "aarch64-pc-windows-msvc"] ci = ["github"] unix-archive = ".tar.gz" windows-archive = ".tar.gz" diff --git a/cargo-dist/tests/snapshots/axolotlsay_cross2.snap b/cargo-dist/tests/snapshots/axolotlsay_cross2.snap index 64e20a13f..e3bf75d11 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_cross2.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_cross2.snap @@ -165,6 +165,18 @@ download_binary_and_run_installer() { # destructure selected archive info into locals case "$_artifact_name" in + "axolotlsay-aarch64-pc-windows-msvc.tar.gz") + _arch="aarch64-pc-windows-msvc" + _zip_ext=".tar.gz" + _bins="axolotlsay.exe" + _bins_js_array='"axolotlsay.exe"' + _libs="" + _libs_js_array="" + _staticlibs="" + _staticlibs_js_array="" + _updater_name="" + _updater_bin="" + ;; "axolotlsay-aarch64-unknown-linux-gnu.tar.gz") _arch="aarch64-unknown-linux-gnu" _zip_ext=".tar.gz" @@ -287,6 +299,9 @@ json_binary_aliases() { local _arch="$1" case "$_arch" in + "aarch64-pc-windows-gnu") + echo '{}' + ;; "aarch64-unknown-linux-gnu") echo '{}' ;; @@ -301,6 +316,13 @@ aliases_for_binary() { local _arch="$2" case "$_arch" in + "aarch64-pc-windows-gnu") + case "$_bin" in + *) + echo "" + ;; + esac + ;; "aarch64-unknown-linux-gnu") case "$_bin" in *) @@ -321,6 +343,20 @@ select_archive_for_arch() { # try each archive, checking runtime conditions like libc versions # accepting the first one that matches, as it's the best match case "$_true_arch" in + "aarch64-pc-windows-gnu") + _archive="axolotlsay-aarch64-pc-windows-msvc.tar.gz" + if [ -n "$_archive" ]; then + echo "$_archive" + return 0 + fi + ;; + "aarch64-pc-windows-msvc") + _archive="axolotlsay-aarch64-pc-windows-msvc.tar.gz" + if [ -n "$_archive" ]; then + echo "$_archive" + return 0 + fi + ;; "aarch64-unknown-linux-gnu") _archive="axolotlsay-aarch64-unknown-linux-gnu.tar.gz" if ! check_glibc "2" "31"; then @@ -1210,6 +1246,550 @@ verify_checksum() { download_binary_and_run_installer "$@" || exit 1 +================ axolotlsay-installer.ps1 ================ +# Licensed under the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +<# +.SYNOPSIS + +The installer for axolotlsay 0.2.2 + +.DESCRIPTION + +This script detects what platform you're on and fetches an appropriate archive from +https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2 +then unpacks the binaries and installs them to + + $env:CARGO_HOME/bin (or $HOME/.cargo/bin) + +It will then add that dir to PATH by editing your Environment.Path registry key + +.PARAMETER ArtifactDownloadUrl +The URL of the directory where artifacts can be fetched from + +.PARAMETER NoModifyPath +Don't add the install directory to PATH + +.PARAMETER Help +Print help + +#> + +param ( + [Parameter(HelpMessage = "The URL of the directory where artifacts can be fetched from")] + [string]$ArtifactDownloadUrl = 'https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2', + [Parameter(HelpMessage = "Don't add the install directory to PATH")] + [switch]$NoModifyPath, + [Parameter(HelpMessage = "Print Help")] + [switch]$Help +) + +$app_name = 'axolotlsay' +$app_version = '0.2.2' +if ($env:AXOLOTLSAY_INSTALLER_GHE_BASE_URL) { + $installer_base_url = $env:AXOLOTLSAY_INSTALLER_GHE_BASE_URL +} elseif ($env:AXOLOTLSAY_INSTALLER_GITHUB_BASE_URL) { + $installer_base_url = $env:AXOLOTLSAY_INSTALLER_GITHUB_BASE_URL +} else { + $installer_base_url = "https://github.com" +} +if ($env:INSTALLER_DOWNLOAD_URL) { + $ArtifactDownloadUrl = $env:INSTALLER_DOWNLOAD_URL +} else { + $ArtifactDownloadUrl = "$installer_base_url/axodotdev/axolotlsay/releases/download/v0.2.2" +} + +$receipt = @" +{"binaries":["CARGO_DIST_BINS"],"binary_aliases":{},"cdylibs":["CARGO_DIST_DYLIBS"],"cstaticlibs":["CARGO_DIST_STATICLIBS"],"install_layout":"unspecified","install_prefix":"AXO_INSTALL_PREFIX","modify_path":true,"provider":{"source":"cargo-dist","version":"CENSORED"},"source":{"app_name":"axolotlsay","name":"axolotlsay","owner":"axodotdev","release_type":"github"},"version":"CENSORED"} +"@ +$receipt_home = "${env:LOCALAPPDATA}\axolotlsay" + +if ($env:AXOLOTLSAY_DISABLE_UPDATE) { + $install_updater = $false +} else { + $install_updater = $true +} + +if ($NoModifyPath) { + Write-Information "-NoModifyPath has been deprecated; please set AXOLOTLSAY_NO_MODIFY_PATH=1 in the environment" +} + +if ($env:AXOLOTLSAY_NO_MODIFY_PATH) { + $NoModifyPath = $true +} + +$unmanaged_install = $env:AXOLOTLSAY_UNMANAGED_INSTALL + +if ($unmanaged_install) { + $NoModifyPath = $true + $install_updater = $false +} + +function Install-Binary($install_args) { + if ($Help) { + Get-Help $PSCommandPath -Detailed + Exit + } + + Initialize-Environment + + # Platform info injected by dist + $platforms = @{ + "aarch64-pc-windows-gnu" = @{ + "artifact_name" = "axolotlsay-aarch64-pc-windows-msvc.tar.gz" + "bins" = @("axolotlsay.exe") + "libs" = @() + "staticlibs" = @() + "zip_ext" = ".tar.gz" + "aliases" = @{ + } + "aliases_json" = '{}' + } + "aarch64-pc-windows-msvc" = @{ + "artifact_name" = "axolotlsay-aarch64-pc-windows-msvc.tar.gz" + "bins" = @("axolotlsay.exe") + "libs" = @() + "staticlibs" = @() + "zip_ext" = ".tar.gz" + "aliases" = @{ + } + "aliases_json" = '{}' + } + } + + $fetched = Download "$ArtifactDownloadUrl" $platforms + # FIXME: add a flag that lets the user not do this step + try { + Invoke-Installer -artifacts $fetched -platforms $platforms "$install_args" + } catch { + throw @" +We encountered an error trying to perform the installation; +please review the error messages below. + +$_ +"@ + } +} + +function Get-TargetTriple($platforms) { + $double = Get-Arch + if ($platforms.Contains("$double-msvc")) { + return "$double-msvc" + } else { + return "$double-gnu" + } +} + +function Get-Arch() { + try { + # NOTE: this might return X64 on ARM64 Windows, which is OK since emulation is available. + # It works correctly starting in PowerShell Core 7.3 and Windows PowerShell in Win 11 22H2. + # Ideally this would just be + # [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture + # but that gets a type from the wrong assembly on Windows PowerShell (i.e. not Core) + $a = [System.Reflection.Assembly]::LoadWithPartialName("System.Runtime.InteropServices.RuntimeInformation") + $t = $a.GetType("System.Runtime.InteropServices.RuntimeInformation") + $p = $t.GetProperty("OSArchitecture") + # Possible OSArchitecture Values: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.architecture + # Rust supported platforms: https://doc.rust-lang.org/stable/rustc/platform-support.html + switch ($p.GetValue($null).ToString()) + { + "X86" { return "i686-pc-windows" } + "X64" { return "x86_64-pc-windows" } + "Arm" { return "thumbv7a-pc-windows" } + "Arm64" { return "aarch64-pc-windows" } + } + } catch { + # The above was added in .NET 4.7.1, so Windows PowerShell in versions of Windows + # prior to Windows 10 v1709 may not have this API. + Write-Verbose "Get-TargetTriple: Exception when trying to determine OS architecture." + Write-Verbose $_ + } + + # This is available in .NET 4.0. We already checked for PS 5, which requires .NET 4.5. + Write-Verbose("Get-TargetTriple: falling back to Is64BitOperatingSystem.") + if ([System.Environment]::Is64BitOperatingSystem) { + return "x86_64-pc-windows" + } else { + return "i686-pc-windows" + } +} + +function Download($download_url, $platforms) { + $arch = Get-TargetTriple $platforms + + if (-not $platforms.ContainsKey($arch)) { + $platforms_json = ConvertTo-Json $platforms + throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json" + } + + # Lookup what we expect this platform to look like + $info = $platforms[$arch] + $zip_ext = $info["zip_ext"] + $bin_names = $info["bins"] + $lib_names = $info["libs"] + $staticlib_names = $info["staticlibs"] + $artifact_name = $info["artifact_name"] + + # Make a new temp dir to unpack things to + $tmp = New-Temp-Dir + $dir_path = "$tmp\$app_name$zip_ext" + + # Download and unpack! + $url = "$download_url/$artifact_name" + Write-Information "Downloading $app_name $app_version ($arch)" + Write-Verbose " from $url" + Write-Verbose " to $dir_path" + $wc = New-Object Net.Webclient + $wc.downloadFile($url, $dir_path) + + Write-Verbose "Unpacking to $tmp" + + # Select the tool to unpack the files with. + # + # As of windows 10(?), powershell comes with tar preinstalled, but in practice + # it only seems to support .tar.gz, and not xz/zstd. Still, we should try to + # forward all tars to it in case the user has a machine that can handle it! + switch -Wildcard ($zip_ext) { + ".zip" { + Expand-Archive -Path $dir_path -DestinationPath "$tmp"; + Break + } + ".tar.*" { + tar xf $dir_path --strip-components 1 -C "$tmp"; + Break + } + Default { + throw "ERROR: unknown archive format $zip_ext" + } + } + + # Let the next step know what to copy + $bin_paths = @() + foreach ($bin_name in $bin_names) { + Write-Verbose " Unpacked $bin_name" + $bin_paths += "$tmp\$bin_name" + } + $lib_paths = @() + foreach ($lib_name in $lib_names) { + Write-Verbose " Unpacked $lib_name" + $lib_paths += "$tmp\$lib_name" + } + $staticlib_paths = @() + foreach ($lib_name in $staticlib_names) { + Write-Verbose " Unpacked $lib_name" + $staticlib_paths += "$tmp\$lib_name" + } + + if (($null -ne $info["updater"]) -and $install_updater) { + $updater_id = $info["updater"]["artifact_name"] + $updater_url = "$download_url/$updater_id" + $out_name = "$tmp\axolotlsay-update.exe" + + $wc.downloadFile($updater_url, $out_name) + $bin_paths += $out_name + } + + return @{ + "bin_paths" = $bin_paths + "lib_paths" = $lib_paths + "staticlib_paths" = $staticlib_paths + } +} + +function Invoke-Installer($artifacts, $platforms) { + # Replaces the placeholder binary entry with the actual list of binaries + $arch = Get-TargetTriple $platforms + + if (-not $platforms.ContainsKey($arch)) { + $platforms_json = ConvertTo-Json $platforms + throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json" + } + + $info = $platforms[$arch] + + # Forces the install to occur at this path, not the default + $force_install_dir = $null + $install_layout = "unspecified" + # Check the newer app-specific variable before falling back + # to the older generic one + if (($env:AXOLOTLSAY_INSTALL_DIR)) { + $force_install_dir = $env:AXOLOTLSAY_INSTALL_DIR + $install_layout = "cargo-home" + } elseif (($env:CARGO_DIST_FORCE_INSTALL_DIR)) { + $force_install_dir = $env:CARGO_DIST_FORCE_INSTALL_DIR + $install_layout = "cargo-home" + } elseif ($unmanaged_install) { + $force_install_dir = $unmanaged_install + $install_layout = "flat" + } + + # Check if the install layout should be changed from `flat` to `cargo-home` + # for backwards compatible updates of applications that switched layouts. + if (($force_install_dir) -and ($install_layout -eq "flat")) { + # If the install directory is targeting the Cargo home directory, then + # we assume this application was previously installed that layout + # Note the installer passes the path with `\\` separators, but here they are + # `\` so we normalize for comparison. We don't use `Resolve-Path` because they + # may not exist. + $cargo_home = if ($env:CARGO_HOME) { $env:CARGO_HOME } else { + Join-Path $(if ($HOME) { $HOME } else { "." }) ".cargo" + } + if ($force_install_dir.Replace('\\', '\') -eq $cargo_home) { + $install_layout = "cargo-home" + } + } + + # The actual path we're going to install to + $dest_dir = $null + $dest_dir_lib = $null + # The install prefix we write to the receipt. + # For organized install methods like CargoHome, which have + # subdirectories, this is the root without `/bin`. For other + # methods, this is the same as `_install_dir`. + $receipt_dest_dir = $null + # Before actually consulting the configured install strategy, see + # if we're overriding it. + if (($force_install_dir)) { + switch ($install_layout) { + "hierarchical" { + $dest_dir = Join-Path $force_install_dir "bin" + $dest_dir_lib = Join-Path $force_install_dir "lib" + } + "cargo-home" { + $dest_dir = Join-Path $force_install_dir "bin" + $dest_dir_lib = $dest_dir + } + "flat" { + $dest_dir = $force_install_dir + $dest_dir_lib = $dest_dir + } + Default { + throw "Error: unrecognized installation layout: $install_layout" + } + } + $receipt_dest_dir = $force_install_dir + } + if (-Not $dest_dir) { + # first try $env:CARGO_HOME, then fallback to $HOME + # (for whatever reason $HOME is not a normal env var and doesn't need the $env: prefix) + $root = if (($base_dir = $env:CARGO_HOME)) { + $base_dir + } elseif (($base_dir = $HOME)) { + Join-Path $base_dir ".cargo" + } else { + throw "ERROR: could not find your HOME dir or CARGO_HOME to install binaries to" + } + + $dest_dir = Join-Path $root "bin" + $dest_dir_lib = $dest_dir + $receipt_dest_dir = $root + $install_layout = "cargo-home" + } + + # Looks like all of the above assignments failed + if (-Not $dest_dir) { + throw "ERROR: could not find a valid path to install to; please check the installation instructions" + } + + # The replace call here ensures proper escaping is inlined into the receipt + $receipt = $receipt.Replace('AXO_INSTALL_PREFIX', $receipt_dest_dir.replace("\", "\\")) + $receipt = $receipt.Replace('"install_layout":"unspecified"', -join('"install_layout":"', $install_layout, '"')) + + $dest_dir = New-Item -Force -ItemType Directory -Path $dest_dir + $dest_dir_lib = New-Item -Force -ItemType Directory -Path $dest_dir_lib + Write-Information "Installing to $dest_dir" + # Just copy the binaries from the temp location to the install dir + foreach ($bin_path in $artifacts["bin_paths"]) { + $installed_file = Split-Path -Path "$bin_path" -Leaf + Copy-Item "$bin_path" -Destination "$dest_dir" -ErrorAction Stop + Remove-Item "$bin_path" -Recurse -Force -ErrorAction Stop + Write-Information " $installed_file" + + if (($dests = $info["aliases"][$installed_file])) { + $source = Join-Path "$dest_dir" "$installed_file" + foreach ($dest_name in $dests) { + $dest = Join-Path $dest_dir $dest_name + $null = New-Item -ItemType HardLink -Target "$source" -Path "$dest" -Force -ErrorAction Stop + } + } + } + foreach ($lib_path in $artifacts["lib_paths"]) { + $installed_file = Split-Path -Path "$lib_path" -Leaf + Copy-Item "$lib_path" -Destination "$dest_dir_lib" -ErrorAction Stop + Remove-Item "$lib_path" -Recurse -Force -ErrorAction Stop + Write-Information " $installed_file" + } + foreach ($lib_path in $artifacts["staticlib_paths"]) { + $installed_file = Split-Path -Path "$lib_path" -Leaf + Copy-Item "$lib_path" -Destination "$dest_dir_lib" -ErrorAction Stop + Remove-Item "$lib_path" -Recurse -Force -ErrorAction Stop + Write-Information " $installed_file" + } + + $formatted_bins = ($info["bins"] | ForEach-Object { '"' + $_ + '"' }) -join "," + $receipt = $receipt.Replace('"CARGO_DIST_BINS"', $formatted_bins) + $formatted_libs = ($info["libs"] | ForEach-Object { '"' + $_ + '"' }) -join "," + $receipt = $receipt.Replace('"CARGO_DIST_DYLIBS"', $formatted_libs) + $formatted_staticlibs = ($info["staticlibs"] | ForEach-Object { '"' + $_ + '"' }) -join "," + $receipt = $receipt.Replace('"CARGO_DIST_STATICLIBS"', $formatted_staticlibs) + # Also replace the aliases with the arch-specific one + $receipt = $receipt.Replace('"binary_aliases":{}', -join('"binary_aliases":', $info['aliases_json'])) + if ($NoModifyPath) { + $receipt = $receipt.Replace('"modify_path":true', '"modify_path":false') + } + + # Write the install receipt + if ($install_updater) { + $null = New-Item -Path $receipt_home -ItemType "directory" -ErrorAction SilentlyContinue + # Trying to get Powershell 5.1 (not 6+, which is fake and lies) to write utf8 is a crime + # because "Out-File -Encoding utf8" actually still means utf8BOM, so we need to pull out + # .NET's APIs which actually do what you tell them (also apparently utf8NoBOM is the + # default in newer .NETs but I'd rather not rely on that at this point). + $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False + [IO.File]::WriteAllLines("$receipt_home/axolotlsay-receipt.json", "$receipt", $Utf8NoBomEncoding) + } + + # Respect the environment, but CLI takes precedence + if ($null -eq $NoModifyPath) { + $NoModifyPath = $env:INSTALLER_NO_MODIFY_PATH + } + + Write-Information "everything's installed!" + if (-not $NoModifyPath) { + Add-Ci-Path $dest_dir + if (Add-Path $dest_dir) { + Write-Information "" + Write-Information "To add $dest_dir to your PATH, either restart your system or run:" + Write-Information "" + Write-Information " set Path=$dest_dir;%Path% (cmd)" + Write-Information " `$env:Path = `"$dest_dir;`$env:Path`" (powershell)" + } + } +} + +# Attempt to do CI-specific rituals to get the install-dir on PATH faster +function Add-Ci-Path($OrigPathToAdd) { + # If GITHUB_PATH is present, then write install_dir to the file it refs. + # After each GitHub Action, the contents will be added to PATH. + # So if you put a curl | sh for this script in its own "run" step, + # the next step will have this dir on PATH. + # + # Note that GITHUB_PATH will not resolve any variables, so we in fact + # want to write the install dir and not an expression that evals to it + if (($gh_path = $env:GITHUB_PATH)) { + Write-Output "$OrigPathToAdd" | Out-File -FilePath "$gh_path" -Encoding utf8 -Append + } +} + +# Try to add the given path to PATH via the registry +# +# Returns true if the registry was modified, otherwise returns false +# (indicating it was already on PATH) +function Add-Path($OrigPathToAdd) { + Write-Verbose "Adding $OrigPathToAdd to your PATH" + $RegistryPath = "HKCU:\Environment" + $PropertyName = "Path" + $PathToAdd = $OrigPathToAdd + + $Item = if (Test-Path $RegistryPath) { + # If the registry key exists, get it + Get-Item -Path $RegistryPath + } else { + # If the registry key doesn't exist, create it + Write-Verbose "Creating $RegistryPath" + New-Item -Path $RegistryPath -Force + } + + $OldPath = "" + try { + # Try to get the old PATH value. If that fails, assume we're making it from scratch. + # Otherwise assume there's already paths in here and use a ; separator + $OldPath = $Item | Get-ItemPropertyValue -Name $PropertyName + $PathToAdd = "$PathToAdd;" + } catch { + # We'll be creating the PATH from scratch + Write-Verbose "No $PropertyName Property exists on $RegistryPath (we'll make one)" + } + + # Check if the path is already there + # + # We don't want to incorrectly match "C:\blah\" to "C:\blah\blah\", so we include the semicolon + # delimiters when searching, ensuring exact matches. To avoid corner cases we add semicolons to + # both sides of the input, allowing us to pretend we're always in the middle of a list. + Write-Verbose "Old $PropertyName Property is $OldPath" + if (";$OldPath;" -like "*;$OrigPathToAdd;*") { + # Already on path, nothing to do + Write-Verbose "install dir already on PATH, all done!" + return $false + } else { + # Actually update PATH + Write-Verbose "Actually mutating $PropertyName Property" + $NewPath = $PathToAdd + $OldPath + # We use -Force here to make the value already existing not be an error + $Item | New-ItemProperty -Name $PropertyName -Value $NewPath -PropertyType String -Force | Out-Null + return $true + } +} + +function Initialize-Environment() { + If (($PSVersionTable.PSVersion.Major) -lt 5) { + throw @" +Error: PowerShell 5 or later is required to install $app_name. +Upgrade PowerShell: + + https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell + +"@ + } + + # show notification to change execution policy: + $allowedExecutionPolicy = @('Unrestricted', 'RemoteSigned', 'ByPass') + If ((Get-ExecutionPolicy).ToString() -notin $allowedExecutionPolicy) { + throw @" +Error: PowerShell requires an execution policy in [$($allowedExecutionPolicy -join ", ")] to run $app_name. For example, to set the execution policy to 'RemoteSigned' please run: + + Set-ExecutionPolicy RemoteSigned -scope CurrentUser + +"@ + } + + # GitHub requires TLS 1.2 + If ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -notcontains 'Tls12') { + throw @" +Error: Installing $app_name requires at least .NET Framework 4.5 +Please download and install it first: + + https://www.microsoft.com/net/download + +"@ + } +} + +function New-Temp-Dir() { + [CmdletBinding(SupportsShouldProcess)] + param() + $parent = [System.IO.Path]::GetTempPath() + [string] $name = [System.Guid]::NewGuid() + New-Item -ItemType Directory -Path (Join-Path $parent $name) +} + +# PSScriptAnalyzer doesn't like how we use our params as globals, this calms it +$Null = $ArtifactDownloadUrl, $NoModifyPath, $Help +# Make Write-Information statements be visible +$InformationPreference = "Continue" + +# The default interactive handler +try { + Install-Binary "$Args" +} catch { + Write-Information $_ + exit 1 +} + ================ sha256.sum ================ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.gz @@ -1222,7 +1802,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g "announcement_is_prerelease": false, "announcement_title": "Version 0.2.2", "announcement_changelog": "```text\n +----------------------------------+\n | now with arm64 linux binaries!!! |\n +----------------------------------+\n /\n≽(◕ ᴗ ◕)≼\n```", - "announcement_github_body": "## Release Notes\n\n```text\n +----------------------------------+\n | now with arm64 linux binaries!!! |\n +----------------------------------+\n /\n≽(◕ ᴗ ◕)≼\n```\n\n## Install axolotlsay 0.2.2\n\n### Install prebuilt binaries via shell script\n\n```sh\ncurl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-installer.sh | sh\n```\n\n## Download axolotlsay 0.2.2\n\n| File | Platform | Checksum |\n|--------|----------|----------|\n| [axolotlsay-aarch64-unknown-linux-gnu.tar.gz](https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-aarch64-unknown-linux-gnu.tar.gz) | ARM64 Linux | [checksum](https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-aarch64-unknown-linux-gnu.tar.gz.sha256) |\n\n", + "announcement_github_body": "## Release Notes\n\n```text\n +----------------------------------+\n | now with arm64 linux binaries!!! |\n +----------------------------------+\n /\n≽(◕ ᴗ ◕)≼\n```\n\n## Install axolotlsay 0.2.2\n\n### Install prebuilt binaries via shell script\n\n```sh\ncurl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-installer.sh | sh\n```\n\n### Install prebuilt binaries via powershell script\n\n```sh\npowershell -ExecutionPolicy ByPass -c \"irm https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-installer.ps1 | iex\"\n```\n\n## Download axolotlsay 0.2.2\n\n| File | Platform | Checksum |\n|--------|----------|----------|\n| [axolotlsay-aarch64-pc-windows-msvc.tar.gz](https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-aarch64-pc-windows-msvc.tar.gz) | ARM64 Windows | [checksum](https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-aarch64-pc-windows-msvc.tar.gz.sha256) |\n| [axolotlsay-aarch64-unknown-linux-gnu.tar.gz](https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-aarch64-unknown-linux-gnu.tar.gz) | ARM64 Linux | [checksum](https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-aarch64-unknown-linux-gnu.tar.gz.sha256) |\n\n", "releases": [ { "app_name": "axolotlsay", @@ -1241,7 +1821,10 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g "source.tar.gz", "source.tar.gz.sha256", "axolotlsay-installer.sh", + "axolotlsay-installer.ps1", "sha256.sum", + "axolotlsay-aarch64-pc-windows-msvc.tar.gz", + "axolotlsay-aarch64-pc-windows-msvc.tar.gz.sha256", "axolotlsay-aarch64-unknown-linux-gnu.tar.gz", "axolotlsay-aarch64-unknown-linux-gnu.tar.gz.sha256" ], @@ -1256,6 +1839,49 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g } ], "artifacts": { + "axolotlsay-aarch64-pc-windows-msvc.tar.gz": { + "name": "axolotlsay-aarch64-pc-windows-msvc.tar.gz", + "kind": "executable-zip", + "target_triples": [ + "aarch64-pc-windows-msvc" + ], + "assets": [ + { + "name": "CHANGELOG.md", + "path": "CHANGELOG.md", + "kind": "changelog" + }, + { + "name": "LICENSE-APACHE", + "path": "LICENSE-APACHE", + "kind": "license" + }, + { + "name": "LICENSE-MIT", + "path": "LICENSE-MIT", + "kind": "license" + }, + { + "name": "README.md", + "path": "README.md", + "kind": "readme" + }, + { + "id": "axolotlsay-aarch64-pc-windows-msvc-exe-axolotlsay", + "name": "axolotlsay", + "path": "axolotlsay.exe", + "kind": "executable" + } + ], + "checksum": "axolotlsay-aarch64-pc-windows-msvc.tar.gz.sha256" + }, + "axolotlsay-aarch64-pc-windows-msvc.tar.gz.sha256": { + "name": "axolotlsay-aarch64-pc-windows-msvc.tar.gz.sha256", + "kind": "checksum", + "target_triples": [ + "aarch64-pc-windows-msvc" + ] + }, "axolotlsay-aarch64-unknown-linux-gnu.tar.gz": { "name": "axolotlsay-aarch64-unknown-linux-gnu.tar.gz", "kind": "executable-zip", @@ -1299,10 +1925,21 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g "aarch64-unknown-linux-gnu" ] }, + "axolotlsay-installer.ps1": { + "name": "axolotlsay-installer.ps1", + "kind": "installer", + "target_triples": [ + "aarch64-pc-windows-gnu", + "aarch64-pc-windows-msvc" + ], + "install_hint": "powershell -ExecutionPolicy ByPass -c \"irm https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-installer.ps1 | iex\"", + "description": "Install prebuilt binaries via powershell script" + }, "axolotlsay-installer.sh": { "name": "axolotlsay-installer.sh", "kind": "installer", "target_triples": [ + "aarch64-pc-windows-gnu", "aarch64-unknown-linux-gnu" ], "install_hint": "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/axolotlsay/releases/download/v0.2.2/axolotlsay-installer.sh | sh", @@ -1335,6 +1972,25 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g "github": { "artifacts_matrix": { "include": [ + { + "runner": "ubuntu-20.04", + "host": "x86_64-unknown-linux-gnu", + "container": { + "image": "messense/cargo-xwin", + "host": "x86_64-unknown-linux-musl", + "package_manager": null + }, + "install_dist": { + "shell": "sh", + "run": "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/vSOME_VERSION/cargo-dist-installer.sh | sh" + }, + "dist_args": "--artifacts=local --target=aarch64-pc-windows-msvc", + "targets": [ + "aarch64-pc-windows-msvc" + ], + "packages_install": "if ! command -v cargo-xwin > /dev/null 2>&1; then\n if ! command -v pip3 > /dev/null 2>&1; then\n dnf install --assumeyes python3-pip\n pip3 install --upgrade pip\n fi\n pip3 install cargo-xwin\nfi", + "cache_provider": "github" + }, { "runner": "ubuntu-20.04", "host": "x86_64-unknown-linux-gnu",