From 8610845961942d5e3c38de26a41c22b07824cbd6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 18:29:54 +0200 Subject: [PATCH 01/52] Enhance GitHub Action to support multiple OS and PowerShell versions; remove unused scripts and test placeholders. --- .github/workflows/Action-Test.yml | 9 ++-- action.yml | 83 +++++++++++++++++-------------- scripts/main.ps1 | 24 --------- tests/README.md | 3 -- 4 files changed, 53 insertions(+), 66 deletions(-) delete mode 100644 scripts/main.ps1 delete mode 100644 tests/README.md diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 405a723..6a89f61 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -18,8 +18,12 @@ permissions: jobs: ActionTestBasic: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + version: ['7.4.0', '7.5.0'] # Specify the versions to test name: Action-Test - [Basic] - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} steps: # Need to check out as part of the test, as its a local action - name: Checkout repo @@ -28,5 +32,4 @@ jobs: - name: Action-Test uses: ./ with: - working-directory: ./tests - subject: PSModule + Version: ${{ matrix.version }} diff --git a/action.yml b/action.yml index 1fca22c..440116d 100644 --- a/action.yml +++ b/action.yml @@ -1,48 +1,59 @@ -name: {{ NAME }} -description: {{ DESCRIPTION }} +name: Install-PowerShell +description: Install PowerShell author: PSModule branding: icon: upload-cloud color: white inputs: - subject: - description: The subject to greet - required: false - default: World - Debug: - description: Enable debug output. - required: false - default: 'false' - Verbose: - description: Enable verbose output. - required: false - default: 'false' Version: - description: Specifies the version of the GitHub module to be installed. The value must be an exact version. - required: false - Prerelease: - description: Allow prerelease versions if available. + description: The version of PowerShell to install, i.e. 7.4.0 or 7.5.0. If not provided it, latest version is installed. required: false - default: 'false' - WorkingDirectory: - description: The working directory where the script will run from. - required: false - default: ${{ github.workspace }} + default: '' runs: using: composite steps: - - name: {{ NAME }} - uses: PSModule/GitHub-Script@v1 - env: - {{ ORG }}_{{ NAME }}_INPUT_subject: ${{ inputs.subject }} - with: - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Script: | - # {{ NAME }} - ${{ github.action_path }}/scripts/main.ps1 + - name: Install PowerShell on Windows + if: runner.os == 'Windows' + shell: powershell + run: | + $version = '${{ inputs.version }}' + winget uninstall --id Microsoft.PowerShell --accept-source-agreements --accept-package-agreements + if ([string]::IsNullOrWhiteSpace($version)) { + winget install --id Microsoft.PowerShell --source winget --accept-package-agreements --accept-source-agreements + } + else { + winget install --id Microsoft.PowerShell --version $version --source winget --accept-package-agreements --accept-source-agreements + } + + - name: Install PowerShell on Ubuntu + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get remove powershell -y + version='${{ inputs.version }}' + if [ -z "$version" ]; then + version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) + else + version="v$version" + fi + wget https://github.com/PowerShell/PowerShell/releases/download/$version/powershell_${version#v}-1.deb_amd64.deb + sudo dpkg -i powershell_${version#v}-1.deb_amd64.deb + sudo apt-get install -f + + - name: Install PowerShell on macOS + if: runner.os == 'macOS' + shell: bash + run: | + sudo rm -rf /usr/local/microsoft/powershell + version='${{ inputs.version }}' + if [ -z "$version" ]; then + version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) + else + version="v$version" + fi + pkg="powershell-${version#v}-osx.pkg" + url="https://github.com/PowerShell/PowerShell/releases/download/$version/$pkg" + curl -LO $url + sudo installer -pkg $pkg -target / diff --git a/scripts/main.ps1 b/scripts/main.ps1 deleted file mode 100644 index cfdee7c..0000000 --- a/scripts/main.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -#Requires -Modules GitHub - -[CmdletBinding()] -param( - [Parameter()] - [string] $Subject = $env:__INPUT_subject -) - -begin { - $scriptName = $MyInvocation.MyCommand.Name - Write-Debug "[$scriptName] - Start" -} - -process { - try { - Write-Output "Hello, $Subject!" - } catch { - throw $_ - } -} - -end { - Write-Debug "[$scriptName] - End" -} diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 43816d3..0000000 --- a/tests/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Placeholder for tests - -Location for tests of the action. From a26e566a2211642f2654fba4e2876eeadbc326be Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 18:34:00 +0200 Subject: [PATCH 02/52] Fix workflow strategy to ensure fail-fast behavior is explicitly set --- .github/workflows/Action-Test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 6a89f61..45a7c18 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -19,6 +19,7 @@ permissions: jobs: ActionTestBasic: strategy: + fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] version: ['7.4.0', '7.5.0'] # Specify the versions to test From c5bbec5dc89c75d33a896d127a9be54f425dd482 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 18:39:44 +0200 Subject: [PATCH 03/52] Add version testing step to Action-Test workflow --- .github/workflows/Action-Test.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 45a7c18..098d9fd 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -34,3 +34,11 @@ jobs: uses: ./ with: Version: ${{ matrix.version }} + + - name: Test version + shell: pwsh + run: | + $PSVersionTable | Format-Table -AutoSize + if ($PSVersionTable.PSVersion -ne '${{ matrix.version }}') { + throw "Failed to install the expected version" + } From 03ceafa877b320f7f53974cb354b6fc71ce0a548 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 18:44:28 +0200 Subject: [PATCH 04/52] Refactor PowerShell installation process to improve version handling and uninstall existing installations --- action.yml | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index 440116d..84b7f43 100644 --- a/action.yml +++ b/action.yml @@ -7,8 +7,7 @@ branding: inputs: Version: - description: The version of PowerShell to install, i.e. 7.4.0 or 7.5.0. If not provided it, latest version is installed. - required: false + description: The version of PowerShell to install, e.g., 7.4.0 or 7.5.0. If not provided, the latest version is installed. default: '' runs: @@ -19,12 +18,46 @@ runs: shell: powershell run: | $version = '${{ inputs.version }}' - winget uninstall --id Microsoft.PowerShell --accept-source-agreements --accept-package-agreements + + # Try to remove existing PowerShell installation + try { + # Find existing PowerShell installations to remove + Get-Package -Name "PowerShell*" -ErrorAction SilentlyContinue | ForEach-Object { + Write-Host "Uninstalling $($_.Name) version $($_.Version)" + Uninstall-Package -Name $_.Name -Force -ErrorAction SilentlyContinue + } + } catch { + Write-Host "Error removing existing PowerShell: $_" + } + + # Get the version to install if ([string]::IsNullOrWhiteSpace($version)) { - winget install --id Microsoft.PowerShell --source winget --accept-package-agreements --accept-source-agreements + # Get latest version from GitHub API + $releaseInfo = Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' + $version = $releaseInfo.tag_name.Trim('v') + Write-Host "Latest PowerShell version: $version" + } else { + Write-Host "Installing specified PowerShell version: $version" } - else { - winget install --id Microsoft.PowerShell --version $version --source winget --accept-package-agreements --accept-source-agreements + + # Download and install PowerShell + $msiName = "PowerShell-$version-win-x64.msi" + $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" + + Write-Host "Downloading from $downloadUrl" + Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName + + Write-Host "Installing PowerShell $version" + Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait + + # Verify installation + $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" + if (Test-Path $pwshPath) { + Write-Host "PowerShell installed successfully:" + & $pwshPath -Command '$PSVersionTable' + } else { + Write-Error "PowerShell installation failed. Could not find $pwshPath" + exit 1 } - name: Install PowerShell on Ubuntu From 2362a3a4b25fa1edacdb1a9611104c43e74d0348 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 18:49:24 +0200 Subject: [PATCH 05/52] Enhance macOS installation process for PowerShell: add version retrieval, architecture detection, and improved error handling for package downloads. --- action.yml | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index 84b7f43..d1cb230 100644 --- a/action.yml +++ b/action.yml @@ -79,14 +79,75 @@ runs: if: runner.os == 'macOS' shell: bash run: | + # Clean up existing PowerShell installation sudo rm -rf /usr/local/microsoft/powershell + + # Get version information version='${{ inputs.version }}' if [ -z "$version" ]; then + # Get latest version if not specified version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) + echo "Latest PowerShell version: $version" else version="v$version" + echo "Installing specified PowerShell version: $version" + fi + + # The version without 'v' prefix + clean_version=${version#v} + + # Try the different naming patterns for the macOS package + pkg_patterns=( + "powershell-$clean_version-osx-x64.pkg" + "powershell-$clean_version-osx-arm64.pkg" + "powershell-$clean_version-osx.pkg" + ) + + # Determine if running on Apple Silicon or Intel + if [ "$(uname -m)" = "arm64" ]; then + echo "Detected Apple Silicon (ARM64)" + arch="arm64" + else + echo "Detected Intel CPU (x64)" + arch="x64" + fi + + # Try to download the appropriate package based on architecture + download_success=false + + for pkg_name in "${pkg_patterns[@]}"; do + echo "Trying to download $pkg_name..." + url="https://github.com/PowerShell/PowerShell/releases/download/$version/$pkg_name" + + # Try to download the file + if curl -LO $url --fail; then + echo "Successfully downloaded $pkg_name" + download_success=true + break + else + echo "Failed to download $pkg_name" + fi + done + + if [ "$download_success" = false ]; then + echo "ERROR: Could not download PowerShell package for macOS. Please check version and available packages." + exit 1 + fi + + # Verify the file exists before installation + if [ -f "$pkg_name" ]; then + echo "Installing PowerShell package: $pkg_name" + sudo installer -pkg "$pkg_name" -target / + + # Verify the installation + if [ -f "/usr/local/bin/pwsh" ]; then + echo "PowerShell installed successfully:" + /usr/local/bin/pwsh -Command '$PSVersionTable' + else + echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh" + exit 1 + fi + else + echo "ERROR: Downloaded package file not found: $pkg_name" + exit 1 fi - pkg="powershell-${version#v}-osx.pkg" - url="https://github.com/PowerShell/PowerShell/releases/download/$version/$pkg" - curl -LO $url - sudo installer -pkg $pkg -target / From e108e4d38c75541ae52b2944728d67c2359a6b67 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 18:59:47 +0200 Subject: [PATCH 06/52] Refactor PowerShell installation process: improve version checking, uninstall existing installations, and enhance error handling for macOS and Ubuntu. --- action.yml | 224 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 147 insertions(+), 77 deletions(-) diff --git a/action.yml b/action.yml index d1cb230..68e6090 100644 --- a/action.yml +++ b/action.yml @@ -19,17 +19,6 @@ runs: run: | $version = '${{ inputs.version }}' - # Try to remove existing PowerShell installation - try { - # Find existing PowerShell installations to remove - Get-Package -Name "PowerShell*" -ErrorAction SilentlyContinue | ForEach-Object { - Write-Host "Uninstalling $($_.Name) version $($_.Version)" - Uninstall-Package -Name $_.Name -Force -ErrorAction SilentlyContinue - } - } catch { - Write-Host "Error removing existing PowerShell: $_" - } - # Get the version to install if ([string]::IsNullOrWhiteSpace($version)) { # Get latest version from GitHub API @@ -40,48 +29,108 @@ runs: Write-Host "Installing specified PowerShell version: $version" } - # Download and install PowerShell - $msiName = "PowerShell-$version-win-x64.msi" - $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" + # Check if PowerShell is already installed and compare versions + $needToInstall = $true + try { + $currentInstall = Get-Package -Name "PowerShell*" -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($currentInstall) { + $currentVersion = $currentInstall.Version + Write-Host "Current PowerShell version: $currentVersion" + + # Compare versions + if ([System.Version]$currentVersion -ge [System.Version]$version) { + Write-Host "Current version is greater than or equal to target version. Skipping installation." + $needToInstall = $false + } else { + Write-Host "Current version is lower than target version. Will upgrade." + + # Uninstall current version + Write-Host "Uninstalling $($currentInstall.Name) version $($currentInstall.Version)" + Uninstall-Package -Name $currentInstall.Name -Force -ErrorAction SilentlyContinue + } + } else { + Write-Host "PowerShell Core not found. Will install version $version" + } + } catch { + Write-Host "Error checking current PowerShell version: $_" + } - Write-Host "Downloading from $downloadUrl" - Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName + if ($needToInstall) { + # Download and install PowerShell + $msiName = "PowerShell-$version-win-x64.msi" + $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" - Write-Host "Installing PowerShell $version" - Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait + Write-Host "Downloading from $downloadUrl" + Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName - # Verify installation - $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" - if (Test-Path $pwshPath) { - Write-Host "PowerShell installed successfully:" - & $pwshPath -Command '$PSVersionTable' - } else { - Write-Error "PowerShell installation failed. Could not find $pwshPath" - exit 1 + Write-Host "Installing PowerShell $version" + Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait + + # Verify installation + $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" + if (Test-Path $pwshPath) { + Write-Host "PowerShell installed successfully:" + & $pwshPath -Command '$PSVersionTable' + } else { + Write-Error "PowerShell installation failed. Could not find $pwshPath" + exit 1 + } } - name: Install PowerShell on Ubuntu if: runner.os == 'Linux' shell: bash run: | - sudo apt-get remove powershell -y version='${{ inputs.version }}' if [ -z "$version" ]; then + # Get latest version if not specified version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) + echo "Latest PowerShell version: $version" else version="v$version" + echo "Installing specified PowerShell version: $version" + fi + + # Strip the 'v' prefix for version comparison + clean_version=${version#v} + + # Check if PowerShell is already installed and get current version + need_to_install=true + if command -v pwsh &> /dev/null; then + current_version=$(pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') + echo "Current PowerShell version: $current_version" + + # Compare versions + if [ "$(printf '%s\n' "$clean_version" "$current_version" | sort -V | head -n1)" != "$clean_version" ]; then + echo "Current version $current_version is greater than or equal to target version $clean_version. Skipping installation." + need_to_install=false + else + echo "Current version $current_version is lower than target version $clean_version. Will upgrade." + sudo apt-get remove powershell -y + fi + else + echo "PowerShell is not installed. Will install version $clean_version" + fi + + if [ "$need_to_install" = true ]; then + wget https://github.com/PowerShell/PowerShell/releases/download/$version/powershell_${clean_version}-1.deb_amd64.deb + sudo dpkg -i powershell_${clean_version}-1.deb_amd64.deb + sudo apt-get install -f + + # Verify installation + if command -v pwsh &> /dev/null; then + echo "PowerShell installed successfully:" + pwsh -c '$PSVersionTable' + else + echo "ERROR: PowerShell installation failed." + exit 1 + fi fi - wget https://github.com/PowerShell/PowerShell/releases/download/$version/powershell_${version#v}-1.deb_amd64.deb - sudo dpkg -i powershell_${version#v}-1.deb_amd64.deb - sudo apt-get install -f - name: Install PowerShell on macOS if: runner.os == 'macOS' shell: bash run: | - # Clean up existing PowerShell installation - sudo rm -rf /usr/local/microsoft/powershell - # Get version information version='${{ inputs.version }}' if [ -z "$version" ]; then @@ -96,58 +145,79 @@ runs: # The version without 'v' prefix clean_version=${version#v} - # Try the different naming patterns for the macOS package - pkg_patterns=( - "powershell-$clean_version-osx-x64.pkg" - "powershell-$clean_version-osx-arm64.pkg" - "powershell-$clean_version-osx.pkg" - ) - - # Determine if running on Apple Silicon or Intel - if [ "$(uname -m)" = "arm64" ]; then - echo "Detected Apple Silicon (ARM64)" - arch="arm64" + # Check if PowerShell is already installed and get current version + need_to_install=true + if [ -f "/usr/local/bin/pwsh" ]; then + current_version=$(/usr/local/bin/pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') + echo "Current PowerShell version: $current_version" + + # Compare versions + if [ "$(printf '%s\n' "$clean_version" "$current_version" | sort -V | head -n1)" != "$clean_version" ]; then + echo "Current version $current_version is greater than or equal to target version $clean_version. Skipping installation." + need_to_install=false + else + echo "Current version $current_version is lower than target version $clean_version. Will upgrade." + # Clean up existing PowerShell installation + sudo rm -rf /usr/local/microsoft/powershell + fi else - echo "Detected Intel CPU (x64)" - arch="x64" + echo "PowerShell is not installed. Will install version $clean_version" fi - # Try to download the appropriate package based on architecture - download_success=false - - for pkg_name in "${pkg_patterns[@]}"; do - echo "Trying to download $pkg_name..." - url="https://github.com/PowerShell/PowerShell/releases/download/$version/$pkg_name" - - # Try to download the file - if curl -LO $url --fail; then - echo "Successfully downloaded $pkg_name" - download_success=true - break + if [ "$need_to_install" = true ]; then + # Try the different naming patterns for the macOS package + pkg_patterns=( + "powershell-$clean_version-osx-x64.pkg" + "powershell-$clean_version-osx-arm64.pkg" + "powershell-$clean_version-osx.pkg" + ) + + # Determine if running on Apple Silicon or Intel + if [ "$(uname -m)" = "arm64" ]; then + echo "Detected Apple Silicon (ARM64)" + arch="arm64" else - echo "Failed to download $pkg_name" + echo "Detected Intel CPU (x64)" + arch="x64" fi - done - - if [ "$download_success" = false ]; then - echo "ERROR: Could not download PowerShell package for macOS. Please check version and available packages." - exit 1 - fi - # Verify the file exists before installation - if [ -f "$pkg_name" ]; then - echo "Installing PowerShell package: $pkg_name" - sudo installer -pkg "$pkg_name" -target / + # Try to download the appropriate package based on architecture + download_success=false + + for pkg_name in "${pkg_patterns[@]}"; do + echo "Trying to download $pkg_name..." + url="https://github.com/PowerShell/PowerShell/releases/download/$version/$pkg_name" + + # Try to download the file + if curl -LO $url --fail; then + echo "Successfully downloaded $pkg_name" + download_success=true + break + else + echo "Failed to download $pkg_name" + fi + done + + if [ "$download_success" = false ]; then + echo "ERROR: Could not download PowerShell package for macOS. Please check version and available packages." + exit 1 + fi - # Verify the installation - if [ -f "/usr/local/bin/pwsh" ]; then - echo "PowerShell installed successfully:" - /usr/local/bin/pwsh -Command '$PSVersionTable' + # Verify the file exists before installation + if [ -f "$pkg_name" ]; then + echo "Installing PowerShell package: $pkg_name" + sudo installer -pkg "$pkg_name" -target / + + # Verify the installation + if [ -f "/usr/local/bin/pwsh" ]; then + echo "PowerShell installed successfully:" + /usr/local/bin/pwsh -Command '$PSVersionTable' + else + echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh" + exit 1 + fi else - echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh" + echo "ERROR: Downloaded package file not found: $pkg_name" exit 1 fi - else - echo "ERROR: Downloaded package file not found: $pkg_name" - exit 1 fi From ad96cf2a01929fefc028198909349b79c991becb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:04:19 +0200 Subject: [PATCH 07/52] Enhance version comparison logic in PowerShell installation: implement detailed component-wise comparison for accurate version checks on Linux and macOS. --- action.yml | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index 68e6090..0dbd2d9 100644 --- a/action.yml +++ b/action.yml @@ -100,8 +100,19 @@ runs: current_version=$(pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') echo "Current PowerShell version: $current_version" - # Compare versions - if [ "$(printf '%s\n' "$clean_version" "$current_version" | sort -V | head -n1)" != "$clean_version" ]; then + # Properly compare versions with version components + current_major=$(echo "$current_version" | cut -d'.' -f1) + current_minor=$(echo "$current_version" | cut -d'.' -f2) + current_patch=$(echo "$current_version" | cut -d'.' -f3) + + target_major=$(echo "$clean_version" | cut -d'.' -f1) + target_minor=$(echo "$clean_version" | cut -d'.' -f2) + target_patch=$(echo "$clean_version" | cut -d'.' -f3) + + # Check if the current version is greater than or equal to target + if [ "$current_major" -gt "$target_major" ] || + ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -gt "$target_minor" ]) || + ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -eq "$target_minor" ] && [ "$current_patch" -ge "$target_patch" ]); then echo "Current version $current_version is greater than or equal to target version $clean_version. Skipping installation." need_to_install=false else @@ -151,8 +162,19 @@ runs: current_version=$(/usr/local/bin/pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') echo "Current PowerShell version: $current_version" - # Compare versions - if [ "$(printf '%s\n' "$clean_version" "$current_version" | sort -V | head -n1)" != "$clean_version" ]; then + # Properly compare versions with version components + current_major=$(echo "$current_version" | cut -d'.' -f1) + current_minor=$(echo "$current_version" | cut -d'.' -f2) + current_patch=$(echo "$current_version" | cut -d'.' -f3) + + target_major=$(echo "$clean_version" | cut -d'.' -f1) + target_minor=$(echo "$clean_version" | cut -d'.' -f2) + target_patch=$(echo "$clean_version" | cut -d'.' -f3) + + # Check if the current version is greater than or equal to target + if [ "$current_major" -gt "$target_major" ] || + ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -gt "$target_minor" ]) || + ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -eq "$target_minor" ] && [ "$current_patch" -ge "$target_patch" ]); then echo "Current version $current_version is greater than or equal to target version $clean_version. Skipping installation." need_to_install=false else From df3c67e54aede2b83b7aff51e93817b93e1f1c33 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:07:49 +0200 Subject: [PATCH 08/52] Enhance version comparison logic in PowerShell installation: parse versions into System.Version objects for accurate comparison and improve error handling during version checks. --- action.yml | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/action.yml b/action.yml index 0dbd2d9..f0300af 100644 --- a/action.yml +++ b/action.yml @@ -37,16 +37,24 @@ runs: $currentVersion = $currentInstall.Version Write-Host "Current PowerShell version: $currentVersion" - # Compare versions - if ([System.Version]$currentVersion -ge [System.Version]$version) { - Write-Host "Current version is greater than or equal to target version. Skipping installation." - $needToInstall = $false - } else { - Write-Host "Current version is lower than target version. Will upgrade." - - # Uninstall current version - Write-Host "Uninstalling $($currentInstall.Name) version $($currentInstall.Version)" - Uninstall-Package -Name $currentInstall.Name -Force -ErrorAction SilentlyContinue + # Parse versions into System.Version objects for proper comparison + try { + $currentVersionObj = [System.Version]$currentVersion + $targetVersionObj = [System.Version]$version + + # Compare versions + if ($currentVersionObj -ge $targetVersionObj) { + Write-Host "Current version $currentVersion is greater than or equal to target version $version. Skipping installation." + $needToInstall = $false + } else { + Write-Host "Current version $currentVersion is lower than target version $version. Will upgrade." + + # Uninstall current version + Write-Host "Uninstalling $($currentInstall.Name) version $($currentInstall.Version)" + Uninstall-Package -Name $currentInstall.Name -Force -ErrorAction SilentlyContinue + } + } catch { + Write-Host "Error comparing versions: $_. Will proceed with installation." } } else { Write-Host "PowerShell Core not found. Will install version $version" From 0fcd8c81bf23a95f22997f93e80c35c06cb50732 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:11:46 +0200 Subject: [PATCH 09/52] Fix version handling in PowerShell installation: trim 'v' prefix from specified version input for accurate installation. --- action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/action.yml b/action.yml index f0300af..2a3bca8 100644 --- a/action.yml +++ b/action.yml @@ -26,6 +26,8 @@ runs: $version = $releaseInfo.tag_name.Trim('v') Write-Host "Latest PowerShell version: $version" } else { + # Remove the 'v' prefix if it exists + $version = $version.TrimStart('v') Write-Host "Installing specified PowerShell version: $version" } From 4afaeb095a77e761583c4ebf559ee8bbba7e4706 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:18:11 +0200 Subject: [PATCH 10/52] Fix version input handling and enhance version comparison logic in PowerShell installation for improved accuracy and error handling --- action.yml | 197 ++++++++++++++++++++++++++--------------------------- 1 file changed, 98 insertions(+), 99 deletions(-) diff --git a/action.yml b/action.yml index 2a3bca8..ea9a910 100644 --- a/action.yml +++ b/action.yml @@ -17,7 +17,7 @@ runs: if: runner.os == 'Windows' shell: powershell run: | - $version = '${{ inputs.version }}' + $version = '${{ inputs.Version }}' # Get the version to install if ([string]::IsNullOrWhiteSpace($version)) { @@ -45,7 +45,8 @@ runs: $targetVersionObj = [System.Version]$version # Compare versions - if ($currentVersionObj -ge $targetVersionObj) { + $comparison = $currentVersionObj.CompareTo($targetVersionObj) + if ($comparison -ge 0) { Write-Host "Current version $currentVersion is greater than or equal to target version $version. Skipping installation." $needToInstall = $false } else { @@ -56,7 +57,7 @@ runs: Uninstall-Package -Name $currentInstall.Name -Force -ErrorAction SilentlyContinue } } catch { - Write-Host "Error comparing versions: $_. Will proceed with installation." + Write-Host "Error comparing versions: $_ Will proceed with installation." } } else { Write-Host "PowerShell Core not found. Will install version $version" @@ -91,18 +92,44 @@ runs: if: runner.os == 'Linux' shell: bash run: | - version='${{ inputs.version }}' + version='${{ inputs.Version }}' + + # Function to compare versions + compare_versions() { + local current=$1 + local target=$2 + + # Split versions into arrays + IFS='.' read -ra current_parts <<< "$current" + IFS='.' read -ra target_parts <<< "$target" + + # Ensure all parts exist (default to 0 if missing) + for i in {0..2}; do + current_parts[$i]=${current_parts[$i]:-0} + target_parts[$i]=${target_parts[$i]:-0} + done + + # Compare major, minor, patch + for i in {0..2}; do + if [ "${current_parts[$i]}" -lt "${target_parts[$i]}" ]; then + return 1 # current < target + elif [ "${current_parts[$i]}" -gt "${target_parts[$i]}" ]; then + return 2 # current > target + fi + done + + return 0 # equal + } + if [ -z "$version" ]; then # Get latest version if not specified version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) echo "Latest PowerShell version: $version" - else - version="v$version" - echo "Installing specified PowerShell version: $version" fi - # Strip the 'v' prefix for version comparison + # Always remove 'v' prefix if present clean_version=${version#v} + echo "Installing PowerShell version: $clean_version" # Check if PowerShell is already installed and get current version need_to_install=true @@ -110,31 +137,22 @@ runs: current_version=$(pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') echo "Current PowerShell version: $current_version" - # Properly compare versions with version components - current_major=$(echo "$current_version" | cut -d'.' -f1) - current_minor=$(echo "$current_version" | cut -d'.' -f2) - current_patch=$(echo "$current_version" | cut -d'.' -f3) - - target_major=$(echo "$clean_version" | cut -d'.' -f1) - target_minor=$(echo "$clean_version" | cut -d'.' -f2) - target_patch=$(echo "$clean_version" | cut -d'.' -f3) - - # Check if the current version is greater than or equal to target - if [ "$current_major" -gt "$target_major" ] || - ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -gt "$target_minor" ]) || - ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -eq "$target_minor" ] && [ "$current_patch" -ge "$target_patch" ]); then - echo "Current version $current_version is greater than or equal to target version $clean_version. Skipping installation." - need_to_install=false - else - echo "Current version $current_version is lower than target version $clean_version. Will upgrade." - sudo apt-get remove powershell -y - fi + compare_versions "$current_version" "$clean_version" + case $? in + 0) echo "Versions are equal"; need_to_install=false ;; + 2) echo "Current version is higher"; need_to_install=false ;; + 1) echo "Current version is lower"; need_to_install=true ;; + esac else echo "PowerShell is not installed. Will install version $clean_version" fi if [ "$need_to_install" = true ]; then - wget https://github.com/PowerShell/PowerShell/releases/download/$version/powershell_${clean_version}-1.deb_amd64.deb + # Install prerequisites + sudo apt-get update + sudo apt-get install -y wget apt-transport-https + + wget https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/powershell_${clean_version}-1.deb_amd64.deb sudo dpkg -i powershell_${clean_version}-1.deb_amd64.deb sudo apt-get install -f @@ -152,19 +170,44 @@ runs: if: runner.os == 'macOS' shell: bash run: | - # Get version information - version='${{ inputs.version }}' + version='${{ inputs.Version }}' + + # Function to compare versions + compare_versions() { + local current=$1 + local target=$2 + + # Split versions into arrays + IFS='.' read -ra current_parts <<< "$current" + IFS='.' read -ra target_parts <<< "$target" + + # Ensure all parts exist (default to 0 if missing) + for i in {0..2}; do + current_parts[$i]=${current_parts[$i]:-0} + target_parts[$i]=${target_parts[$i]:-0} + done + + # Compare major, minor, patch + for i in {0..2}; do + if [ "${current_parts[$i]}" -lt "${target_parts[$i]}" ]; then + return 1 # current < target + elif [ "${current_parts[$i]}" -gt "${target_parts[$i]}" ]; then + return 2 # current > target + fi + done + + return 0 # equal + } + if [ -z "$version" ]; then # Get latest version if not specified version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) echo "Latest PowerShell version: $version" - else - version="v$version" - echo "Installing specified PowerShell version: $version" fi - # The version without 'v' prefix + # Always remove 'v' prefix if present clean_version=${version#v} + echo "Installing PowerShell version: $clean_version" # Check if PowerShell is already installed and get current version need_to_install=true @@ -172,84 +215,40 @@ runs: current_version=$(/usr/local/bin/pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') echo "Current PowerShell version: $current_version" - # Properly compare versions with version components - current_major=$(echo "$current_version" | cut -d'.' -f1) - current_minor=$(echo "$current_version" | cut -d'.' -f2) - current_patch=$(echo "$current_version" | cut -d'.' -f3) - - target_major=$(echo "$clean_version" | cut -d'.' -f1) - target_minor=$(echo "$clean_version" | cut -d'.' -f2) - target_patch=$(echo "$clean_version" | cut -d'.' -f3) - - # Check if the current version is greater than or equal to target - if [ "$current_major" -gt "$target_major" ] || - ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -gt "$target_minor" ]) || - ([ "$current_major" -eq "$target_major" ] && [ "$current_minor" -eq "$target_minor" ] && [ "$current_patch" -ge "$target_patch" ]); then - echo "Current version $current_version is greater than or equal to target version $clean_version. Skipping installation." - need_to_install=false - else - echo "Current version $current_version is lower than target version $clean_version. Will upgrade." - # Clean up existing PowerShell installation - sudo rm -rf /usr/local/microsoft/powershell - fi + compare_versions "$current_version" "$clean_version" + case $? in + 0) echo "Versions are equal"; need_to_install=false ;; + 2) echo "Current version is higher"; need_to_install=false ;; + 1) echo "Current version is lower"; need_to_install=true ;; + esac else echo "PowerShell is not installed. Will install version $clean_version" fi if [ "$need_to_install" = true ]; then - # Try the different naming patterns for the macOS package - pkg_patterns=( - "powershell-$clean_version-osx-x64.pkg" - "powershell-$clean_version-osx-arm64.pkg" - "powershell-$clean_version-osx.pkg" - ) - - # Determine if running on Apple Silicon or Intel + # Determine architecture if [ "$(uname -m)" = "arm64" ]; then echo "Detected Apple Silicon (ARM64)" - arch="arm64" + pkg_name="powershell-$clean_version-osx-arm64.pkg" else echo "Detected Intel CPU (x64)" - arch="x64" + pkg_name="powershell-$clean_version-osx-x64.pkg" fi - # Try to download the appropriate package based on architecture - download_success=false - - for pkg_name in "${pkg_patterns[@]}"; do - echo "Trying to download $pkg_name..." - url="https://github.com/PowerShell/PowerShell/releases/download/$version/$pkg_name" - - # Try to download the file - if curl -LO $url --fail; then - echo "Successfully downloaded $pkg_name" - download_success=true - break - else - echo "Failed to download $pkg_name" - fi - done - - if [ "$download_success" = false ]; then - echo "ERROR: Could not download PowerShell package for macOS. Please check version and available packages." - exit 1 - fi + # Download the package + url="https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name" + echo "Downloading from $url" + curl -LO $url + + # Install the package + sudo installer -pkg "$pkg_name" -target / - # Verify the file exists before installation - if [ -f "$pkg_name" ]; then - echo "Installing PowerShell package: $pkg_name" - sudo installer -pkg "$pkg_name" -target / - - # Verify the installation - if [ -f "/usr/local/bin/pwsh" ]; then - echo "PowerShell installed successfully:" - /usr/local/bin/pwsh -Command '$PSVersionTable' - else - echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh" - exit 1 - fi + # Verify the installation + if [ -f "/usr/local/bin/pwsh" ]; then + echo "PowerShell installed successfully:" + /usr/local/bin/pwsh -Command '$PSVersionTable' else - echo "ERROR: Downloaded package file not found: $pkg_name" + echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh" exit 1 fi fi From e67fd074075da790f139b27d5ba5219c27857476 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:22:23 +0200 Subject: [PATCH 11/52] Enhance PowerShell installation logic: improve version comparison, streamline current version retrieval, and add error handling for download and installation processes. --- action.yml | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/action.yml b/action.yml index ea9a910..3024bc3 100644 --- a/action.yml +++ b/action.yml @@ -34,9 +34,9 @@ runs: # Check if PowerShell is already installed and compare versions $needToInstall = $true try { - $currentInstall = Get-Package -Name "PowerShell*" -ErrorAction SilentlyContinue | Select-Object -First 1 + $currentInstall = Get-Command pwsh -ErrorAction SilentlyContinue if ($currentInstall) { - $currentVersion = $currentInstall.Version + $currentVersion = & pwsh -Command '$PSVersionTable.PSVersion.ToString()' Write-Host "Current PowerShell version: $currentVersion" # Parse versions into System.Version objects for proper comparison @@ -45,45 +45,47 @@ runs: $targetVersionObj = [System.Version]$version # Compare versions - $comparison = $currentVersionObj.CompareTo($targetVersionObj) - if ($comparison -ge 0) { + if ($currentVersionObj -ge $targetVersionObj) { Write-Host "Current version $currentVersion is greater than or equal to target version $version. Skipping installation." $needToInstall = $false } else { Write-Host "Current version $currentVersion is lower than target version $version. Will upgrade." - - # Uninstall current version - Write-Host "Uninstalling $($currentInstall.Name) version $($currentInstall.Version)" - Uninstall-Package -Name $currentInstall.Name -Force -ErrorAction SilentlyContinue } } catch { Write-Host "Error comparing versions: $_ Will proceed with installation." + $needToInstall = $true } } else { Write-Host "PowerShell Core not found. Will install version $version" } } catch { Write-Host "Error checking current PowerShell version: $_" + $needToInstall = $true } if ($needToInstall) { - # Download and install PowerShell - $msiName = "PowerShell-$version-win-x64.msi" - $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" - - Write-Host "Downloading from $downloadUrl" - Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName - - Write-Host "Installing PowerShell $version" - Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait - - # Verify installation - $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" - if (Test-Path $pwshPath) { - Write-Host "PowerShell installed successfully:" - & $pwshPath -Command '$PSVersionTable' - } else { - Write-Error "PowerShell installation failed. Could not find $pwshPath" + try { + # Download and install PowerShell + $msiName = "PowerShell-$version-win-x64.msi" + $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" + + Write-Host "Downloading from $downloadUrl" + Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName -ErrorAction Stop + + Write-Host "Installing PowerShell $version" + Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait -ErrorAction Stop + + # Verify installation + $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" + if (Test-Path $pwshPath) { + Write-Host "PowerShell installed successfully:" + & $pwshPath -Command '$PSVersionTable' + } else { + Write-Error "PowerShell installation failed. Could not find $pwshPath" + exit 1 + } + } catch { + Write-Error "Failed to install PowerShell: $_" exit 1 } } From 23bddd9ee6abcbf1b6da9360abfb8c08d00452d5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:25:52 +0200 Subject: [PATCH 12/52] Enhance PowerShell installation on Linux: add version normalization, improve version comparison logic, and handle multiple package naming formats for downloads. --- action.yml | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index 3024bc3..a902abe 100644 --- a/action.yml +++ b/action.yml @@ -96,10 +96,18 @@ runs: run: | version='${{ inputs.Version }}' + # Function to normalize version (remove trailing .0 and v prefix) + normalize_version() { + local version=${1#v} # Remove v prefix + version=${version%.0} # Remove trailing .0 + version=${version%.0} # Remove additional .0 if present + echo "$version" + } + # Function to compare versions compare_versions() { - local current=$1 - local target=$2 + local current=$(normalize_version "$1") + local target=$(normalize_version "$2") # Split versions into arrays IFS='.' read -ra current_parts <<< "$current" @@ -144,6 +152,7 @@ runs: 0) echo "Versions are equal"; need_to_install=false ;; 2) echo "Current version is higher"; need_to_install=false ;; 1) echo "Current version is lower"; need_to_install=true ;; + *) echo "Version comparison failed, proceeding with installation" ;; esac else echo "PowerShell is not installed. Will install version $clean_version" @@ -154,8 +163,18 @@ runs: sudo apt-get update sudo apt-get install -y wget apt-transport-https - wget https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/powershell_${clean_version}-1.deb_amd64.deb - sudo dpkg -i powershell_${clean_version}-1.deb_amd64.deb + # Download package - handle both old and new naming formats + pkg_name="powershell_${clean_version}-1.deb_amd64.deb" + if ! wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name"; then + # Try alternative package name format + pkg_name="powershell-${clean_version}-linux-x64.deb" + wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name" || { + echo "ERROR: Failed to download PowerShell package" + exit 1 + } + fi + + sudo dpkg -i "$pkg_name" sudo apt-get install -f # Verify installation From cb597662ebce41dd2fc6b71c11113a8b76f6d74e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:44:15 +0200 Subject: [PATCH 13/52] Refactor PowerShell installation logic: improve version comparison functions, streamline version retrieval, and enhance error handling for installation processes. --- action.yml | 251 ++++++++++++++++++++++------------------------------- 1 file changed, 102 insertions(+), 149 deletions(-) diff --git a/action.yml b/action.yml index a902abe..cf7b1cf 100644 --- a/action.yml +++ b/action.yml @@ -19,53 +19,57 @@ runs: run: | $version = '${{ inputs.Version }}' - # Get the version to install + # Get version to install if ([string]::IsNullOrWhiteSpace($version)) { - # Get latest version from GitHub API $releaseInfo = Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' $version = $releaseInfo.tag_name.Trim('v') Write-Host "Latest PowerShell version: $version" } else { - # Remove the 'v' prefix if it exists $version = $version.TrimStart('v') Write-Host "Installing specified PowerShell version: $version" } - # Check if PowerShell is already installed and compare versions + # Function to compare versions + function Compare-Versions { + param( + [string]$CurrentVersion, + [string]$TargetVersion + ) + + $currentParts = $CurrentVersion.Split('.') + @(0,0,0) + $targetParts = $TargetVersion.Split('.') + @(0,0,0) + + for ($i = 0; $i -lt 3; $i++) { + $currentPart = [int]$currentParts[$i] + $targetPart = [int]$targetParts[$i] + + if ($currentPart -lt $targetPart) { return -1 } + if ($currentPart -gt $targetPart) { return 1 } + } + return 0 + } + + # Check existing installation $needToInstall = $true try { - $currentInstall = Get-Command pwsh -ErrorAction SilentlyContinue - if ($currentInstall) { + if (Get-Command pwsh -ErrorAction SilentlyContinue) { $currentVersion = & pwsh -Command '$PSVersionTable.PSVersion.ToString()' Write-Host "Current PowerShell version: $currentVersion" - # Parse versions into System.Version objects for proper comparison - try { - $currentVersionObj = [System.Version]$currentVersion - $targetVersionObj = [System.Version]$version - - # Compare versions - if ($currentVersionObj -ge $targetVersionObj) { - Write-Host "Current version $currentVersion is greater than or equal to target version $version. Skipping installation." - $needToInstall = $false - } else { - Write-Host "Current version $currentVersion is lower than target version $version. Will upgrade." - } - } catch { - Write-Host "Error comparing versions: $_ Will proceed with installation." - $needToInstall = $true + $comparison = Compare-Versions -CurrentVersion $currentVersion -TargetVersion $version + if ($comparison -ge 0) { + Write-Host "Current version meets or exceeds target version. Skipping installation." + $needToInstall = $false + } else { + Write-Host "Current version is lower than target version. Will upgrade." } - } else { - Write-Host "PowerShell Core not found. Will install version $version" } } catch { - Write-Host "Error checking current PowerShell version: $_" - $needToInstall = $true + Write-Host "Error checking current version: $_" } if ($needToInstall) { try { - # Download and install PowerShell $msiName = "PowerShell-$version-win-x64.msi" $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" @@ -73,19 +77,16 @@ runs: Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName -ErrorAction Stop Write-Host "Installing PowerShell $version" - Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait -ErrorAction Stop + Start-Process msiexec.exe -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait -ErrorAction Stop - # Verify installation - $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" - if (Test-Path $pwshPath) { - Write-Host "PowerShell installed successfully:" - & $pwshPath -Command '$PSVersionTable' + if (Test-Path "$env:ProgramFiles\PowerShell\7\pwsh.exe") { + Write-Host "Installation successful" + & "$env:ProgramFiles\PowerShell\7\pwsh.exe" -Command '$PSVersionTable' } else { - Write-Error "PowerShell installation failed. Could not find $pwshPath" - exit 1 + throw "Installation failed - pwsh.exe not found" } } catch { - Write-Error "Failed to install PowerShell: $_" + Write-Error "Installation failed: $_" exit 1 } } @@ -96,52 +97,34 @@ runs: run: | version='${{ inputs.Version }}' - # Function to normalize version (remove trailing .0 and v prefix) - normalize_version() { - local version=${1#v} # Remove v prefix - version=${version%.0} # Remove trailing .0 - version=${version%.0} # Remove additional .0 if present - echo "$version" + # Version comparison functions + get_version_parts() { + local version=${1#v} + IFS='.' read -ra parts <<< "$version" + echo "${parts[0]:-0} ${parts[1]:-0} ${parts[2]:-0}" } - # Function to compare versions compare_versions() { - local current=$(normalize_version "$1") - local target=$(normalize_version "$2") - - # Split versions into arrays - IFS='.' read -ra current_parts <<< "$current" - IFS='.' read -ra target_parts <<< "$target" - - # Ensure all parts exist (default to 0 if missing) - for i in {0..2}; do - current_parts[$i]=${current_parts[$i]:-0} - target_parts[$i]=${target_parts[$i]:-0} - done - - # Compare major, minor, patch - for i in {0..2}; do - if [ "${current_parts[$i]}" -lt "${target_parts[$i]}" ]; then - return 1 # current < target - elif [ "${current_parts[$i]}" -gt "${target_parts[$i]}" ]; then - return 2 # current > target - fi - done - - return 0 # equal + local current_parts=($(get_version_parts "$1")) + local target_parts=($(get_version_parts "$2")) + + for i in {0..2}; do + if (( current_parts[i] < target_parts[i] )); then return 1; fi + if (( current_parts[i] > target_parts[i] )); then return 2; fi + done + return 0 } + # Get version if not specified if [ -z "$version" ]; then - # Get latest version if not specified version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) echo "Latest PowerShell version: $version" fi - # Always remove 'v' prefix if present clean_version=${version#v} echo "Installing PowerShell version: $clean_version" - # Check if PowerShell is already installed and get current version + # Check existing installation need_to_install=true if command -v pwsh &> /dev/null; then current_version=$(pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') @@ -149,42 +132,34 @@ runs: compare_versions "$current_version" "$clean_version" case $? in - 0) echo "Versions are equal"; need_to_install=false ;; - 2) echo "Current version is higher"; need_to_install=false ;; - 1) echo "Current version is lower"; need_to_install=true ;; - *) echo "Version comparison failed, proceeding with installation" ;; + 0) echo "Versions equal - skipping install"; need_to_install=false ;; + 2) echo "Current version higher - skipping install"; need_to_install=false ;; + 1) echo "Current version lower - will upgrade" ;; esac - else - echo "PowerShell is not installed. Will install version $clean_version" fi if [ "$need_to_install" = true ]; then - # Install prerequisites sudo apt-get update sudo apt-get install -y wget apt-transport-https - # Download package - handle both old and new naming formats - pkg_name="powershell_${clean_version}-1.deb_amd64.deb" - if ! wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name"; then - # Try alternative package name format - pkg_name="powershell-${clean_version}-linux-x64.deb" - wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name" || { - echo "ERROR: Failed to download PowerShell package" - exit 1 - } - fi - - sudo dpkg -i "$pkg_name" - sudo apt-get install -f - - # Verify installation - if command -v pwsh &> /dev/null; then - echo "PowerShell installed successfully:" - pwsh -c '$PSVersionTable' - else - echo "ERROR: PowerShell installation failed." + # Try multiple package formats + pkg_found=false + for pkg in "powershell_${clean_version}-1.deb_amd64.deb" "powershell-${clean_version}-linux-x64.deb"; do + if wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg"; then + pkg_found=true + sudo dpkg -i "$pkg" + sudo apt-get install -f + break + fi + done + + if [ "$pkg_found" = false ]; then + echo "ERROR: Failed to download package" exit 1 fi + + echo "Installation successful:" + pwsh -c '$PSVersionTable' fi - name: Install PowerShell on macOS @@ -193,44 +168,34 @@ runs: run: | version='${{ inputs.Version }}' - # Function to compare versions + # Version comparison functions + get_version_parts() { + local version=${1#v} + IFS='.' read -ra parts <<< "$version" + echo "${parts[0]:-0} ${parts[1]:-0} ${parts[2]:-0}" + } + compare_versions() { - local current=$1 - local target=$2 - - # Split versions into arrays - IFS='.' read -ra current_parts <<< "$current" - IFS='.' read -ra target_parts <<< "$target" - - # Ensure all parts exist (default to 0 if missing) - for i in {0..2}; do - current_parts[$i]=${current_parts[$i]:-0} - target_parts[$i]=${target_parts[$i]:-0} - done - - # Compare major, minor, patch - for i in {0..2}; do - if [ "${current_parts[$i]}" -lt "${target_parts[$i]}" ]; then - return 1 # current < target - elif [ "${current_parts[$i]}" -gt "${target_parts[$i]}" ]; then - return 2 # current > target - fi - done - - return 0 # equal + local current_parts=($(get_version_parts "$1")) + local target_parts=($(get_version_parts "$2")) + + for i in {0..2}; do + if (( current_parts[i] < target_parts[i] )); then return 1; fi + if (( current_parts[i] > target_parts[i] )); then return 2; fi + done + return 0 } + # Get version if not specified if [ -z "$version" ]; then - # Get latest version if not specified version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) echo "Latest PowerShell version: $version" fi - # Always remove 'v' prefix if present clean_version=${version#v} echo "Installing PowerShell version: $clean_version" - # Check if PowerShell is already installed and get current version + # Check existing installation need_to_install=true if [ -f "/usr/local/bin/pwsh" ]; then current_version=$(/usr/local/bin/pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') @@ -238,38 +203,26 @@ runs: compare_versions "$current_version" "$clean_version" case $? in - 0) echo "Versions are equal"; need_to_install=false ;; - 2) echo "Current version is higher"; need_to_install=false ;; - 1) echo "Current version is lower"; need_to_install=true ;; + 0) echo "Versions equal - skipping install"; need_to_install=false ;; + 2) echo "Current version higher - skipping install"; need_to_install=false ;; + 1) echo "Current version lower - will upgrade" ;; esac - else - echo "PowerShell is not installed. Will install version $clean_version" fi if [ "$need_to_install" = true ]; then - # Determine architecture - if [ "$(uname -m)" = "arm64" ]; then - echo "Detected Apple Silicon (ARM64)" - pkg_name="powershell-$clean_version-osx-arm64.pkg" - else - echo "Detected Intel CPU (x64)" - pkg_name="powershell-$clean_version-osx-x64.pkg" - fi - - # Download the package - url="https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name" - echo "Downloading from $url" - curl -LO $url - - # Install the package - sudo installer -pkg "$pkg_name" -target / + arch=$(uname -m) + case $arch in + arm64) pkg="powershell-${clean_version}-osx-arm64.pkg" ;; + *) pkg="powershell-${clean_version}-osx-x64.pkg" ;; + esac - # Verify the installation - if [ -f "/usr/local/bin/pwsh" ]; then - echo "PowerShell installed successfully:" - /usr/local/bin/pwsh -Command '$PSVersionTable' - else - echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh" + if ! curl -LO "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg"; then + echo "ERROR: Failed to download package" exit 1 fi + + sudo installer -pkg "$pkg" -target / + + echo "Installation successful:" + /usr/local/bin/pwsh -c '$PSVersionTable' fi From 9272ace87528d8804ce43db555dc7eb763d778d5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 19:56:17 +0200 Subject: [PATCH 14/52] Refactor PowerShell installation action: improve input handling, streamline version detection, and enhance logging for installation processes across Linux, macOS, and Windows. --- action.yml | 353 ++++++++++++++++++++++------------------------------- 1 file changed, 149 insertions(+), 204 deletions(-) diff --git a/action.yml b/action.yml index cf7b1cf..18be4fb 100644 --- a/action.yml +++ b/action.yml @@ -1,228 +1,173 @@ -name: Install-PowerShell -description: Install PowerShell -author: PSModule +name: "Install PowerShell" +description: "Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Handles install, downgrade, or forced reinstall with uniform logging." +author: "Your Org" branding: - icon: upload-cloud - color: white + icon: "terminal" + color: "purple" inputs: - Version: - description: The version of PowerShell to install, e.g., 7.4.0 or 7.5.0. If not provided, the latest version is installed. - default: '' + version: + description: "Exact PowerShell version to install (e.g. 7.4.1)" + required: true + reinstall: + description: "Set to 'true' to uninstall & reinstall even when the exact version is already present." + default: "false" + package-source: + description: "Package source: 'microsoft' (default), 'github', or custom direct URL to the archive/MSI." + default: "microsoft" runs: - using: composite + using: "composite" steps: - - name: Install PowerShell on Windows - if: runner.os == 'Windows' - shell: powershell + # --------------------------------------------------------------------- + # Common environment + # --------------------------------------------------------------------- + - name: Set shared env + shell: bash run: | - $version = '${{ inputs.Version }}' - - # Get version to install - if ([string]::IsNullOrWhiteSpace($version)) { - $releaseInfo = Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' - $version = $releaseInfo.tag_name.Trim('v') - Write-Host "Latest PowerShell version: $version" - } else { - $version = $version.TrimStart('v') - Write-Host "Installing specified PowerShell version: $version" - } - - # Function to compare versions - function Compare-Versions { - param( - [string]$CurrentVersion, - [string]$TargetVersion - ) - - $currentParts = $CurrentVersion.Split('.') + @(0,0,0) - $targetParts = $TargetVersion.Split('.') + @(0,0,0) - - for ($i = 0; $i -lt 3; $i++) { - $currentPart = [int]$currentParts[$i] - $targetPart = [int]$targetParts[$i] - - if ($currentPart -lt $targetPart) { return -1 } - if ($currentPart -gt $targetPart) { return 1 } - } - return 0 - } - - # Check existing installation - $needToInstall = $true - try { - if (Get-Command pwsh -ErrorAction SilentlyContinue) { - $currentVersion = & pwsh -Command '$PSVersionTable.PSVersion.ToString()' - Write-Host "Current PowerShell version: $currentVersion" - - $comparison = Compare-Versions -CurrentVersion $currentVersion -TargetVersion $version - if ($comparison -ge 0) { - Write-Host "Current version meets or exceeds target version. Skipping installation." - $needToInstall = $false - } else { - Write-Host "Current version is lower than target version. Will upgrade." - } - } - } catch { - Write-Host "Error checking current version: $_" - } - - if ($needToInstall) { - try { - $msiName = "PowerShell-$version-win-x64.msi" - $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName" - - Write-Host "Downloading from $downloadUrl" - Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName -ErrorAction Stop - - Write-Host "Installing PowerShell $version" - Start-Process msiexec.exe -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait -ErrorAction Stop - - if (Test-Path "$env:ProgramFiles\PowerShell\7\pwsh.exe") { - Write-Host "Installation successful" - & "$env:ProgramFiles\PowerShell\7\pwsh.exe" -Command '$PSVersionTable' - } else { - throw "Installation failed - pwsh.exe not found" - } - } catch { - Write-Error "Installation failed: $_" - exit 1 - } - } - - - name: Install PowerShell on Ubuntu + echo "REQUESTED_VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "REINSTALL=${{ inputs.reinstall }}" >> $GITHUB_ENV + echo "PACKAGE_SOURCE=${{ inputs['package-source'] }}" >> $GITHUB_ENV + + # --------------------------------------------------------------------- + # Linux installer ------------------------------------------------------ + # --------------------------------------------------------------------- + - name: Install PowerShell (Linux) if: runner.os == 'Linux' + id: linux shell: bash run: | - version='${{ inputs.Version }}' - - # Version comparison functions - get_version_parts() { - local version=${1#v} - IFS='.' read -ra parts <<< "$version" - echo "${parts[0]:-0} ${parts[1]:-0} ${parts[2]:-0}" - } - - compare_versions() { - local current_parts=($(get_version_parts "$1")) - local target_parts=($(get_version_parts "$2")) - - for i in {0..2}; do - if (( current_parts[i] < target_parts[i] )); then return 1; fi - if (( current_parts[i] > target_parts[i] )); then return 2; fi - done - return 0 - } - - # Get version if not specified - if [ -z "$version" ]; then - version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) - echo "Latest PowerShell version: $version" + set -e + log() { echo "::notice title=pwsh-installer::[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $1"; } + + log "Detecting existing PowerShell on Linux…" + DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) + log "Detected version: ${DETECTED_VERSION:-}" + log "Requested version: $REQUESTED_VERSION" + log "Reinstall flag: $REINSTALL" + + if [[ -z "$DETECTED_VERSION" ]]; then + DECISION="install" + elif [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + if [[ "$REINSTALL" == "true" ]]; then DECISION="reinstall"; else DECISION="skip"; fi + else + DECISION="uninstall-install" # covers downgrade or upgrade fi - - clean_version=${version#v} - echo "Installing PowerShell version: $clean_version" - - # Check existing installation - need_to_install=true - if command -v pwsh &> /dev/null; then - current_version=$(pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') - echo "Current PowerShell version: $current_version" - - compare_versions "$current_version" "$clean_version" - case $? in - 0) echo "Versions equal - skipping install"; need_to_install=false ;; - 2) echo "Current version higher - skipping install"; need_to_install=false ;; - 1) echo "Current version lower - will upgrade" ;; - esac + log "Decision: $DECISION" + + if [[ "$DECISION" == "skip" ]]; then + log "Skipping installation on Linux (exact version present)." + else + log "Uninstalling any existing PowerShell…" + sudo rm -rf /usr/local/microsoft/powershell || true + sudo rm -f /usr/local/bin/pwsh || true + log "Installing PowerShell $REQUESTED_VERSION…" + curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- -Version "$REQUESTED_VERSION" -Destination /usr/local fi - if [ "$need_to_install" = true ]; then - sudo apt-get update - sudo apt-get install -y wget apt-transport-https - - # Try multiple package formats - pkg_found=false - for pkg in "powershell_${clean_version}-1.deb_amd64.deb" "powershell-${clean_version}-linux-x64.deb"; do - if wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg"; then - pkg_found=true - sudo dpkg -i "$pkg" - sudo apt-get install -f - break - fi - done - - if [ "$pkg_found" = false ]; then - echo "ERROR: Failed to download package" - exit 1 - fi - - echo "Installation successful:" - pwsh -c '$PSVersionTable' - fi + PWSH_PATH=$(command -v pwsh) + echo "PWSH_PATH=$PWSH_PATH" >> $GITHUB_ENV + echo "PWSH_VERSION=$REQUESTED_VERSION" >> $GITHUB_ENV + echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT + echo "pwsh-version=$REQUESTED_VERSION" >> $GITHUB_OUTPUT - - name: Install PowerShell on macOS + # --------------------------------------------------------------------- + # macOS installer ------------------------------------------------------ + # --------------------------------------------------------------------- + - name: Install PowerShell (macOS) if: runner.os == 'macOS' + id: macos shell: bash run: | - version='${{ inputs.Version }}' - - # Version comparison functions - get_version_parts() { - local version=${1#v} - IFS='.' read -ra parts <<< "$version" - echo "${parts[0]:-0} ${parts[1]:-0} ${parts[2]:-0}" - } + set -e + log() { echo "::notice title=pwsh-installer::[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $1"; } + + log "Detecting existing PowerShell on macOS…" + DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) + log "Detected version: ${DETECTED_VERSION:-}" + log "Requested version: $REQUESTED_VERSION" + log "Reinstall flag: $REINSTALL" + + if [[ -z "$DETECTED_VERSION" ]]; then + DECISION="install" + elif [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + if [[ "$REINSTALL" == "true" ]]; then DECISION="reinstall"; else DECISION="skip"; fi + else + DECISION="uninstall-install" + fi + log "Decision: $DECISION" + + if [[ "$DECISION" == "skip" ]]; then + log "Skipping installation on macOS (exact version present)." + else + log "Uninstalling any existing PowerShell…" + sudo rm -rf /usr/local/microsoft/powershell || true + sudo rm -f /usr/local/bin/pwsh || true + log "Installing PowerShell $REQUESTED_VERSION…" + curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- -Version "$REQUESTED_VERSION" -Destination /usr/local + fi - compare_versions() { - local current_parts=($(get_version_parts "$1")) - local target_parts=($(get_version_parts "$2")) + PWSH_PATH=$(command -v pwsh) + echo "PWSH_PATH=$PWSH_PATH" >> $GITHUB_ENV + echo "PWSH_VERSION=$REQUESTED_VERSION" >> $GITHUB_ENV + echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT + echo "pwsh-version=$REQUESTED_VERSION" >> $GITHUB_OUTPUT - for i in {0..2}; do - if (( current_parts[i] < target_parts[i] )); then return 1; fi - if (( current_parts[i] > target_parts[i] )); then return 2; fi - done - return 0 + # --------------------------------------------------------------------- + # Windows installer ---------------------------------------------------- + # --------------------------------------------------------------------- + - name: Install PowerShell (Windows) + if: runner.os == 'Windows' + id: windows + shell: powershell + run: | + function Log($Message) { + Write-Host "::notice title=pwsh-installer::[$([DateTime]::UtcNow.ToString('u'))] $Message" } - # Get version if not specified - if [ -z "$version" ]; then - version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4) - echo "Latest PowerShell version: $version" - fi + Log "Detecting existing PowerShell on Windows…" + try { $detected = (pwsh -NoLogo -NoProfile -Command "$PSVersionTable.PSVersion.ToString()") } catch { $detected = $null } + Log "Detected version: $($detected ?? '')" + Log "Requested version: $env:REQUESTED_VERSION" + Log "Reinstall flag: $env:REINSTALL" - clean_version=${version#v} - echo "Installing PowerShell version: $clean_version" - - # Check existing installation - need_to_install=true - if [ -f "/usr/local/bin/pwsh" ]; then - current_version=$(/usr/local/bin/pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n') - echo "Current PowerShell version: $current_version" - - compare_versions "$current_version" "$clean_version" - case $? in - 0) echo "Versions equal - skipping install"; need_to_install=false ;; - 2) echo "Current version higher - skipping install"; need_to_install=false ;; - 1) echo "Current version lower - will upgrade" ;; - esac - fi - - if [ "$need_to_install" = true ]; then - arch=$(uname -m) - case $arch in - arm64) pkg="powershell-${clean_version}-osx-arm64.pkg" ;; - *) pkg="powershell-${clean_version}-osx-x64.pkg" ;; - esac - - if ! curl -LO "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg"; then - echo "ERROR: Failed to download package" - exit 1 - fi + if (-not $detected) { + $decision = 'install' + } elseif ($detected -eq $env:REQUESTED_VERSION) { + $decision = ($env:REINSTALL -eq 'true') ? 'reinstall' : 'skip' + } else { + $decision = 'uninstall-install' + } + Log "Decision: $decision" - sudo installer -pkg "$pkg" -target / + if ($decision -eq 'skip') { + Log 'Skipping installation on Windows (exact version present).' + } + else { + Log 'Uninstalling any existing PowerShell…' + winget uninstall --id Microsoft.PowerShell -e --silent | Out-Null + Log "Installing PowerShell $env:REQUESTED_VERSION…" + $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" + $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" + Invoke-WebRequest $url -OutFile $msi + Start-Process msiexec.exe -ArgumentList "/i", $msi, "/quiet", "/norestart" -Wait + } - echo "Installation successful:" - /usr/local/bin/pwsh -c '$PSVersionTable' - fi + $pwshPath = (Get-Command pwsh).Source + echo "PWSH_PATH=$pwshPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "PWSH_VERSION=$($env:REQUESTED_VERSION)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "pwsh-path=$pwshPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + echo "pwsh-version=$($env:REQUESTED_VERSION)" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + + # --------------------------------------------------------------------- + # Aggregate outputs ---------------------------------------------------- + # --------------------------------------------------------------------- + - name: Export composite outputs + id: export + shell: bash + run: | + echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT + echo "pwsh-version=$PWSH_VERSION" >> $GITHUB_OUTPUT + env: + PWSH_PATH: ${{ env.PWSH_PATH }} + PWSH_VERSION: ${{ env.PWSH_VERSION }} From 4fb301bbe05d95a93a5d390d150369edc9a8a897 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:01:17 +0200 Subject: [PATCH 15/52] Refactor action.yml: standardize input naming, remove unused package source input, and streamline environment variable setup for PowerShell installation. --- action.yml | 61 ++++++++++++------------------------------------------ 1 file changed, 13 insertions(+), 48 deletions(-) diff --git a/action.yml b/action.yml index 18be4fb..bfc11da 100644 --- a/action.yml +++ b/action.yml @@ -1,37 +1,27 @@ -name: "Install PowerShell" -description: "Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Handles install, downgrade, or forced reinstall with uniform logging." -author: "Your Org" +name: Install PowerShell +description: Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Handles install, downgrade, or forced reinstall with uniform logging. +author: PSModule branding: - icon: "terminal" - color: "purple" + icon: terminal + color: purple inputs: - version: - description: "Exact PowerShell version to install (e.g. 7.4.1)" + Version: + description: Exact PowerShell version to install (e.g. 7.4.1) required: true - reinstall: - description: "Set to 'true' to uninstall & reinstall even when the exact version is already present." - default: "false" - package-source: - description: "Package source: 'microsoft' (default), 'github', or custom direct URL to the archive/MSI." - default: "microsoft" + Reinstall: + description: Set to 'true' to uninstall & reinstall even when the exact version is already present. + default: 'false' runs: - using: "composite" + using: composite steps: - # --------------------------------------------------------------------- - # Common environment - # --------------------------------------------------------------------- - name: Set shared env shell: bash run: | - echo "REQUESTED_VERSION=${{ inputs.version }}" >> $GITHUB_ENV - echo "REINSTALL=${{ inputs.reinstall }}" >> $GITHUB_ENV - echo "PACKAGE_SOURCE=${{ inputs['package-source'] }}" >> $GITHUB_ENV + echo "REQUESTED_VERSION=${{ inputs.Version }}" >> $GITHUB_ENV + echo "REINSTALL=${{ inputs.Reinstall }}" >> $GITHUB_ENV - # --------------------------------------------------------------------- - # Linux installer ------------------------------------------------------ - # --------------------------------------------------------------------- - name: Install PowerShell (Linux) if: runner.os == 'Linux' id: linux @@ -71,9 +61,6 @@ runs: echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT echo "pwsh-version=$REQUESTED_VERSION" >> $GITHUB_OUTPUT - # --------------------------------------------------------------------- - # macOS installer ------------------------------------------------------ - # --------------------------------------------------------------------- - name: Install PowerShell (macOS) if: runner.os == 'macOS' id: macos @@ -113,9 +100,6 @@ runs: echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT echo "pwsh-version=$REQUESTED_VERSION" >> $GITHUB_OUTPUT - # --------------------------------------------------------------------- - # Windows installer ---------------------------------------------------- - # --------------------------------------------------------------------- - name: Install PowerShell (Windows) if: runner.os == 'Windows' id: windows @@ -152,22 +136,3 @@ runs: Invoke-WebRequest $url -OutFile $msi Start-Process msiexec.exe -ArgumentList "/i", $msi, "/quiet", "/norestart" -Wait } - - $pwshPath = (Get-Command pwsh).Source - echo "PWSH_PATH=$pwshPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "PWSH_VERSION=$($env:REQUESTED_VERSION)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "pwsh-path=$pwshPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - echo "pwsh-version=$($env:REQUESTED_VERSION)" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - - # --------------------------------------------------------------------- - # Aggregate outputs ---------------------------------------------------- - # --------------------------------------------------------------------- - - name: Export composite outputs - id: export - shell: bash - run: | - echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT - echo "pwsh-version=$PWSH_VERSION" >> $GITHUB_OUTPUT - env: - PWSH_PATH: ${{ env.PWSH_PATH }} - PWSH_VERSION: ${{ env.PWSH_VERSION }} From 247296af5c75f67fa120655f94eaf298ab1c1ba7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:02:42 +0200 Subject: [PATCH 16/52] Refactor PowerShell installation steps: remove shared environment setup and directly set environment variables for each OS-specific installation step. --- action.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/action.yml b/action.yml index bfc11da..3dfc655 100644 --- a/action.yml +++ b/action.yml @@ -16,15 +16,11 @@ inputs: runs: using: composite steps: - - name: Set shared env - shell: bash - run: | - echo "REQUESTED_VERSION=${{ inputs.Version }}" >> $GITHUB_ENV - echo "REINSTALL=${{ inputs.Reinstall }}" >> $GITHUB_ENV - - name: Install PowerShell (Linux) if: runner.os == 'Linux' - id: linux + env: + REQUESTED_VERSION: ${{ inputs.Version }} + REINSTALL: ${{ inputs.Reinstall }} shell: bash run: | set -e @@ -63,7 +59,9 @@ runs: - name: Install PowerShell (macOS) if: runner.os == 'macOS' - id: macos + env: + REQUESTED_VERSION: ${{ inputs.Version }} + REINSTALL: ${{ inputs.Reinstall }} shell: bash run: | set -e @@ -102,7 +100,9 @@ runs: - name: Install PowerShell (Windows) if: runner.os == 'Windows' - id: windows + env: + REQUESTED_VERSION: ${{ inputs.Version }} + REINSTALL: ${{ inputs.Reinstall }} shell: powershell run: | function Log($Message) { From e05baed03ba204e46d7587f75fde777220d3b3c3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:18:46 +0200 Subject: [PATCH 17/52] Refactor logging in PowerShell installation: replace custom log function with standard echo statements for improved clarity and consistency across Linux, macOS, and Windows installation steps. --- action.yml | 59 +++++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/action.yml b/action.yml index 3dfc655..ba3596f 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,7 @@ name: Install PowerShell -description: Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Handles install, downgrade, or forced reinstall with uniform logging. +description: | + Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). + Handles install, downgrade, or forced reinstall. author: PSModule branding: icon: terminal @@ -24,13 +26,12 @@ runs: shell: bash run: | set -e - log() { echo "::notice title=pwsh-installer::[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $1"; } - log "Detecting existing PowerShell on Linux…" + echo "Detecting existing PowerShell on Linux…" DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - log "Detected version: ${DETECTED_VERSION:-}" - log "Requested version: $REQUESTED_VERSION" - log "Reinstall flag: $REINSTALL" + echo "Detected version: ${DETECTED_VERSION:-}" + echo "Requested version: $REQUESTED_VERSION" + echo "Reinstall flag: $REINSTALL" if [[ -z "$DETECTED_VERSION" ]]; then DECISION="install" @@ -39,15 +40,15 @@ runs: else DECISION="uninstall-install" # covers downgrade or upgrade fi - log "Decision: $DECISION" + echo "Decision: $DECISION" if [[ "$DECISION" == "skip" ]]; then - log "Skipping installation on Linux (exact version present)." + echo "Skipping installation on Linux (exact version present)." else - log "Uninstalling any existing PowerShell…" + echo "Uninstalling any existing PowerShell…" sudo rm -rf /usr/local/microsoft/powershell || true sudo rm -f /usr/local/bin/pwsh || true - log "Installing PowerShell $REQUESTED_VERSION…" + echo "Installing PowerShell $REQUESTED_VERSION…" curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- -Version "$REQUESTED_VERSION" -Destination /usr/local fi @@ -65,13 +66,11 @@ runs: shell: bash run: | set -e - log() { echo "::notice title=pwsh-installer::[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $1"; } - - log "Detecting existing PowerShell on macOS…" + echo "Detecting existing PowerShell on macOS…" DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - log "Detected version: ${DETECTED_VERSION:-}" - log "Requested version: $REQUESTED_VERSION" - log "Reinstall flag: $REINSTALL" + echo "Detected version: ${DETECTED_VERSION:-}" + echo "Requested version: $REQUESTED_VERSION" + echo "Reinstall flag: $REINSTALL" if [[ -z "$DETECTED_VERSION" ]]; then DECISION="install" @@ -80,15 +79,15 @@ runs: else DECISION="uninstall-install" fi - log "Decision: $DECISION" + echo "Decision: $DECISION" if [[ "$DECISION" == "skip" ]]; then - log "Skipping installation on macOS (exact version present)." + echo "Skipping installation on macOS (exact version present)." else - log "Uninstalling any existing PowerShell…" + echo "Uninstalling any existing PowerShell…" sudo rm -rf /usr/local/microsoft/powershell || true sudo rm -f /usr/local/bin/pwsh || true - log "Installing PowerShell $REQUESTED_VERSION…" + echo "Installing PowerShell $REQUESTED_VERSION…" curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- -Version "$REQUESTED_VERSION" -Destination /usr/local fi @@ -105,15 +104,11 @@ runs: REINSTALL: ${{ inputs.Reinstall }} shell: powershell run: | - function Log($Message) { - Write-Host "::notice title=pwsh-installer::[$([DateTime]::UtcNow.ToString('u'))] $Message" - } - - Log "Detecting existing PowerShell on Windows…" + Write-Host "Detecting existing PowerShell on Windows…" try { $detected = (pwsh -NoLogo -NoProfile -Command "$PSVersionTable.PSVersion.ToString()") } catch { $detected = $null } - Log "Detected version: $($detected ?? '')" - Log "Requested version: $env:REQUESTED_VERSION" - Log "Reinstall flag: $env:REINSTALL" + Write-Host "Detected version: $($detected ?? '')" + Write-Host "Requested version: $env:REQUESTED_VERSION" + Write-Host "Reinstall flag: $env:REINSTALL" if (-not $detected) { $decision = 'install' @@ -122,15 +117,15 @@ runs: } else { $decision = 'uninstall-install' } - Log "Decision: $decision" + Write-Host "Decision: $decision" if ($decision -eq 'skip') { - Log 'Skipping installation on Windows (exact version present).' + Write-Host 'Skipping installation on Windows (exact version present).' } else { - Log 'Uninstalling any existing PowerShell…' + Write-Host 'Uninstalling any existing PowerShell…' winget uninstall --id Microsoft.PowerShell -e --silent | Out-Null - Log "Installing PowerShell $env:REQUESTED_VERSION…" + Write-Host "Installing PowerShell $env:REQUESTED_VERSION…" $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest $url -OutFile $msi From f6ff12f5b2bce14420ab621a9e34eca449f4fa0d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:22:14 +0200 Subject: [PATCH 18/52] Refactor action.yml: streamline description formatting, enhance error handling, and improve detected version display for Windows installation. --- action.yml | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/action.yml b/action.yml index ba3596f..0300623 100644 --- a/action.yml +++ b/action.yml @@ -1,7 +1,5 @@ name: Install PowerShell -description: | - Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). - Handles install, downgrade, or forced reinstall. +description: Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Handles install, downgrade, or forced reinstall. author: PSModule branding: icon: terminal @@ -66,6 +64,7 @@ runs: shell: bash run: | set -e + echo "Detecting existing PowerShell on macOS…" DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) echo "Detected version: ${DETECTED_VERSION:-}" @@ -105,15 +104,29 @@ runs: shell: powershell run: | Write-Host "Detecting existing PowerShell on Windows…" - try { $detected = (pwsh -NoLogo -NoProfile -Command "$PSVersionTable.PSVersion.ToString()") } catch { $detected = $null } - Write-Host "Detected version: $($detected ?? '')" + try { + $detected = (pwsh -NoLogo -NoProfile -Command "$PSVersionTable.PSVersion.ToString()") + } catch { + $detected = $null + } + + if ($null -eq $detected -or $detected -eq '') { + $detectedDisplay = '' + } else { + $detectedDisplay = $detected + } + Write-Host "Detected version: $detectedDisplay" Write-Host "Requested version: $env:REQUESTED_VERSION" Write-Host "Reinstall flag: $env:REINSTALL" if (-not $detected) { $decision = 'install' } elseif ($detected -eq $env:REQUESTED_VERSION) { - $decision = ($env:REINSTALL -eq 'true') ? 'reinstall' : 'skip' + if ($env:REINSTALL -eq 'true') { + $decision = 'reinstall' + } else { + $decision = 'skip' + } } else { $decision = 'uninstall-install' } @@ -121,13 +134,12 @@ runs: if ($decision -eq 'skip') { Write-Host 'Skipping installation on Windows (exact version present).' - } - else { + } else { Write-Host 'Uninstalling any existing PowerShell…' winget uninstall --id Microsoft.PowerShell -e --silent | Out-Null Write-Host "Installing PowerShell $env:REQUESTED_VERSION…" $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest $url -OutFile $msi - Start-Process msiexec.exe -ArgumentList "/i", $msi, "/quiet", "/norestart" -Wait + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait } From ba2b99a8c474d9a1ab7f7be4c1123f72be04e4df Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:30:06 +0200 Subject: [PATCH 19/52] Refactor Windows installation: enhance version detection logic, improve error handling, and streamline uninstallation process for existing PowerShell installations. --- action.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/action.yml b/action.yml index 0300623..609bbd6 100644 --- a/action.yml +++ b/action.yml @@ -105,16 +105,12 @@ runs: run: | Write-Host "Detecting existing PowerShell on Windows…" try { - $detected = (pwsh -NoLogo -NoProfile -Command "$PSVersionTable.PSVersion.ToString()") + $detected = (& pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') } catch { $detected = $null } - if ($null -eq $detected -or $detected -eq '') { - $detectedDisplay = '' - } else { - $detectedDisplay = $detected - } + $detectedDisplay = if ([string]::IsNullOrWhiteSpace($detected)) { '' } else { $detected } Write-Host "Detected version: $detectedDisplay" Write-Host "Requested version: $env:REQUESTED_VERSION" Write-Host "Reinstall flag: $env:REINSTALL" @@ -135,11 +131,16 @@ runs: if ($decision -eq 'skip') { Write-Host 'Skipping installation on Windows (exact version present).' } else { - Write-Host 'Uninstalling any existing PowerShell…' - winget uninstall --id Microsoft.PowerShell -e --silent | Out-Null + Write-Host 'Removing existing PowerShell installation (if any)…' + $pwshProducts = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like 'PowerShell*' } + foreach ($p in $pwshProducts) { + Write-Host "Uninstalling $($p.Name)…" + Start-Process msiexec.exe -ArgumentList '/x', $p.IdentifyingNumber, '/quiet', '/norestart' -Wait + } + Write-Host "Installing PowerShell $env:REQUESTED_VERSION…" $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" - Invoke-WebRequest $url -OutFile $msi + Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait } From 662112c498aba7bcbfb5a8efe92d3b0912f90753 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:46:00 +0200 Subject: [PATCH 20/52] Refactor Linux installation: implement APT package manager support for Debian/Ubuntu, enhance error handling, and streamline PowerShell installation process. --- action.yml | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/action.yml b/action.yml index 609bbd6..090605a 100644 --- a/action.yml +++ b/action.yml @@ -42,12 +42,43 @@ runs: if [[ "$DECISION" == "skip" ]]; then echo "Skipping installation on Linux (exact version present)." + exit 0 + fi + + # ------------------------------------------------------------------------------------------------- + # Ubuntu/Debian install via APT package (preferred over legacy GitHub install script) + # ------------------------------------------------------------------------------------------------- + if command -v apt-get >/dev/null; then + echo "Using APT package manager (Debian/Ubuntu)…" + + echo "Ensuring Microsoft package repo is configured…" + if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then + wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null + DIST_CODENAME=$(lsb_release -cs) + sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" + fi + + echo "Updating package index…" + sudo apt-get update -y + + if [[ "$DECISION" != "install" ]]; then + echo "Removing any existing PowerShell packages…" + sudo apt-get remove -y powershell || true + sudo apt-get autoremove -y || true + fi + + echo "Attempting to install exact version $REQUESTED_VERSION from repo…" + EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) + if [[ -n "$EXACT_PKG" ]]; then + sudo apt-get install -y powershell=$EXACT_PKG + else + echo "Exact version not found in repo; installing latest available package instead." + sudo apt-get install -y powershell + fi + else - echo "Uninstalling any existing PowerShell…" - sudo rm -rf /usr/local/microsoft/powershell || true - sudo rm -f /usr/local/bin/pwsh || true - echo "Installing PowerShell $REQUESTED_VERSION…" - curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- -Version "$REQUESTED_VERSION" -Destination /usr/local + echo "Unsupported Linux distribution (no apt-get). PowerShell install via package manager not implemented." + exit 1 fi PWSH_PATH=$(command -v pwsh) @@ -84,10 +115,9 @@ runs: echo "Skipping installation on macOS (exact version present)." else echo "Uninstalling any existing PowerShell…" - sudo rm -rf /usr/local/microsoft/powershell || true - sudo rm -f /usr/local/bin/pwsh || true - echo "Installing PowerShell $REQUESTED_VERSION…" - curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- -Version "$REQUESTED_VERSION" -Destination /usr/local + brew uninstall --ignore-dependencies --force powershell || true + echo "Installing PowerShell $REQUESTED_VERSION via Homebrew…" + brew install --cask powershell@$REQUESTED_VERSION || brew install --cask powershell fi PWSH_PATH=$(command -v pwsh) From 4b3e22eab00ca63477b5862cf5a567faa735176a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 20:55:37 +0200 Subject: [PATCH 21/52] Refactor Debian/Ubuntu installation: update APT package handling to download .deb from GitHub if exact version not found, and improve error handling for macOS installation via Homebrew. --- action.yml | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/action.yml b/action.yml index 090605a..7667980 100644 --- a/action.yml +++ b/action.yml @@ -46,7 +46,7 @@ runs: fi # ------------------------------------------------------------------------------------------------- - # Ubuntu/Debian install via APT package (preferred over legacy GitHub install script) + # Debian/Ubuntu installation # ------------------------------------------------------------------------------------------------- if command -v apt-get >/dev/null; then echo "Using APT package manager (Debian/Ubuntu)…" @@ -72,8 +72,13 @@ runs: if [[ -n "$EXACT_PKG" ]]; then sudo apt-get install -y powershell=$EXACT_PKG else - echo "Exact version not found in repo; installing latest available package instead." - sudo apt-get install -y powershell + echo "Exact version not found in repo; downloading .deb package from GitHub release…" + ARCH=$(dpkg --print-architecture) + DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" + echo "Fetching $URL" + wget -q "$URL" -O "$DEB_NAME" + sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y fi else @@ -81,12 +86,6 @@ runs: exit 1 fi - PWSH_PATH=$(command -v pwsh) - echo "PWSH_PATH=$PWSH_PATH" >> $GITHUB_ENV - echo "PWSH_VERSION=$REQUESTED_VERSION" >> $GITHUB_ENV - echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT - echo "pwsh-version=$REQUESTED_VERSION" >> $GITHUB_OUTPUT - - name: Install PowerShell (macOS) if: runner.os == 'macOS' env: @@ -116,15 +115,20 @@ runs: else echo "Uninstalling any existing PowerShell…" brew uninstall --ignore-dependencies --force powershell || true - echo "Installing PowerShell $REQUESTED_VERSION via Homebrew…" - brew install --cask powershell@$REQUESTED_VERSION || brew install --cask powershell - fi - PWSH_PATH=$(command -v pwsh) - echo "PWSH_PATH=$PWSH_PATH" >> $GITHUB_ENV - echo "PWSH_VERSION=$REQUESTED_VERSION" >> $GITHUB_ENV - echo "pwsh-path=$PWSH_PATH" >> $GITHUB_OUTPUT - echo "pwsh-version=$REQUESTED_VERSION" >> $GITHUB_OUTPUT + echo "Attempting to install PowerShell $REQUESTED_VERSION via Homebrew…" + if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then + brew install --cask powershell@$REQUESTED_VERSION + else + echo "Exact version not available via Homebrew; downloading .pkg from GitHub release…" + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg"; else PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg"; fi + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" + echo "Fetching $URL" + curl -sSL "$URL" -o "$PKG_NAME" + sudo installer -pkg "$PKG_NAME" -target / + fi + fi - name: Install PowerShell (Windows) if: runner.os == 'Windows' From b944f3ffc7f680e11e6aa4d93e744eebe99e0471 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:09:47 +0200 Subject: [PATCH 22/52] Refactor action.yml: standardize ellipsis formatting in echo and Write-Host statements for improved consistency across installation steps. --- action.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/action.yml b/action.yml index 7667980..d59600f 100644 --- a/action.yml +++ b/action.yml @@ -25,7 +25,7 @@ runs: run: | set -e - echo "Detecting existing PowerShell on Linux…" + echo "Detecting existing PowerShell on Linux..." DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) echo "Detected version: ${DETECTED_VERSION:-}" echo "Requested version: $REQUESTED_VERSION" @@ -49,30 +49,30 @@ runs: # Debian/Ubuntu installation # ------------------------------------------------------------------------------------------------- if command -v apt-get >/dev/null; then - echo "Using APT package manager (Debian/Ubuntu)…" + echo "Using APT package manager (Debian/Ubuntu)..." - echo "Ensuring Microsoft package repo is configured…" + echo "Ensuring Microsoft package repo is configured..." if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null DIST_CODENAME=$(lsb_release -cs) sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" fi - echo "Updating package index…" + echo "Updating package index..." sudo apt-get update -y if [[ "$DECISION" != "install" ]]; then - echo "Removing any existing PowerShell packages…" + echo "Removing any existing PowerShell packages..." sudo apt-get remove -y powershell || true sudo apt-get autoremove -y || true fi - echo "Attempting to install exact version $REQUESTED_VERSION from repo…" + echo "Attempting to install exact version $REQUESTED_VERSION from repo..." EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) if [[ -n "$EXACT_PKG" ]]; then sudo apt-get install -y powershell=$EXACT_PKG else - echo "Exact version not found in repo; downloading .deb package from GitHub release…" + echo "Exact version not found in repo; downloading .deb package from GitHub release..." ARCH=$(dpkg --print-architecture) DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" @@ -95,7 +95,7 @@ runs: run: | set -e - echo "Detecting existing PowerShell on macOS…" + echo "Detecting existing PowerShell on macOS..." DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) echo "Detected version: ${DETECTED_VERSION:-}" echo "Requested version: $REQUESTED_VERSION" @@ -113,14 +113,14 @@ runs: if [[ "$DECISION" == "skip" ]]; then echo "Skipping installation on macOS (exact version present)." else - echo "Uninstalling any existing PowerShell…" + echo "Uninstalling any existing PowerShell..." brew uninstall --ignore-dependencies --force powershell || true - echo "Attempting to install PowerShell $REQUESTED_VERSION via Homebrew…" + echo "Attempting to install PowerShell $REQUESTED_VERSION via Homebrew..." if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then brew install --cask powershell@$REQUESTED_VERSION else - echo "Exact version not available via Homebrew; downloading .pkg from GitHub release…" + echo "Exact version not available via Homebrew; downloading .pkg from GitHub release..." ARCH=$(uname -m) if [[ "$ARCH" == "arm64" ]]; then PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg"; else PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg"; fi URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" @@ -137,7 +137,7 @@ runs: REINSTALL: ${{ inputs.Reinstall }} shell: powershell run: | - Write-Host "Detecting existing PowerShell on Windows…" + Write-Host "Detecting existing PowerShell on Windows..." try { $detected = (& pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') } catch { @@ -165,14 +165,14 @@ runs: if ($decision -eq 'skip') { Write-Host 'Skipping installation on Windows (exact version present).' } else { - Write-Host 'Removing existing PowerShell installation (if any)…' + Write-Host 'Removing existing PowerShell installation (if any)...' $pwshProducts = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like 'PowerShell*' } foreach ($p in $pwshProducts) { - Write-Host "Uninstalling $($p.Name)…" + Write-Host "Uninstalling $($p.Name)..." Start-Process msiexec.exe -ArgumentList '/x', $p.IdentifyingNumber, '/quiet', '/norestart' -Wait } - Write-Host "Installing PowerShell $env:REQUESTED_VERSION…" + Write-Host "Installing PowerShell $env:REQUESTED_VERSION..." $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing From 102f5df930b51e298e6cb604d5673f05c5ba31b6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:11:55 +0200 Subject: [PATCH 23/52] Refactor Action-Test.yml and action.yml: update version matrix for testing, streamline installation logic, and enhance version detection for PowerShell installations. --- .github/workflows/Action-Test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 098d9fd..87f750e 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -22,9 +22,9 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - version: ['7.4.0', '7.5.0'] # Specify the versions to test - name: Action-Test - [Basic] + version: ['7.2.0', '7.4.0', '7.4.7', '7.5.0'] runs-on: ${{ matrix.os }} + name: ${{ matrix.os }} - ${{ matrix.version }} steps: # Need to check out as part of the test, as its a local action - name: Checkout repo From 630dd6aef24c02589629481432b89dcdfce52c83 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:12:09 +0200 Subject: [PATCH 24/52] remove uninstall --- action.yml | 125 +++++++++-------------------------------------------- 1 file changed, 21 insertions(+), 104 deletions(-) diff --git a/action.yml b/action.yml index d59600f..289a3aa 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ name: Install PowerShell -description: Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Handles install, downgrade, or forced reinstall. +description: Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Installs only when the requested version is not already present. author: PSModule branding: icon: terminal @@ -9,9 +9,6 @@ inputs: Version: description: Exact PowerShell version to install (e.g. 7.4.1) required: true - Reinstall: - description: Set to 'true' to uninstall & reinstall even when the exact version is already present. - default: 'false' runs: using: composite @@ -20,69 +17,37 @@ runs: if: runner.os == 'Linux' env: REQUESTED_VERSION: ${{ inputs.Version }} - REINSTALL: ${{ inputs.Reinstall }} shell: bash run: | set -e - - echo "Detecting existing PowerShell on Linux..." DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - echo "Detected version: ${DETECTED_VERSION:-}" - echo "Requested version: $REQUESTED_VERSION" - echo "Reinstall flag: $REINSTALL" - - if [[ -z "$DETECTED_VERSION" ]]; then - DECISION="install" - elif [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then - if [[ "$REINSTALL" == "true" ]]; then DECISION="reinstall"; else DECISION="skip"; fi - else - DECISION="uninstall-install" # covers downgrade or upgrade - fi - echo "Decision: $DECISION" - - if [[ "$DECISION" == "skip" ]]; then - echo "Skipping installation on Linux (exact version present)." + if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + echo "PowerShell $DETECTED_VERSION already installed. Skipping." exit 0 fi - # ------------------------------------------------------------------------------------------------- - # Debian/Ubuntu installation - # ------------------------------------------------------------------------------------------------- if command -v apt-get >/dev/null; then echo "Using APT package manager (Debian/Ubuntu)..." - echo "Ensuring Microsoft package repo is configured..." if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null DIST_CODENAME=$(lsb_release -cs) sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" fi - echo "Updating package index..." sudo apt-get update -y - - if [[ "$DECISION" != "install" ]]; then - echo "Removing any existing PowerShell packages..." - sudo apt-get remove -y powershell || true - sudo apt-get autoremove -y || true - fi - - echo "Attempting to install exact version $REQUESTED_VERSION from repo..." EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) if [[ -n "$EXACT_PKG" ]]; then sudo apt-get install -y powershell=$EXACT_PKG else - echo "Exact version not found in repo; downloading .deb package from GitHub release..." ARCH=$(dpkg --print-architecture) DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" - echo "Fetching $URL" wget -q "$URL" -O "$DEB_NAME" sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y fi - else - echo "Unsupported Linux distribution (no apt-get). PowerShell install via package manager not implemented." + echo "Unsupported Linux distribution (no apt-get)." exit 1 fi @@ -90,91 +55,43 @@ runs: if: runner.os == 'macOS' env: REQUESTED_VERSION: ${{ inputs.Version }} - REINSTALL: ${{ inputs.Reinstall }} shell: bash run: | set -e - - echo "Detecting existing PowerShell on macOS..." DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - echo "Detected version: ${DETECTED_VERSION:-}" - echo "Requested version: $REQUESTED_VERSION" - echo "Reinstall flag: $REINSTALL" - - if [[ -z "$DETECTED_VERSION" ]]; then - DECISION="install" - elif [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then - if [[ "$REINSTALL" == "true" ]]; then DECISION="reinstall"; else DECISION="skip"; fi - else - DECISION="uninstall-install" + if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + echo "PowerShell $DETECTED_VERSION already installed. Skipping." + exit 0 fi - echo "Decision: $DECISION" - if [[ "$DECISION" == "skip" ]]; then - echo "Skipping installation on macOS (exact version present)." + if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then + brew install --cask powershell@$REQUESTED_VERSION else - echo "Uninstalling any existing PowerShell..." - brew uninstall --ignore-dependencies --force powershell || true - - echo "Attempting to install PowerShell $REQUESTED_VERSION via Homebrew..." - if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then - brew install --cask powershell@$REQUESTED_VERSION - else - echo "Exact version not available via Homebrew; downloading .pkg from GitHub release..." - ARCH=$(uname -m) - if [[ "$ARCH" == "arm64" ]]; then PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg"; else PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg"; fi - URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" - echo "Fetching $URL" - curl -sSL "$URL" -o "$PKG_NAME" - sudo installer -pkg "$PKG_NAME" -target / - fi + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg"; else PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg"; fi + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" + curl -sSL "$URL" -o "$PKG_NAME" + sudo installer -pkg "$PKG_NAME" -target / fi - name: Install PowerShell (Windows) if: runner.os == 'Windows' env: REQUESTED_VERSION: ${{ inputs.Version }} - REINSTALL: ${{ inputs.Reinstall }} shell: powershell run: | - Write-Host "Detecting existing PowerShell on Windows..." try { $detected = (& pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') } catch { $detected = $null } - $detectedDisplay = if ([string]::IsNullOrWhiteSpace($detected)) { '' } else { $detected } - Write-Host "Detected version: $detectedDisplay" - Write-Host "Requested version: $env:REQUESTED_VERSION" - Write-Host "Reinstall flag: $env:REINSTALL" - - if (-not $detected) { - $decision = 'install' - } elseif ($detected -eq $env:REQUESTED_VERSION) { - if ($env:REINSTALL -eq 'true') { - $decision = 'reinstall' - } else { - $decision = 'skip' - } - } else { - $decision = 'uninstall-install' + if ($detected -eq $env:REQUESTED_VERSION) { + Write-Host "PowerShell $detected already installed. Skipping." + exit 0 } - Write-Host "Decision: $decision" - if ($decision -eq 'skip') { - Write-Host 'Skipping installation on Windows (exact version present).' - } else { - Write-Host 'Removing existing PowerShell installation (if any)...' - $pwshProducts = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like 'PowerShell*' } - foreach ($p in $pwshProducts) { - Write-Host "Uninstalling $($p.Name)..." - Start-Process msiexec.exe -ArgumentList '/x', $p.IdentifyingNumber, '/quiet', '/norestart' -Wait - } - - Write-Host "Installing PowerShell $env:REQUESTED_VERSION..." - $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" - $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" - Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait - } + $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" + $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" + Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait From e924d13dfaf2328621ed6796d5d3e67f0d1be84b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:18:02 +0200 Subject: [PATCH 25/52] Refactor Action-Test.yml: update version matrix to remove deprecated version 7.2.0 --- .github/workflows/Action-Test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 87f750e..321c6d4 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - version: ['7.2.0', '7.4.0', '7.4.7', '7.5.0'] + version: ['7.4.0', '7.4.7', '7.5.0'] runs-on: ${{ matrix.os }} name: ${{ matrix.os }} - ${{ matrix.version }} steps: From d13e05c1e255236789767668ac4f8a33075e5352 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:22:31 +0200 Subject: [PATCH 26/52] Refactor action.yml: improve PowerShell version detection logic and enhance output messaging for clarity --- action.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 289a3aa..22a2b67 100644 --- a/action.yml +++ b/action.yml @@ -81,11 +81,13 @@ runs: shell: powershell run: | try { - $detected = (& pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') + $detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') } catch { $detected = $null } + Write-Host "Detected PowerShell version: $detected" + if ($detected -eq $env:REQUESTED_VERSION) { Write-Host "PowerShell $detected already installed. Skipping." exit 0 From e4428e1d67879871eeb637bf7170cb4f2c066e6e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:29:40 +0200 Subject: [PATCH 27/52] Enhance output messaging: add requested PowerShell version to installation logs for better clarity --- action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/action.yml b/action.yml index 22a2b67..d9fa221 100644 --- a/action.yml +++ b/action.yml @@ -87,6 +87,7 @@ runs: } Write-Host "Detected PowerShell version: $detected" + Write-Host "Requested PowerShell version: $env:REQUESTED_VERSION" if ($detected -eq $env:REQUESTED_VERSION) { Write-Host "PowerShell $detected already installed. Skipping." From 1588830a554af4c2ef747f30907f9b2e607a44b1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 21:46:29 +0200 Subject: [PATCH 28/52] Enhance Windows installation: add '/force' argument to msiexec for PowerShell installation --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index d9fa221..4c045f4 100644 --- a/action.yml +++ b/action.yml @@ -97,4 +97,4 @@ runs: $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart', '/force' -Wait From 82866d535d8ee12a82cd00ccc0b8d9f05ee2342b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:06:15 +0200 Subject: [PATCH 29/52] Fix Windows installation: add 'REINSTALL=ALL' argument to msiexec for proper reinstallation --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 4c045f4..19b91e4 100644 --- a/action.yml +++ b/action.yml @@ -97,4 +97,4 @@ runs: $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart', '/force' -Wait + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart', 'REINSTALL=ALL' -Wait From 34bc667c274b29d0b828c535eefbda503f82a911 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:11:11 +0200 Subject: [PATCH 30/52] Fix Windows installation: correct msiexec argument formatting for proper reinstallation --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 19b91e4..c342b2e 100644 --- a/action.yml +++ b/action.yml @@ -97,4 +97,4 @@ runs: $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart', 'REINSTALL=ALL' -Wait + Start-Process msiexec.exe -ArgumentList '/i $msi REINSTALL=ALL /quiet /norestart' -Wait From 47cf60726164b30f00810f975aac825831c316a5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:15:01 +0200 Subject: [PATCH 31/52] Fix Windows installation: simplify msiexec command by removing Start-Process --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index c342b2e..54d7309 100644 --- a/action.yml +++ b/action.yml @@ -97,4 +97,4 @@ runs: $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i $msi REINSTALL=ALL /quiet /norestart' -Wait + msiexec.exe /i $msi REINSTALL=ALL /quiet /norestart From 6db690c556ad282d439c12af2f97a7cc8cada9d9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:20:26 +0200 Subject: [PATCH 32/52] Fix Windows installation: update msiexec command to use Start-Process for better execution control --- .github/workflows/Action-Test.yml | 2 +- action.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 321c6d4..3b9fc11 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - version: ['7.4.0', '7.4.7', '7.5.0'] + version: ['', '7.4.7', '7.5.0'] runs-on: ${{ matrix.os }} name: ${{ matrix.os }} - ${{ matrix.version }} steps: diff --git a/action.yml b/action.yml index 54d7309..d9fa221 100644 --- a/action.yml +++ b/action.yml @@ -97,4 +97,4 @@ runs: $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - msiexec.exe /i $msi REINSTALL=ALL /quiet /norestart + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait From a7729636921525694a97b7f90bbf9f4d32e28363 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:27:31 +0200 Subject: [PATCH 33/52] Refactor PowerShell installation: enhance version resolution and improve error handling for Linux and macOS; update Windows installation process to ensure proper version detection and installation. --- action.yml | 196 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 117 insertions(+), 79 deletions(-) diff --git a/action.yml b/action.yml index d9fa221..dfe2ab5 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,8 @@ name: Install PowerShell -description: Install a specific version of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Installs only when the requested version is not already present. +description: >- + Install a specific version —or the latest stable version— of PowerShell Core + on any GitHub runner (Linux, macOS, Windows). + Skips the install if the requested version is already present. author: PSModule branding: icon: terminal @@ -7,94 +10,129 @@ branding: inputs: Version: - description: Exact PowerShell version to install (e.g. 7.4.1) - required: true + description: >- + PowerShell version to install (`7.4.1`, `7.3.10`, or `latest` for the + newest stable release). + Defaults to **latest**. + required: false + default: latest runs: using: composite steps: - - name: Install PowerShell (Linux) - if: runner.os == 'Linux' - env: - REQUESTED_VERSION: ${{ inputs.Version }} - shell: bash - run: | - set -e - DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then - echo "PowerShell $DETECTED_VERSION already installed. Skipping." - exit 0 + - name: Install PowerShell (Linux) + if: runner.os == 'Linux' + shell: bash + env: + REQUESTED_VERSION: ${{ inputs.Version }} + run: | + set -e + + # Resolve "latest" to a concrete version number (e.g. 7.4.1) + if [[ -z "$REQUESTED_VERSION" || "$REQUESTED_VERSION" == "latest" ]]; then + REQUESTED_VERSION=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ + | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//') + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" + fi + + DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) + if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + echo "PowerShell $DETECTED_VERSION already installed. Skipping." + exit 0 + fi + + if command -v apt-get >/dev/null; then + echo "Using APT package manager (Debian/Ubuntu)…" + + if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then + wget -qO- https://packages.microsoft.com/keys/microsoft.asc \ + | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null + DIST_CODENAME=$(lsb_release -cs) + sudo add-apt-repository \ + "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" fi - if command -v apt-get >/dev/null; then - echo "Using APT package manager (Debian/Ubuntu)..." - - if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then - wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null - DIST_CODENAME=$(lsb_release -cs) - sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" - fi - - sudo apt-get update -y - EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) - if [[ -n "$EXACT_PKG" ]]; then - sudo apt-get install -y powershell=$EXACT_PKG - else - ARCH=$(dpkg --print-architecture) - DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" - URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" - wget -q "$URL" -O "$DEB_NAME" - sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y - fi + sudo apt-get update -y + EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' \ + | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) + + if [[ -n "$EXACT_PKG" ]]; then + sudo apt-get install -y powershell=$EXACT_PKG else - echo "Unsupported Linux distribution (no apt-get)." - exit 1 + ARCH=$(dpkg --print-architecture) + DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" + wget -q "$URL" -O "$DEB_NAME" + sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y fi + else + echo "Unsupported Linux distribution (no apt-get)." + exit 1 + fi - - name: Install PowerShell (macOS) - if: runner.os == 'macOS' - env: - REQUESTED_VERSION: ${{ inputs.Version }} - shell: bash - run: | - set -e - DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then - echo "PowerShell $DETECTED_VERSION already installed. Skipping." - exit 0 - fi + - name: Install PowerShell (macOS) + if: runner.os == 'macOS' + shell: bash + env: + REQUESTED_VERSION: ${{ inputs.Version }} + run: | + set -e - if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then - brew install --cask powershell@$REQUESTED_VERSION + # Resolve "latest" to concrete version number + if [[ -z "$REQUESTED_VERSION" || "$REQUESTED_VERSION" == "latest" ]]; then + REQUESTED_VERSION=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ + | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//') + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" + fi + + DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) + if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + echo "PowerShell $DETECTED_VERSION already installed. Skipping." + exit 0 + fi + + if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then + brew install --cask powershell@$REQUESTED_VERSION + else + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then + PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" else - ARCH=$(uname -m) - if [[ "$ARCH" == "arm64" ]]; then PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg"; else PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg"; fi - URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" - curl -sSL "$URL" -o "$PKG_NAME" - sudo installer -pkg "$PKG_NAME" -target / + PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg" fi + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" + curl -sSL "$URL" -o "$PKG_NAME" + sudo installer -pkg "$PKG_NAME" -target / + fi + + - name: Install PowerShell (Windows) + if: runner.os == 'Windows' + shell: powershell + env: + REQUESTED_VERSION: ${{ inputs.Version }} + run: | + # Resolve "latest" to concrete version number + if (-not $env:REQUESTED_VERSION -or $env:REQUESTED_VERSION -eq 'latest') { + $latest = (Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest').tag_name.TrimStart('v') + Write-Host "Latest stable PowerShell release detected: $latest" + $env:REQUESTED_VERSION = $latest + } + + try { + $detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') + } catch { + $detected = $null + } + + Write-Host "Detected PowerShell version: $detected" + Write-Host "Requested PowerShell version: $env:REQUESTED_VERSION" + + if ($detected -eq $env:REQUESTED_VERSION) { + Write-Host "PowerShell $detected already installed. Skipping." + exit 0 + } - - name: Install PowerShell (Windows) - if: runner.os == 'Windows' - env: - REQUESTED_VERSION: ${{ inputs.Version }} - shell: powershell - run: | - try { - $detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') - } catch { - $detected = $null - } - - Write-Host "Detected PowerShell version: $detected" - Write-Host "Requested PowerShell version: $env:REQUESTED_VERSION" - - if ($detected -eq $env:REQUESTED_VERSION) { - Write-Host "PowerShell $detected already installed. Skipping." - exit 0 - } - - $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" - $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" - Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait + $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" + $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" + Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait From 4d59103418a8081c74d86a99bcf81836a6f7e243 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:33:57 +0200 Subject: [PATCH 34/52] Refactor PowerShell installation: improve version resolution logic for Linux, macOS, and Windows; enhance handling of empty and 'null' inputs for requested version. --- action.yml | 241 ++++++++++++++++++++++++++++------------------------- 1 file changed, 126 insertions(+), 115 deletions(-) diff --git a/action.yml b/action.yml index dfe2ab5..050e9d3 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ name: Install PowerShell -description: >- +description: > Install a specific version —or the latest stable version— of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Skips the install if the requested version is already present. @@ -10,129 +10,140 @@ branding: inputs: Version: - description: >- - PowerShell version to install (`7.4.1`, `7.3.10`, or `latest` for the - newest stable release). - Defaults to **latest**. + description: > + PowerShell version to install (e.g. `7.4.1`). + Use `latest`, `null`, leave it **empty**, or omit the input entirely + to grab the newest stable release automatically. required: false - default: latest + default: '' # Empty string → newest release runs: using: composite steps: - - name: Install PowerShell (Linux) - if: runner.os == 'Linux' - shell: bash - env: - REQUESTED_VERSION: ${{ inputs.Version }} - run: | - set -e - - # Resolve "latest" to a concrete version number (e.g. 7.4.1) - if [[ -z "$REQUESTED_VERSION" || "$REQUESTED_VERSION" == "latest" ]]; then - REQUESTED_VERSION=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ - | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//') - echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - fi - - DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then - echo "PowerShell $DETECTED_VERSION already installed. Skipping." - exit 0 - fi - - if command -v apt-get >/dev/null; then - echo "Using APT package manager (Debian/Ubuntu)…" - - if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then - wget -qO- https://packages.microsoft.com/keys/microsoft.asc \ - | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null - DIST_CODENAME=$(lsb_release -cs) - sudo add-apt-repository \ - "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" + - name: Install PowerShell (Linux) + if: runner.os == 'Linux' + shell: bash + env: + REQUESTED_VERSION: ${{ inputs.Version }} + run: | + set -e + + # Resolve empty / 'null' / 'latest' to a concrete version number + if [[ -z "$REQUESTED_VERSION" || \ + "${REQUESTED_VERSION,,}" == "latest" || \ + "${REQUESTED_VERSION,,}" == "null" ]]; then + REQUESTED_VERSION=$( + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ + | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//' + ) + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" fi - sudo apt-get update -y - EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' \ - | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) + DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) + if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + echo "PowerShell $DETECTED_VERSION already installed. Skipping." + exit 0 + fi - if [[ -n "$EXACT_PKG" ]]; then - sudo apt-get install -y powershell=$EXACT_PKG + if command -v apt-get >/dev/null; then + echo "Using APT package manager (Debian/Ubuntu)…" + + if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then + wget -qO- https://packages.microsoft.com/keys/microsoft.asc \ + | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc > /dev/null + DIST_CODENAME=$(lsb_release -cs) + sudo add-apt-repository \ + "deb [arch=$(dpkg --print-architecture)] https://packages.microsoft.com/ubuntu/$DIST_CODENAME/prod $DIST_CODENAME main" + fi + + sudo apt-get update -y + EXACT_PKG=$(apt-cache madison powershell | awk '{print $3}' \ + | grep -E "^${REQUESTED_VERSION}(-|$)" | head -n1 || true) + + if [[ -n "$EXACT_PKG" ]]; then + sudo apt-get install -y powershell=$EXACT_PKG + else + ARCH=$(dpkg --print-architecture) + DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" + wget -q "$URL" -O "$DEB_NAME" + sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y + fi else - ARCH=$(dpkg --print-architecture) - DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb" - URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}" - wget -q "$URL" -O "$DEB_NAME" - sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y + echo "Unsupported Linux distribution (no apt-get)." + exit 1 + fi + + - name: Install PowerShell (macOS) + if: runner.os == 'macOS' + shell: bash + env: + REQUESTED_VERSION: ${{ inputs.Version }} + run: | + set -e + + # Resolve empty / 'null' / 'latest' to a concrete version number + if [[ -z "$REQUESTED_VERSION" || \ + "${REQUESTED_VERSION,,}" == "latest" || \ + "${REQUESTED_VERSION,,}" == "null" ]]; then + REQUESTED_VERSION=$( + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ + | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//' + ) + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" fi - else - echo "Unsupported Linux distribution (no apt-get)." - exit 1 - fi - - - name: Install PowerShell (macOS) - if: runner.os == 'macOS' - shell: bash - env: - REQUESTED_VERSION: ${{ inputs.Version }} - run: | - set -e - - # Resolve "latest" to concrete version number - if [[ -z "$REQUESTED_VERSION" || "$REQUESTED_VERSION" == "latest" ]]; then - REQUESTED_VERSION=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ - | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//') - echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - fi - - DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) - if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then - echo "PowerShell $DETECTED_VERSION already installed. Skipping." - exit 0 - fi - - if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then - brew install --cask powershell@$REQUESTED_VERSION - else - ARCH=$(uname -m) - if [[ "$ARCH" == "arm64" ]]; then - PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" + + DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) + if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then + echo "PowerShell $DETECTED_VERSION already installed. Skipping." + exit 0 + fi + + if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then + brew install --cask powershell@$REQUESTED_VERSION else - PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg" + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then + PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" + else + PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg" + fi + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" + curl -sSL "$URL" -o "$PKG_NAME" + sudo installer -pkg "$PKG_NAME" -target / fi - URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" - curl -sSL "$URL" -o "$PKG_NAME" - sudo installer -pkg "$PKG_NAME" -target / - fi - - - name: Install PowerShell (Windows) - if: runner.os == 'Windows' - shell: powershell - env: - REQUESTED_VERSION: ${{ inputs.Version }} - run: | - # Resolve "latest" to concrete version number - if (-not $env:REQUESTED_VERSION -or $env:REQUESTED_VERSION -eq 'latest') { - $latest = (Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest').tag_name.TrimStart('v') - Write-Host "Latest stable PowerShell release detected: $latest" - $env:REQUESTED_VERSION = $latest - } - - try { - $detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') - } catch { - $detected = $null - } - - Write-Host "Detected PowerShell version: $detected" - Write-Host "Requested PowerShell version: $env:REQUESTED_VERSION" - - if ($detected -eq $env:REQUESTED_VERSION) { - Write-Host "PowerShell $detected already installed. Skipping." - exit 0 - } - - $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" - $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" - Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing - Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait + + - name: Install PowerShell (Windows) + if: runner.os == 'Windows' + shell: powershell + env: + REQUESTED_VERSION: ${{ inputs.Version }} + run: | + # Resolve empty / 'null' / 'latest' to a concrete version number + $req = $env:REQUESTED_VERSION + if ([string]::IsNullOrWhiteSpace($req) -or + ($req.Trim().ToLower() -in @('latest','null'))) { + + $latest = (Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest').tag_name.TrimStart('v') + Write-Host "Latest stable PowerShell release detected: $latest" + $env:REQUESTED_VERSION = $latest + } + + try { + $detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()') + } catch { + $detected = $null + } + + Write-Host "Detected PowerShell version: $detected" + Write-Host "Requested PowerShell version: $env:REQUESTED_VERSION" + + if ($detected -eq $env:REQUESTED_VERSION) { + Write-Host "PowerShell $detected already installed. Skipping." + exit 0 + } + + $msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi" + $url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi" + Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing + Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait From eea5f4db7b9857ae9b6775fad4e74baf862913b1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:34:17 +0200 Subject: [PATCH 35/52] Fix formatting in PowerShell version input description for consistency --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 050e9d3..3b8f2f5 100644 --- a/action.yml +++ b/action.yml @@ -11,7 +11,7 @@ branding: inputs: Version: description: > - PowerShell version to install (e.g. `7.4.1`). + PowerShell version to install (e.g. `7.4.1`). Use `latest`, `null`, leave it **empty**, or omit the input entirely to grab the newest stable release automatically. required: false From a5f659757df1b534da244759d53fbb5b124b3a0d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:42:12 +0200 Subject: [PATCH 36/52] Refactor Action-Test workflow: enhance version matrix to include 'null' and 'latest'; improve version verification logic for better clarity and error handling. --- .github/workflows/Action-Test.yml | 33 ++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 3b9fc11..70bc63c 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -22,23 +22,42 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - version: ['', '7.4.7', '7.5.0'] + version: ['', null, 'latest', '7.4.7', '7.5.0'] # '' → should resolve to latest runs-on: ${{ matrix.os }} - name: ${{ matrix.os }} - ${{ matrix.version }} + name: ${{ matrix.os }} - ${{ matrix.version == '' && 'latest' || matrix.version }} steps: - # Need to check out as part of the test, as its a local action + # 1. Checkout the repo so the local action is available - name: Checkout repo uses: actions/checkout@v4 + # 2. Run the action under test - name: Action-Test uses: ./ with: Version: ${{ matrix.version }} - - name: Test version + # 3. Verify the installed PowerShell version + - name: Verify installed version shell: pwsh run: | - $PSVersionTable | Format-Table -AutoSize - if ($PSVersionTable.PSVersion -ne '${{ matrix.version }}') { - throw "Failed to install the expected version" + # Requested version that came from the matrix + $requested = '${{ matrix.version }}' + + # When empty / 'null' / 'latest' → resolve to latest stable release + if ([string]::IsNullOrWhiteSpace($requested) -or + $requested.Trim().ToLower() -in @('latest','null')) { + + $requested = (Invoke-RestMethod ` + -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' + ).tag_name.TrimStart('v') + Write-Host "Resolved 'latest' → $requested" + } + + # Actual version installed by the action + $installed = ($PSVersionTable.PSVersion).ToString() + Write-Host "Installed PowerShell version: $installed" + Write-Host "Expected PowerShell version: $requested" + + if ($installed -ne $requested) { + throw "Failed: expected $requested but got $installed" } From 985f7da055e318be435843a10b4248740c5d8d55 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:50:37 +0200 Subject: [PATCH 37/52] Refactor Action-Test workflow: update job name formatting for clarity; improve input description consistency in action.yml --- .github/workflows/Action-Test.yml | 2 +- action.yml | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 70bc63c..df18acb 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -24,7 +24,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] version: ['', null, 'latest', '7.4.7', '7.5.0'] # '' → should resolve to latest runs-on: ${{ matrix.os }} - name: ${{ matrix.os }} - ${{ matrix.version == '' && 'latest' || matrix.version }} + name: '${{ matrix.os }} - [${{ matrix.version }}]' steps: # 1. Checkout the repo so the local action is available - name: Checkout repo diff --git a/action.yml b/action.yml index 3b8f2f5..d13e7c4 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ name: Install PowerShell description: > - Install a specific version —or the latest stable version— of PowerShell Core + Install a specific version —or the latest stable version— of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Skips the install if the requested version is already present. author: PSModule @@ -15,7 +15,7 @@ inputs: Use `latest`, `null`, leave it **empty**, or omit the input entirely to grab the newest stable release automatically. required: false - default: '' # Empty string → newest release + default: '' runs: using: composite @@ -29,9 +29,8 @@ runs: set -e # Resolve empty / 'null' / 'latest' to a concrete version number - if [[ -z "$REQUESTED_VERSION" || \ - "${REQUESTED_VERSION,,}" == "latest" || \ - "${REQUESTED_VERSION,,}" == "null" ]]; then + lower_req="$(printf '%s' "$REQUESTED_VERSION" | tr '[:upper:]' '[:lower:]')" + if [[ -z "$REQUESTED_VERSION" || "$lower_req" == "latest" || "$lower_req" == "null" ]]; then REQUESTED_VERSION=$( curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//' @@ -83,9 +82,8 @@ runs: set -e # Resolve empty / 'null' / 'latest' to a concrete version number - if [[ -z "$REQUESTED_VERSION" || \ - "${REQUESTED_VERSION,,}" == "latest" || \ - "${REQUESTED_VERSION,,}" == "null" ]]; then + lower_req="$(printf '%s' "$REQUESTED_VERSION" | tr '[:upper:]' '[:lower:]')" + if [[ -z "$REQUESTED_VERSION" || "$lower_req" == "latest" || "$lower_req" == "null" ]]; then REQUESTED_VERSION=$( curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//' From 948a17920264972aaaf3674a09f870039346cbea Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 22:59:54 +0200 Subject: [PATCH 38/52] Refactor PowerShell installation: improve logic for fetching the latest stable release version; enhance command for better reliability and clarity. --- action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index d13e7c4..ae0efa6 100644 --- a/action.yml +++ b/action.yml @@ -85,8 +85,8 @@ runs: lower_req="$(printf '%s' "$REQUESTED_VERSION" | tr '[:upper:]' '[:lower:]')" if [[ -z "$REQUESTED_VERSION" || "$lower_req" == "latest" || "$lower_req" == "null" ]]; then REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ - | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//' + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + grep '"tag_name"' | head -n1 | sed -E 's/.*"v?([^"]+)".*/\1/' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" fi From 45bce542d69a63f07755eadf7114476faad5c8d5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 23:07:16 +0200 Subject: [PATCH 39/52] Refactor PowerShell installation: streamline version resolution logic for empty, 'null', and 'latest' inputs; enhance readability of the code. --- action.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/action.yml b/action.yml index ae0efa6..5f42b44 100644 --- a/action.yml +++ b/action.yml @@ -81,15 +81,16 @@ runs: run: | set -e - # Resolve empty / 'null' / 'latest' to a concrete version number - lower_req="$(printf '%s' "$REQUESTED_VERSION" | tr '[:upper:]' '[:lower:]')" - if [[ -z "$REQUESTED_VERSION" || "$lower_req" == "latest" || "$lower_req" == "null" ]]; then - REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | - grep '"tag_name"' | head -n1 | sed -E 's/.*"v?([^"]+)".*/\1/' - ) - echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - fi + case "${REQUESTED_VERSION:-}" in + "" | [Ll][Aa][Tt][Ee][Ss][Tt] | [Nn][Uu][Ll][Ll]) + REQUESTED_VERSION=$( + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + grep '"tag_name"' | head -n1 | + sed -E 's/.*"v?([^"]+)".*/\1/' + ) + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" + ;; + esac DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then From ddd52b1633177623a81fad1903bff62bd8130b2d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 23:21:03 +0200 Subject: [PATCH 40/52] Refactor PowerShell installation: improve comments for clarity; standardize version resolution logic across platforms. --- action.yml | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/action.yml b/action.yml index 5f42b44..20b1d66 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ name: Install PowerShell description: > - Install a specific version —or the latest stable version— of PowerShell Core + Install a specific version —or the latest stable version— of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Skips the install if the requested version is already present. author: PSModule @@ -15,7 +15,7 @@ inputs: Use `latest`, `null`, leave it **empty**, or omit the input entirely to grab the newest stable release automatically. required: false - default: '' + default: '' # Empty string → newest release runs: using: composite @@ -28,15 +28,17 @@ runs: run: | set -e - # Resolve empty / 'null' / 'latest' to a concrete version number - lower_req="$(printf '%s' "$REQUESTED_VERSION" | tr '[:upper:]' '[:lower:]')" - if [[ -z "$REQUESTED_VERSION" || "$lower_req" == "latest" || "$lower_req" == "null" ]]; then - REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ - | grep -oP '"tag_name":\s*"\K([^"]+)' | sed 's/^v//' - ) - echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - fi + # Resolve "" / null / latest → concrete latest version (Bash‑3 safe) + case "${REQUESTED_VERSION:-}" in + ""|[Ll][Aa][Tt][Ee][Ss][Tt]|[Nn][Uu][Ll][Ll]|~) + REQUESTED_VERSION=$( + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + grep '"tag_name"' | head -n1 | + sed -E 's/.*"v?([^"]+)".*/\1/' + ) + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" + ;; + esac DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then @@ -81,15 +83,16 @@ runs: run: | set -e + # Resolve "" / null / latest → concrete latest version (Bash‑3 safe) case "${REQUESTED_VERSION:-}" in - "" | [Ll][Aa][Tt][Ee][Ss][Tt] | [Nn][Uu][Ll][Ll]) - REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | - grep '"tag_name"' | head -n1 | - sed -E 's/.*"v?([^"]+)".*/\1/' - ) - echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - ;; + ""|[Ll][Aa][Tt][Ee][Ss][Tt]|[Nn][Uu][Ll][Ll]|~) + REQUESTED_VERSION=$( + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + grep '"tag_name"' | head -n1 | + sed -E 's/.*"v?([^"]+)".*/\1/' + ) + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" + ;; esac DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) @@ -118,10 +121,10 @@ runs: env: REQUESTED_VERSION: ${{ inputs.Version }} run: | - # Resolve empty / 'null' / 'latest' to a concrete version number + # Resolve "" / null / latest → concrete latest version $req = $env:REQUESTED_VERSION if ([string]::IsNullOrWhiteSpace($req) -or - ($req.Trim().ToLower() -in @('latest','null'))) { + $req.Trim().ToLower() -in @('latest','null','~')) { $latest = (Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest').tag_name.TrimStart('v') Write-Host "Latest stable PowerShell release detected: $latest" From d026fe575cb7dcdee59ae81fc99054ccc02cc1e5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 23:43:44 +0200 Subject: [PATCH 41/52] Refactor PowerShell installation: correct APT package manager message; streamline version resolution logic and add validation for requested version. --- action.yml | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/action.yml b/action.yml index 20b1d66..9931412 100644 --- a/action.yml +++ b/action.yml @@ -47,7 +47,7 @@ runs: fi if command -v apt-get >/dev/null; then - echo "Using APT package manager (Debian/Ubuntu)…" + echo "Using APT package manager (Debian/Ubuntu)..." if ! grep -q "packages.microsoft.com" /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null; then wget -qO- https://packages.microsoft.com/keys/microsoft.asc \ @@ -83,17 +83,21 @@ runs: run: | set -e - # Resolve "" / null / latest → concrete latest version (Bash‑3 safe) - case "${REQUESTED_VERSION:-}" in - ""|[Ll][Aa][Tt][Ee][Ss][Tt]|[Nn][Uu][Ll][Ll]|~) - REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | - grep '"tag_name"' | head -n1 | - sed -E 's/.*"v?([^"]+)".*/\1/' - ) - echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - ;; - esac + # Resolve "" / null / latest → concrete latest version + if [[ -z "${REQUESTED_VERSION}" || "${REQUESTED_VERSION}" =~ ^[Ll][Aa][Tt][Ee][Ss][Tt]$ || "${REQUESTED_VERSION}" =~ ^[Nn][Uu][Ll][Ll]$ || "${REQUESTED_VERSION}" == "~" ]]; then + REQUESTED_VERSION=$( + curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + grep '"tag_name"' | head -n1 | + sed -E 's/.*"v?([^"]+)".*/\1/' + ) + echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" + fi + + # Validate REQUESTED_VERSION is not empty + if [[ -z "${REQUESTED_VERSION}" ]]; then + echo "Error: Could not determine a valid PowerShell version." + exit 1 + fi DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then From 0ae9ecfb3ff5e94c8e08b1c4d5445cfd41e85bf0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 20 Apr 2025 23:50:08 +0200 Subject: [PATCH 42/52] Refactor PowerShell installation: add echo statements to display requested version for better visibility during installation. --- action.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/action.yml b/action.yml index 9931412..982d5fe 100644 --- a/action.yml +++ b/action.yml @@ -28,6 +28,8 @@ runs: run: | set -e + echo "Requested version: [$REQUESTED_VERSION]" + # Resolve "" / null / latest → concrete latest version (Bash‑3 safe) case "${REQUESTED_VERSION:-}" in ""|[Ll][Aa][Tt][Ee][Ss][Tt]|[Nn][Uu][Ll][Ll]|~) @@ -83,6 +85,8 @@ runs: run: | set -e + echo "Requested version: [$REQUESTED_VERSION]" + # Resolve "" / null / latest → concrete latest version if [[ -z "${REQUESTED_VERSION}" || "${REQUESTED_VERSION}" =~ ^[Ll][Aa][Tt][Ee][Ss][Tt]$ || "${REQUESTED_VERSION}" =~ ^[Nn][Uu][Ll][Ll]$ || "${REQUESTED_VERSION}" == "~" ]]; then REQUESTED_VERSION=$( @@ -125,6 +129,7 @@ runs: env: REQUESTED_VERSION: ${{ inputs.Version }} run: | + Write-Host "Requested version: [$REQUESTED_VERSION]" # Resolve "" / null / latest → concrete latest version $req = $env:REQUESTED_VERSION if ([string]::IsNullOrWhiteSpace($req) -or From a9b92d67cc57818614046329d3ec85250eea9116 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 00:06:25 +0200 Subject: [PATCH 43/52] Refactor PowerShell installation: update version input handling to only resolve to latest if explicitly set; improve error messaging for empty version input. --- .github/workflows/Action-Test.yml | 5 +---- action.yml | 33 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index df18acb..99cb865 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -22,21 +22,18 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - version: ['', null, 'latest', '7.4.7', '7.5.0'] # '' → should resolve to latest + version: ['latest', '7.4.7', '7.5.0'] runs-on: ${{ matrix.os }} name: '${{ matrix.os }} - [${{ matrix.version }}]' steps: - # 1. Checkout the repo so the local action is available - name: Checkout repo uses: actions/checkout@v4 - # 2. Run the action under test - name: Action-Test uses: ./ with: Version: ${{ matrix.version }} - # 3. Verify the installed PowerShell version - name: Verify installed version shell: pwsh run: | diff --git a/action.yml b/action.yml index 982d5fe..d7c2310 100644 --- a/action.yml +++ b/action.yml @@ -12,10 +12,9 @@ inputs: Version: description: > PowerShell version to install (e.g. `7.4.1`). - Use `latest`, `null`, leave it **empty**, or omit the input entirely - to grab the newest stable release automatically. + Set to 'latest' to automatically install the newest stable release. required: false - default: '' # Empty string → newest release + default: 'latest' runs: using: composite @@ -30,9 +29,9 @@ runs: echo "Requested version: [$REQUESTED_VERSION]" - # Resolve "" / null / latest → concrete latest version (Bash‑3 safe) + # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) case "${REQUESTED_VERSION:-}" in - ""|[Ll][Aa][Tt][Ee][Ss][Tt]|[Nn][Uu][Ll][Ll]|~) + [Ll][Aa][Tt][Ee][Ss][Tt]) REQUESTED_VERSION=$( curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name"' | head -n1 | @@ -40,6 +39,10 @@ runs: ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" ;; + "") + echo "Error: Version input is required (or use 'latest')" + exit 1 + ;; esac DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true) @@ -87,19 +90,16 @@ runs: echo "Requested version: [$REQUESTED_VERSION]" - # Resolve "" / null / latest → concrete latest version - if [[ -z "${REQUESTED_VERSION}" || "${REQUESTED_VERSION}" =~ ^[Ll][Aa][Tt][Ee][Ss][Tt]$ || "${REQUESTED_VERSION}" =~ ^[Nn][Uu][Ll][Ll]$ || "${REQUESTED_VERSION}" == "~" ]]; then + # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) + if [[ "${REQUESTED_VERSION}" =~ ^[Ll][Aa][Tt][Ee][Ss][Tt]$ ]]; then REQUESTED_VERSION=$( curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name"' | head -n1 | sed -E 's/.*"v?([^"]+)".*/\1/' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - fi - - # Validate REQUESTED_VERSION is not empty - if [[ -z "${REQUESTED_VERSION}" ]]; then - echo "Error: Could not determine a valid PowerShell version." + elif [[ -z "${REQUESTED_VERSION}" ]]; then + echo "Error: Version input is required (or use 'latest')" exit 1 fi @@ -130,14 +130,15 @@ runs: REQUESTED_VERSION: ${{ inputs.Version }} run: | Write-Host "Requested version: [$REQUESTED_VERSION]" - # Resolve "" / null / latest → concrete latest version + # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) $req = $env:REQUESTED_VERSION - if ([string]::IsNullOrWhiteSpace($req) -or - $req.Trim().ToLower() -in @('latest','null','~')) { - + if ($req -and $req.Trim().ToLower() -eq 'latest') { $latest = (Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest').tag_name.TrimStart('v') Write-Host "Latest stable PowerShell release detected: $latest" $env:REQUESTED_VERSION = $latest + } elseif ([string]::IsNullOrWhiteSpace($req)) { + Write-Host "Error: Version input is required (or use 'latest')" + exit 1 } try { From d7e306416c3f39f132d5aa057ff7b65a296d161e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 00:20:35 +0200 Subject: [PATCH 44/52] Refactor PowerShell installation: improve version resolution logic for 'latest'; add validation for empty version input and enhance error messaging. --- action.yml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/action.yml b/action.yml index d7c2310..81f9c1f 100644 --- a/action.yml +++ b/action.yml @@ -91,15 +91,18 @@ runs: echo "Requested version: [$REQUESTED_VERSION]" # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) - if [[ "${REQUESTED_VERSION}" =~ ^[Ll][Aa][Tt][Ee][Ss][Tt]$ ]]; then + if [[ "${REQUESTED_VERSION,,}" == "latest" ]]; then REQUESTED_VERSION=$( curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name"' | head -n1 | sed -E 's/.*"v?([^"]+)".*/\1/' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" - elif [[ -z "${REQUESTED_VERSION}" ]]; then - echo "Error: Version input is required (or use 'latest')" + fi + + # Validate REQUESTED_VERSION is not empty + if [[ -z "${REQUESTED_VERSION}" ]]; then + echo "Error: Could not determine a valid PowerShell version." exit 1 fi @@ -109,9 +112,17 @@ runs: exit 0 fi - if brew info --cask powershell@$REQUESTED_VERSION >/dev/null 2>&1; then - brew install --cask powershell@$REQUESTED_VERSION + # Try Homebrew first + if command -v brew >/dev/null; then + echo "Using Homebrew package manager..." + if [[ "${REQUESTED_VERSION}" == "latest" ]]; then + brew install --cask powershell + else + brew install --cask powershell@$REQUESTED_VERSION + fi else + # Fall back to direct download + echo "Homebrew not available, downloading directly..." ARCH=$(uname -m) if [[ "$ARCH" == "arm64" ]]; then PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" From 4967815f43f0b51d575d9b31382f77895c674a70 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 00:29:44 +0200 Subject: [PATCH 45/52] Refactor PowerShell installation: enhance version resolution for macOS; improve error handling and fallback logic for Homebrew installation. --- action.yml | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/action.yml b/action.yml index 81f9c1f..941a352 100644 --- a/action.yml +++ b/action.yml @@ -90,8 +90,11 @@ runs: echo "Requested version: [$REQUESTED_VERSION]" - # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) - if [[ "${REQUESTED_VERSION,,}" == "latest" ]]; then + # Convert to lowercase for comparison (macOS-compatible method) + REQ_VER_LOWER=$(echo "$REQUESTED_VERSION" | tr '[:upper:]' '[:lower:]') + + # Only resolve to latest version if explicitly set to 'latest' + if [[ "$REQ_VER_LOWER" == "latest" ]]; then REQUESTED_VERSION=$( curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name"' | head -n1 | @@ -112,25 +115,37 @@ runs: exit 0 fi - # Try Homebrew first + # Try Homebrew first (simplified approach) if command -v brew >/dev/null; then echo "Using Homebrew package manager..." - if [[ "${REQUESTED_VERSION}" == "latest" ]]; then + # Homebrew handles 'latest' automatically when no version is specified + if [[ "$REQ_VER_LOWER" == "latest" ]]; then brew install --cask powershell else - brew install --cask powershell@$REQUESTED_VERSION + # Try specific version formula first + if brew install --cask "powershell@$REQUESTED_VERSION" 2>/dev/null; then + echo "Successfully installed via Homebrew" + else + # Fall back to generic formula if versioned one doesn't exist + echo "Version-specific formula not found, installing latest via Homebrew" + brew install --cask powershell + fi fi else # Fall back to direct download echo "Homebrew not available, downloading directly..." ARCH=$(uname -m) - if [[ "$ARCH" == "arm64" ]]; then - PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" - else - PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg" - fi + case "$ARCH" in + "arm64") PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" ;; + *) PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg" ;; + esac + URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}" - curl -sSL "$URL" -o "$PKG_NAME" + echo "Downloading from: $URL" + if ! curl -sSL "$URL" -o "$PKG_NAME"; then + echo "Error: Failed to download PowerShell package" + exit 1 + fi sudo installer -pkg "$PKG_NAME" -target / fi From b08f77b72a3e85599efbc89f5528da137e6d3d20 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 11:46:37 +0200 Subject: [PATCH 46/52] Refactor action metadata: update descriptions for clarity and consistency; ensure proper formatting in action.yml. --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++-------- action.yml | 6 +++--- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d560186..33c8b0d 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,60 @@ -# Template-Action +# Install-PowerShell -A template repository for GitHub Actions +A cross‑platform GitHub Action that installs a specific **PowerShell Core** version—or the latest stable release—on any GitHub‑hosted runner +(Linux, macOS, or Windows). The action automatically skips installation when the requested version is already present. ## Usage -### Inputs +Add the action to a job in your workflow file: -### Secrets - -### Outputs +```yaml +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 -### Example + - name: Install PowerShell + uses: PSModule/install-powershell@v1 + with: + Version: 7.5.0 -```yaml -Example here + - name: Run a PowerShell script + shell: pwsh + run: | + Write-Host "Using PowerShell $($PSVersionTable.PSVersion)" ``` + +## Inputs + +| Input | Required | Default | Description | +| ------- | -------- | ------- | ----------- | +| `Version` | `false` | `latest` | Desired PowerShell Core version (e.g. `7.4.1`). Use `latest` to install the newest stable release. | + +## Secrets + +This action does **not** require any secrets. + +## Outputs + +This action does **not** generate any outputs. + +## How it works + +* **Version resolution** + If `Version` is set to `latest` (case‑insensitive), the action queries the GitHub API for the newest stable release tag in the + `PowerShell/PowerShell` repository and substitutes that version. + +* **Skip logic** + Before installing, the action checks the current runner to see whether the requested version is already available + (`pwsh -Command $($PSVersionTable.PSVersion)`). If it matches, the step ends immediately. + +* **Platform‑specific installers** + | Runner OS | Install strategy | + | --------- | ---------------- | + | **Linux** (Debian/Ubuntu‑based) | Uses APT if available; otherwise downloads the `.deb` asset directly from the release page and installs with `dpkg`. | + | **macOS** | Prefers Homebrew Cask (`brew install --cask powershell`) and falls back to downloading the `.pkg` installer. ARCH detection (`arm64` / `x64`) is automatic. | + | **Windows** | Downloads the corresponding `.msi` package and installs silently with `msiexec`. | + +* **Error handling** + The step fails with a clear error message if the requested version cannot be resolved or if the operating‑system distribution is unsupported (e.g., non‑APT Linux distros). diff --git a/action.yml b/action.yml index 941a352..5bcfae7 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ name: Install PowerShell -description: > +description: | Install a specific version —or the latest stable version— of PowerShell Core on any GitHub runner (Linux, macOS, Windows). Skips the install if the requested version is already present. @@ -10,9 +10,9 @@ branding: inputs: Version: - description: > + description: | PowerShell version to install (e.g. `7.4.1`). - Set to 'latest' to automatically install the newest stable release. + Defaults to install the latest stable release. required: false default: 'latest' From 0d5c320c53011ff51806a31898758e7b175ade31 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 12:03:40 +0200 Subject: [PATCH 47/52] docs: add blank line for improved readability in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 33c8b0d..1d42759 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ This action does **not** generate any outputs. (`pwsh -Command $($PSVersionTable.PSVersion)`). If it matches, the step ends immediately. * **Platform‑specific installers** + | Runner OS | Install strategy | | --------- | ---------------- | | **Linux** (Debian/Ubuntu‑based) | Uses APT if available; otherwise downloads the `.deb` asset directly from the release page and installs with `dpkg`. | From 6e04ef4430a88868e12f83c52f787697de0735e6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 12:23:29 +0200 Subject: [PATCH 48/52] Refactor PowerShell installation: update curl command to fail silently on errors for improved reliability in version resolution. --- action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 5bcfae7..8336818 100644 --- a/action.yml +++ b/action.yml @@ -33,7 +33,7 @@ runs: case "${REQUESTED_VERSION:-}" in [Ll][Aa][Tt][Ee][Ss][Tt]) REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + curl -sf https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name"' | head -n1 | sed -E 's/.*"v?([^"]+)".*/\1/' ) @@ -96,7 +96,7 @@ runs: # Only resolve to latest version if explicitly set to 'latest' if [[ "$REQ_VER_LOWER" == "latest" ]]; then REQUESTED_VERSION=$( - curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + curl -sf https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name"' | head -n1 | sed -E 's/.*"v?([^"]+)".*/\1/' ) From 9b2d4fcbd7f5dc1423aa4c81ab43460e10ae2dad Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 12:33:03 +0200 Subject: [PATCH 49/52] Refactor PowerShell installation: update curl command to use jq for improved parsing of latest release version. --- action.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index 8336818..65bf15a 100644 --- a/action.yml +++ b/action.yml @@ -33,9 +33,8 @@ runs: case "${REQUESTED_VERSION:-}" in [Ll][Aa][Tt][Ee][Ss][Tt]) REQUESTED_VERSION=$( - curl -sf https://api.github.com/repos/PowerShell/PowerShell/releases/latest | - grep '"tag_name"' | head -n1 | - sed -E 's/.*"v?([^"]+)".*/\1/' + curl -s -f https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + jq -r '.tag_name' | sed 's/^v//' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" ;; @@ -96,9 +95,8 @@ runs: # Only resolve to latest version if explicitly set to 'latest' if [[ "$REQ_VER_LOWER" == "latest" ]]; then REQUESTED_VERSION=$( - curl -sf https://api.github.com/repos/PowerShell/PowerShell/releases/latest | - grep '"tag_name"' | head -n1 | - sed -E 's/.*"v?([^"]+)".*/\1/' + curl -s -f https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + jq -r '.tag_name' | sed 's/^v//' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" fi From 5fb5941df0822ba8f4711e90cdc96a3953063815 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 12:45:49 +0200 Subject: [PATCH 50/52] Refactor PowerShell installation: enhance API calls with authentication headers for improved security and reliability in version resolution. --- action.yml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 65bf15a..03706e1 100644 --- a/action.yml +++ b/action.yml @@ -24,6 +24,7 @@ runs: shell: bash env: REQUESTED_VERSION: ${{ inputs.Version }} + GITHUB_TOKEN: ${{ github.token }} run: | set -e @@ -33,7 +34,11 @@ runs: case "${REQUESTED_VERSION:-}" in [Ll][Aa][Tt][Ee][Ss][Tt]) REQUESTED_VERSION=$( - curl -s -f https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + curl -s -f \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/PowerShell/PowerShell/releases/latest | jq -r '.tag_name' | sed 's/^v//' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" @@ -84,6 +89,7 @@ runs: shell: bash env: REQUESTED_VERSION: ${{ inputs.Version }} + GITHUB_TOKEN: ${{ github.token }} run: | set -e @@ -95,7 +101,11 @@ runs: # Only resolve to latest version if explicitly set to 'latest' if [[ "$REQ_VER_LOWER" == "latest" ]]; then REQUESTED_VERSION=$( - curl -s -f https://api.github.com/repos/PowerShell/PowerShell/releases/latest | + curl -s -f \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/PowerShell/PowerShell/releases/latest | jq -r '.tag_name' | sed 's/^v//' ) echo "Latest stable PowerShell release detected: $REQUESTED_VERSION" @@ -157,7 +167,14 @@ runs: # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) $req = $env:REQUESTED_VERSION if ($req -and $req.Trim().ToLower() -eq 'latest') { - $latest = (Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest').tag_name.TrimStart('v') + $latest = ( + Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' ` + -Headers @{ + 'Accept' = 'application/vnd.github+json' + 'Authorization' = "Bearer $($env:GITHUB_TOKEN)" + 'X-GitHub-Api-Version' = '2022-11-28' + } + ).tag_name.TrimStart('v') Write-Host "Latest stable PowerShell release detected: $latest" $env:REQUESTED_VERSION = $latest } elseif ([string]::IsNullOrWhiteSpace($req)) { From b9fb488073513888f459a245d1117e1dda1cf8ed Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 12:48:41 +0200 Subject: [PATCH 51/52] Refactor PowerShell installation: add GITHUB_TOKEN environment variable for improved security in Windows installation step. --- action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/action.yml b/action.yml index 03706e1..8d48b2d 100644 --- a/action.yml +++ b/action.yml @@ -162,6 +162,7 @@ runs: shell: powershell env: REQUESTED_VERSION: ${{ inputs.Version }} + GITHUB_TOKEN: ${{ github.token }} run: | Write-Host "Requested version: [$REQUESTED_VERSION]" # Only resolve to latest version if explicitly set to 'latest' (case-insensitive) From c269d85d3a7cd3922cf15a8a54d8e3716cbad985 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 21 Apr 2025 12:55:52 +0200 Subject: [PATCH 52/52] Refactor Action-Test workflow: add GITHUB_TOKEN to environment variables for enhanced security and update API call with authentication headers for improved reliability in version resolution. --- .github/linters/.jscpd.json | 3 ++- .github/workflows/Action-Test.yml | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json index 23970e8..6100343 100644 --- a/.github/linters/.jscpd.json +++ b/.github/linters/.jscpd.json @@ -4,7 +4,8 @@ "consoleFull" ], "ignore": [ - "**/tests/**" + "**/tests/**", + "**/action.yml" ], "absolute": true } diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 99cb865..25565a8 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -36,6 +36,8 @@ jobs: - name: Verify installed version shell: pwsh + env: + GITHUB_TOKEN: ${{ github.token }} run: | # Requested version that came from the matrix $requested = '${{ matrix.version }}' @@ -44,9 +46,14 @@ jobs: if ([string]::IsNullOrWhiteSpace($requested) -or $requested.Trim().ToLower() -in @('latest','null')) { - $requested = (Invoke-RestMethod ` - -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' - ).tag_name.TrimStart('v') + $requested = ( + Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' ` + -Headers @{ + 'Accept' = 'application/vnd.github+json' + 'Authorization' = "Bearer $($env:GITHUB_TOKEN)" + 'X-GitHub-Api-Version' = '2022-11-28' + } + ).tag_name.TrimStart('v') Write-Host "Resolved 'latest' → $requested" }