Skip to content

Commit cb59766

Browse files
Refactor PowerShell installation logic: improve version comparison functions, streamline version retrieval, and enhance error handling for installation processes.
1 parent 23bddd9 commit cb59766

File tree

1 file changed

+102
-149
lines changed

1 file changed

+102
-149
lines changed

action.yml

Lines changed: 102 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -19,73 +19,74 @@ runs:
1919
run: |
2020
$version = '${{ inputs.Version }}'
2121
22-
# Get the version to install
22+
# Get version to install
2323
if ([string]::IsNullOrWhiteSpace($version)) {
24-
# Get latest version from GitHub API
2524
$releaseInfo = Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest'
2625
$version = $releaseInfo.tag_name.Trim('v')
2726
Write-Host "Latest PowerShell version: $version"
2827
} else {
29-
# Remove the 'v' prefix if it exists
3028
$version = $version.TrimStart('v')
3129
Write-Host "Installing specified PowerShell version: $version"
3230
}
3331
34-
# Check if PowerShell is already installed and compare versions
32+
# Function to compare versions
33+
function Compare-Versions {
34+
param(
35+
[string]$CurrentVersion,
36+
[string]$TargetVersion
37+
)
38+
39+
$currentParts = $CurrentVersion.Split('.') + @(0,0,0)
40+
$targetParts = $TargetVersion.Split('.') + @(0,0,0)
41+
42+
for ($i = 0; $i -lt 3; $i++) {
43+
$currentPart = [int]$currentParts[$i]
44+
$targetPart = [int]$targetParts[$i]
45+
46+
if ($currentPart -lt $targetPart) { return -1 }
47+
if ($currentPart -gt $targetPart) { return 1 }
48+
}
49+
return 0
50+
}
51+
52+
# Check existing installation
3553
$needToInstall = $true
3654
try {
37-
$currentInstall = Get-Command pwsh -ErrorAction SilentlyContinue
38-
if ($currentInstall) {
55+
if (Get-Command pwsh -ErrorAction SilentlyContinue) {
3956
$currentVersion = & pwsh -Command '$PSVersionTable.PSVersion.ToString()'
4057
Write-Host "Current PowerShell version: $currentVersion"
4158
42-
# Parse versions into System.Version objects for proper comparison
43-
try {
44-
$currentVersionObj = [System.Version]$currentVersion
45-
$targetVersionObj = [System.Version]$version
46-
47-
# Compare versions
48-
if ($currentVersionObj -ge $targetVersionObj) {
49-
Write-Host "Current version $currentVersion is greater than or equal to target version $version. Skipping installation."
50-
$needToInstall = $false
51-
} else {
52-
Write-Host "Current version $currentVersion is lower than target version $version. Will upgrade."
53-
}
54-
} catch {
55-
Write-Host "Error comparing versions: $_ Will proceed with installation."
56-
$needToInstall = $true
59+
$comparison = Compare-Versions -CurrentVersion $currentVersion -TargetVersion $version
60+
if ($comparison -ge 0) {
61+
Write-Host "Current version meets or exceeds target version. Skipping installation."
62+
$needToInstall = $false
63+
} else {
64+
Write-Host "Current version is lower than target version. Will upgrade."
5765
}
58-
} else {
59-
Write-Host "PowerShell Core not found. Will install version $version"
6066
}
6167
} catch {
62-
Write-Host "Error checking current PowerShell version: $_"
63-
$needToInstall = $true
68+
Write-Host "Error checking current version: $_"
6469
}
6570
6671
if ($needToInstall) {
6772
try {
68-
# Download and install PowerShell
6973
$msiName = "PowerShell-$version-win-x64.msi"
7074
$downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v$version/$msiName"
7175
7276
Write-Host "Downloading from $downloadUrl"
7377
Invoke-WebRequest -Uri $downloadUrl -OutFile $msiName -ErrorAction Stop
7478
7579
Write-Host "Installing PowerShell $version"
76-
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait -ErrorAction Stop
80+
Start-Process msiexec.exe -ArgumentList "/i", $msiName, "/quiet", "/norestart" -Wait -ErrorAction Stop
7781
78-
# Verify installation
79-
$pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe"
80-
if (Test-Path $pwshPath) {
81-
Write-Host "PowerShell installed successfully:"
82-
& $pwshPath -Command '$PSVersionTable'
82+
if (Test-Path "$env:ProgramFiles\PowerShell\7\pwsh.exe") {
83+
Write-Host "Installation successful"
84+
& "$env:ProgramFiles\PowerShell\7\pwsh.exe" -Command '$PSVersionTable'
8385
} else {
84-
Write-Error "PowerShell installation failed. Could not find $pwshPath"
85-
exit 1
86+
throw "Installation failed - pwsh.exe not found"
8687
}
8788
} catch {
88-
Write-Error "Failed to install PowerShell: $_"
89+
Write-Error "Installation failed: $_"
8990
exit 1
9091
}
9192
}
@@ -96,95 +97,69 @@ runs:
9697
run: |
9798
version='${{ inputs.Version }}'
9899
99-
# Function to normalize version (remove trailing .0 and v prefix)
100-
normalize_version() {
101-
local version=${1#v} # Remove v prefix
102-
version=${version%.0} # Remove trailing .0
103-
version=${version%.0} # Remove additional .0 if present
104-
echo "$version"
100+
# Version comparison functions
101+
get_version_parts() {
102+
local version=${1#v}
103+
IFS='.' read -ra parts <<< "$version"
104+
echo "${parts[0]:-0} ${parts[1]:-0} ${parts[2]:-0}"
105105
}
106106
107-
# Function to compare versions
108107
compare_versions() {
109-
local current=$(normalize_version "$1")
110-
local target=$(normalize_version "$2")
111-
112-
# Split versions into arrays
113-
IFS='.' read -ra current_parts <<< "$current"
114-
IFS='.' read -ra target_parts <<< "$target"
115-
116-
# Ensure all parts exist (default to 0 if missing)
117-
for i in {0..2}; do
118-
current_parts[$i]=${current_parts[$i]:-0}
119-
target_parts[$i]=${target_parts[$i]:-0}
120-
done
121-
122-
# Compare major, minor, patch
123-
for i in {0..2}; do
124-
if [ "${current_parts[$i]}" -lt "${target_parts[$i]}" ]; then
125-
return 1 # current < target
126-
elif [ "${current_parts[$i]}" -gt "${target_parts[$i]}" ]; then
127-
return 2 # current > target
128-
fi
129-
done
130-
131-
return 0 # equal
108+
local current_parts=($(get_version_parts "$1"))
109+
local target_parts=($(get_version_parts "$2"))
110+
111+
for i in {0..2}; do
112+
if (( current_parts[i] < target_parts[i] )); then return 1; fi
113+
if (( current_parts[i] > target_parts[i] )); then return 2; fi
114+
done
115+
return 0
132116
}
133117
118+
# Get version if not specified
134119
if [ -z "$version" ]; then
135-
# Get latest version if not specified
136120
version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4)
137121
echo "Latest PowerShell version: $version"
138122
fi
139123
140-
# Always remove 'v' prefix if present
141124
clean_version=${version#v}
142125
echo "Installing PowerShell version: $clean_version"
143126
144-
# Check if PowerShell is already installed and get current version
127+
# Check existing installation
145128
need_to_install=true
146129
if command -v pwsh &> /dev/null; then
147130
current_version=$(pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n')
148131
echo "Current PowerShell version: $current_version"
149132
150133
compare_versions "$current_version" "$clean_version"
151134
case $? in
152-
0) echo "Versions are equal"; need_to_install=false ;;
153-
2) echo "Current version is higher"; need_to_install=false ;;
154-
1) echo "Current version is lower"; need_to_install=true ;;
155-
*) echo "Version comparison failed, proceeding with installation" ;;
135+
0) echo "Versions equal - skipping install"; need_to_install=false ;;
136+
2) echo "Current version higher - skipping install"; need_to_install=false ;;
137+
1) echo "Current version lower - will upgrade" ;;
156138
esac
157-
else
158-
echo "PowerShell is not installed. Will install version $clean_version"
159139
fi
160140
161141
if [ "$need_to_install" = true ]; then
162-
# Install prerequisites
163142
sudo apt-get update
164143
sudo apt-get install -y wget apt-transport-https
165144
166-
# Download package - handle both old and new naming formats
167-
pkg_name="powershell_${clean_version}-1.deb_amd64.deb"
168-
if ! wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name"; then
169-
# Try alternative package name format
170-
pkg_name="powershell-${clean_version}-linux-x64.deb"
171-
wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name" || {
172-
echo "ERROR: Failed to download PowerShell package"
173-
exit 1
174-
}
175-
fi
176-
177-
sudo dpkg -i "$pkg_name"
178-
sudo apt-get install -f
179-
180-
# Verify installation
181-
if command -v pwsh &> /dev/null; then
182-
echo "PowerShell installed successfully:"
183-
pwsh -c '$PSVersionTable'
184-
else
185-
echo "ERROR: PowerShell installation failed."
145+
# Try multiple package formats
146+
pkg_found=false
147+
for pkg in "powershell_${clean_version}-1.deb_amd64.deb" "powershell-${clean_version}-linux-x64.deb"; do
148+
if wget "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg"; then
149+
pkg_found=true
150+
sudo dpkg -i "$pkg"
151+
sudo apt-get install -f
152+
break
153+
fi
154+
done
155+
156+
if [ "$pkg_found" = false ]; then
157+
echo "ERROR: Failed to download package"
186158
exit 1
187159
fi
160+
161+
echo "Installation successful:"
162+
pwsh -c '$PSVersionTable'
188163
fi
189164
190165
- name: Install PowerShell on macOS
@@ -193,83 +168,61 @@ runs:
193168
run: |
194169
version='${{ inputs.Version }}'
195170
196-
# Function to compare versions
171+
# Version comparison functions
172+
get_version_parts() {
173+
local version=${1#v}
174+
IFS='.' read -ra parts <<< "$version"
175+
echo "${parts[0]:-0} ${parts[1]:-0} ${parts[2]:-0}"
176+
}
177+
197178
compare_versions() {
198-
local current=$1
199-
local target=$2
200-
201-
# Split versions into arrays
202-
IFS='.' read -ra current_parts <<< "$current"
203-
IFS='.' read -ra target_parts <<< "$target"
204-
205-
# Ensure all parts exist (default to 0 if missing)
206-
for i in {0..2}; do
207-
current_parts[$i]=${current_parts[$i]:-0}
208-
target_parts[$i]=${target_parts[$i]:-0}
209-
done
210-
211-
# Compare major, minor, patch
212-
for i in {0..2}; do
213-
if [ "${current_parts[$i]}" -lt "${target_parts[$i]}" ]; then
214-
return 1 # current < target
215-
elif [ "${current_parts[$i]}" -gt "${target_parts[$i]}" ]; then
216-
return 2 # current > target
217-
fi
218-
done
219-
220-
return 0 # equal
179+
local current_parts=($(get_version_parts "$1"))
180+
local target_parts=($(get_version_parts "$2"))
181+
182+
for i in {0..2}; do
183+
if (( current_parts[i] < target_parts[i] )); then return 1; fi
184+
if (( current_parts[i] > target_parts[i] )); then return 2; fi
185+
done
186+
return 0
221187
}
222188
189+
# Get version if not specified
223190
if [ -z "$version" ]; then
224-
# Get latest version if not specified
225191
version=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep 'tag_name' | cut -d '"' -f 4)
226192
echo "Latest PowerShell version: $version"
227193
fi
228194
229-
# Always remove 'v' prefix if present
230195
clean_version=${version#v}
231196
echo "Installing PowerShell version: $clean_version"
232197
233-
# Check if PowerShell is already installed and get current version
198+
# Check existing installation
234199
need_to_install=true
235200
if [ -f "/usr/local/bin/pwsh" ]; then
236201
current_version=$(/usr/local/bin/pwsh -c '$PSVersionTable.PSVersion.ToString()' | tr -d '\r\n')
237202
echo "Current PowerShell version: $current_version"
238203
239204
compare_versions "$current_version" "$clean_version"
240205
case $? in
241-
0) echo "Versions are equal"; need_to_install=false ;;
242-
2) echo "Current version is higher"; need_to_install=false ;;
243-
1) echo "Current version is lower"; need_to_install=true ;;
206+
0) echo "Versions equal - skipping install"; need_to_install=false ;;
207+
2) echo "Current version higher - skipping install"; need_to_install=false ;;
208+
1) echo "Current version lower - will upgrade" ;;
244209
esac
245-
else
246-
echo "PowerShell is not installed. Will install version $clean_version"
247210
fi
248211
249212
if [ "$need_to_install" = true ]; then
250-
# Determine architecture
251-
if [ "$(uname -m)" = "arm64" ]; then
252-
echo "Detected Apple Silicon (ARM64)"
253-
pkg_name="powershell-$clean_version-osx-arm64.pkg"
254-
else
255-
echo "Detected Intel CPU (x64)"
256-
pkg_name="powershell-$clean_version-osx-x64.pkg"
257-
fi
258-
259-
# Download the package
260-
url="https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg_name"
261-
echo "Downloading from $url"
262-
curl -LO $url
263-
264-
# Install the package
265-
sudo installer -pkg "$pkg_name" -target /
213+
arch=$(uname -m)
214+
case $arch in
215+
arm64) pkg="powershell-${clean_version}-osx-arm64.pkg" ;;
216+
*) pkg="powershell-${clean_version}-osx-x64.pkg" ;;
217+
esac
266218
267-
# Verify the installation
268-
if [ -f "/usr/local/bin/pwsh" ]; then
269-
echo "PowerShell installed successfully:"
270-
/usr/local/bin/pwsh -Command '$PSVersionTable'
271-
else
272-
echo "ERROR: PowerShell installation failed. Could not find /usr/local/bin/pwsh"
219+
if ! curl -LO "https://github.com/PowerShell/PowerShell/releases/download/v$clean_version/$pkg"; then
220+
echo "ERROR: Failed to download package"
273221
exit 1
274222
fi
223+
224+
sudo installer -pkg "$pkg" -target /
225+
226+
echo "Installation successful:"
227+
/usr/local/bin/pwsh -c '$PSVersionTable'
275228
fi

0 commit comments

Comments
 (0)