Skip to content

Commit 41843ce

Browse files
compnerdjeffdavtristanlabelle
authored
GHA: inline the GHA utilities (#23)
Inline the implementation for download and install. This is motivated by the changes to the GHA infrastructure which changed the behaviour of the existing implementation. The event identifies the fragility due to the use of a non-stable interface. We now provide our own implementation. While this is complex, it does avoid the problem of unexpected behavioural changes. Even if we wanted to adopt the behaviour for the changes, we would not be able to provide a backwards compatible implementation which would make this flakey until we are firmly in the new implementation world. Co-authored-by: Jeff <jeffdav@users.noreply.github.com> Co-authored-by: Tristan Labelle <tristan@thebrowser.company>
1 parent 60ac828 commit 41843ce

File tree

1 file changed

+139
-2
lines changed

1 file changed

+139
-2
lines changed

action.yml

+139-2
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,147 @@ runs:
7777
}
7878
}
7979
80+
function Invoke-Download {
81+
Param
82+
(
83+
[Parameter(Mandatory)]
84+
[String] $URL,
85+
[Alias("Destination")]
86+
[Int] $Retries = 20,
87+
[Int] $RetryInterval = 30
88+
)
89+
90+
$InvalidCharacters = [IO.Path]::GetInvalidFileNameChars() -Join ''
91+
$RE = "[{0}]" -f [RegEx]::Escape($InvalidCharacters)
92+
$FileName = [IO.Path]::GetFileName($URL) -Replace $RE
93+
94+
if ([String]::IsNullOrEmpty($FileName)) {
95+
$FileName = [System.IO.Path]::GetRandomFileName()
96+
}
97+
$Path = Join-Path -Path "${env:Temp}" -ChildPath $FileName
98+
99+
Write-Host "Downloading package from $URL to $Path..."
100+
101+
$StartTime = Get-Date
102+
do {
103+
try {
104+
$AttemptStartTime = Get-Date
105+
(New-Object System.Net.WebClient).DownloadFile($URL, $Path)
106+
$AttemptDuration = [math]::Round(($(Get-Date) - $AttemptStartTime).TotalSeconds, 2)
107+
Write-Host "Package downloaded in $AttemptDuration seconds"
108+
break
109+
} catch {
110+
$AttemptDuration = [math]::Round(($(Get-Date) - $AttemptStartTime).TotalSeconds, 2)
111+
Write-Warning "Package download failed after $AttemptDuration seconds"
112+
Write-Warning $_.Exception.Message
113+
}
114+
115+
if ($Retries -eq 1) {
116+
$Duration = [math]::Round(($(Get-Date) - $StartTime).TotalSeconds, 2)
117+
throw "Package download failed after $Duration seconds"
118+
}
119+
120+
Write-Warning "Waiting $RetryInterval seconds before retrying (retries remaining: $($Retries - 1))..."
121+
Start-Sleep -Seconds $RetryInterval
122+
} while (--$Retries -gt 0)
123+
124+
return $Path
125+
}
126+
127+
function Verify-Checksum {
128+
Param
129+
(
130+
[Parameter(Mandatory)]
131+
[String] $Actual,
132+
[Parameter(Mandatory)]
133+
[String] $Expected
134+
)
135+
136+
Write-Verbose "Performing Checksum Verification"
137+
if ($Actual -eq $Expected) {
138+
Write-Verbose "Checksum verification passed"
139+
} else {
140+
throw "Checksum verification failure (Actual: $Actual vs Expected: $Expected)"
141+
}
142+
}
143+
144+
function Invoke-Installer {
145+
Param
146+
(
147+
[Parameter(Mandatory, ParameterSetName = "URL")]
148+
[String] $URL,
149+
[Parameter(Mandatory, ParameterSetName = "LocalPath")]
150+
[String] $LocalPath,
151+
[ValidateSet("MSI", "EXE")]
152+
[String] $Type,
153+
[String[]] $InstallArgs = $null, # Use default for installer format
154+
[String[]] $ExtraInstallArgs = @(),
155+
[String] $ExpectedSHA256
156+
)
157+
158+
if ($PSCmdlet.ParameterSetName -eq "LocalPath") {
159+
if (-not (Test-Path -Path $LocalPath)) {
160+
throw "LocalPath parameter is specified, but the file does not exist"
161+
}
162+
$FilePath = $LocalPath
163+
} else {
164+
$FileName = [System.IO.Path]::GetFileName($URL)
165+
$FilePath = Invoke-Download -URL $URL
166+
}
167+
168+
if ($ExpectedSHA256) {
169+
$Hash = (Get-FileHash -Path $FilePath -Algorithm SH256).Hash
170+
Verify-Checksum -Actual $Hash -Expected $ExpectedSHA256
171+
}
172+
173+
if (-not $Type) {
174+
$Type = ([System.IO.Path]::GetExtension($FilePath)).Replace(".", "").ToUpper()
175+
}
176+
177+
switch ($Type) {
178+
"EXE" {
179+
if (-not $InstallArgs) { $InstallArgs = @() }
180+
$InstallArgs += $ExtraInstallArgs
181+
}
182+
"MSI" {
183+
if (-not $InstallArgs) {
184+
Write-Host "Using default MSI arguments: /i, /qn, /norestart"
185+
$InstallArgs = @("/i", $FilePath, "/qn", "/norestart")
186+
}
187+
188+
$InstallArgs += $ExtraInstallArgs
189+
$FilePath = "msiexec.exe"
190+
}
191+
default {
192+
throw "Unknown installer type (${Type}), please specify via `-Type` parameter"
193+
}
194+
}
195+
196+
$StartTime = Get-Date
197+
Write-Host "Starting Install..."
198+
try {
199+
$Process = Start-Process -FilePath $FilePath -ArgumentList $InstallArgs -Wait -PassThru -Verb RunAs
200+
$ExitCode = $Process.ExitCode
201+
$Duration = [math]::Round(($(Get-Date) - $StartTime).TotalSeconds, 2)
202+
switch ($ExitCode) {
203+
0 { Write-Host "Installation successful in $Duration seconds" }
204+
3010 { Write-Host "Installation successful in $Duration seconds; reboot required"}
205+
default {
206+
Write-Host "Installation process returned unexpected exit code: $ExitCode"
207+
Write-Host "Time elapsed: $Duration seconds"
208+
exit $ExitCode
209+
}
210+
}
211+
} catch {
212+
$Duration = [math]::Round(($(Get-Date) - $StartTime).TotalSeconds, 2)
213+
Write-Host "Installation failed after $Duration seconds"
214+
}
215+
}
216+
80217
if ("${{ steps.validation.outputs.use_custom_url }}" -eq "1") {
81-
Install-Binary -FilePath "${{ inputs.release-asset-name }}" -ArgumentList ("-q")
218+
Invoke-Installer -FilePath "${{ inputs.release-asset-name }}" -InstallArgs ("/quiet")
82219
} else {
83-
Install-Binary -Url "https://download.swift.org/${{ inputs.branch }}/windows10/swift-${{ inputs.tag }}/swift-${{ inputs.tag }}-windows10.exe" -Name "installer.exe" -ArgumentList ("-q")
220+
Invoke-Installer -URL "https://download.swift.org/${{ inputs.branch }}/windows10/swift-${{ inputs.tag }}/swift-${{ inputs.tag }}-windows10.exe" -InstallArgs ("/quiet")
84221
}
85222
Update-EnvironmentVariables
86223

0 commit comments

Comments
 (0)