Skip to content

Commit 7791a3f

Browse files
fix: stage release downloads outside target folder so failures don't leave empty dirs (#534)
1 parent 73e0b72 commit 7791a3f

3 files changed

Lines changed: 75 additions & 63 deletions

File tree

src/ALZ/Private/Shared/Get-GithubRelease.ps1

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -81,73 +81,77 @@ function Get-GithubRelease {
8181
return $releaseTag
8282
}
8383

84-
# Check if directory exists
85-
Write-Verbose "=====> Checking if directory for releases exists: $targetPath"
86-
87-
if (!(Test-Path $targetPath)) {
88-
Write-Verbose "Directory does not exist for releases, will now create: $targetPath"
89-
New-Item -ItemType Directory -Path $targetPath | Out-String | Write-Verbose
90-
}
91-
92-
# Check the directory for this release
84+
# Determine the target version path (do not create it yet - we only create it after a successful download/extract)
9385
$targetVersionPath = Join-Path $targetPath $releaseTag
9486

9587
Write-Verbose "===> Checking if directory for release version exists: $targetVersionPath"
9688

97-
if (!(Test-Path $targetVersionPath)) {
98-
Write-Verbose "Directory does not exist for release $releaseTag, will now create: $targetVersionPath"
99-
New-Item -ItemType Directory -Path $targetVersionPath | Out-String | Write-Verbose
89+
$contentTargetVersionPath = $null
90+
if (Test-Path $targetVersionPath) {
91+
$contentTargetVersionPath = Get-ChildItem -Path $targetVersionPath -Recurse -Force -ErrorAction SilentlyContinue
10092
}
10193

102-
Write-Verbose "===> Checking if any content exists inside of $targetVersionPath"
103-
104-
$contentTargetVersionPath = Get-ChildItem -Path $targetVersionPath -Recurse -Force -ErrorAction SilentlyContinue
105-
10694
if ($null -eq $contentTargetVersionPath) {
107-
Write-Verbose "===> Pulling and extracting release $releaseTag into $targetVersionPath"
108-
New-Item -ItemType Directory -Path "$targetVersionPath/tmp" | Out-String | Write-Verbose
109-
$targetPathForZip = "$targetVersionPath/tmp/$releaseTag.zip"
110-
111-
# Get the artifact url
112-
if($releaseArtifactName -ne "") {
113-
$releaseArtifactUrl = $releaseData.assets | Where-Object { $_.name -eq $releaseArtifactName } | Select-Object -ExpandProperty browser_download_url
114-
} else {
115-
$releaseArtifactUrl = $releaseData.zipball_url
116-
}
117-
118-
Write-Verbose "===> Downloading the release artifact $releaseArtifactUrl from the GitHub repository $repoOrgPlusRepo"
119-
120-
$downloadParams = @{
121-
Uri = $releaseArtifactUrl
122-
OutputFile = $targetPathForZip
123-
MaxRetryCount = $maxRetryCount
124-
RetryIntervalSeconds = $retryIntervalSeconds
125-
}
126-
if ($PSBoundParameters.ContainsKey("httpRequestTimeoutSeconds")) {
127-
$downloadParams["TimeoutSec"] = $httpRequestTimeoutSeconds
95+
# Stage the download and extraction in a temp location under the outputs folder so a failure
96+
# does not leave behind empty release/version folders. We always clean it up in `finally`.
97+
$stagingRoot = Join-Path $targetDirectory "temp/downloads/$([System.Guid]::NewGuid().ToString("N"))"
98+
New-Item -ItemType Directory -Path $stagingRoot -Force | Out-String | Write-Verbose
99+
$targetPathForZip = Join-Path $stagingRoot "$releaseTag.zip"
100+
$targetPathForExtractedZip = Join-Path $stagingRoot "extracted"
101+
102+
try {
103+
# Get the artifact url
104+
if($releaseArtifactName -ne "") {
105+
$releaseArtifactUrl = $releaseData.assets | Where-Object { $_.name -eq $releaseArtifactName } | Select-Object -ExpandProperty browser_download_url
106+
} else {
107+
$releaseArtifactUrl = $releaseData.zipball_url
108+
}
109+
110+
Write-Verbose "===> Downloading the release artifact $releaseArtifactUrl from the GitHub repository $repoOrgPlusRepo to staging location $targetPathForZip"
111+
112+
$downloadParams = @{
113+
Uri = $releaseArtifactUrl
114+
OutputFile = $targetPathForZip
115+
MaxRetryCount = $maxRetryCount
116+
RetryIntervalSeconds = $retryIntervalSeconds
117+
}
118+
if ($PSBoundParameters.ContainsKey("httpRequestTimeoutSeconds")) {
119+
$downloadParams["TimeoutSec"] = $httpRequestTimeoutSeconds
120+
}
121+
Invoke-GitHubApiRequest @downloadParams
122+
123+
if(!(Test-Path $targetPathForZip)) {
124+
Write-ToConsoleLog "Failed to download the release $releaseTag from the GitHub repository $repoOrgPlusRepo" -IsError
125+
throw "Failed to download the release $releaseTag from the GitHub repository $repoOrgPlusRepo"
126+
}
127+
128+
Expand-Archive -Path $targetPathForZip -DestinationPath $targetPathForExtractedZip | Out-String | Write-Verbose
129+
130+
$extractedSubFolder = $targetPathForExtractedZip
131+
if($releaseArtifactName -eq "") {
132+
$extractedSubFolder = (Get-ChildItem -Path $targetPathForExtractedZip -Directory -Force).FullName
133+
}
134+
135+
# Only now (after a successful download and extract) do we create the target folders
136+
# and copy the content in.
137+
if (!(Test-Path $targetPath)) {
138+
Write-Verbose "Directory does not exist for releases, will now create: $targetPath"
139+
New-Item -ItemType Directory -Path $targetPath | Out-String | Write-Verbose
140+
}
141+
142+
Write-Verbose "Directory does not exist for release $releaseTag, will now create: $targetVersionPath"
143+
New-Item -ItemType Directory -Path $targetVersionPath | Out-String | Write-Verbose
144+
145+
Write-Verbose "===> Copying all extracted contents into $targetVersionPath from $($extractedSubFolder)/$moduleSourceFolder/*."
146+
147+
Copy-Item -Path "$($extractedSubFolder)/$moduleSourceFolder/*" -Destination "$targetVersionPath" -Recurse -Force | Out-String | Write-Verbose
148+
149+
Write-ToConsoleLog "The directory for $targetVersionPath has been created and populated." -IsSuccess
150+
} finally {
151+
if (Test-Path $stagingRoot) {
152+
Remove-Item -Path $stagingRoot -Force -Recurse -ErrorAction SilentlyContinue
153+
}
128154
}
129-
Invoke-GitHubApiRequest @downloadParams
130-
131-
if(!(Test-Path $targetPathForZip)) {
132-
Write-ToConsoleLog "Failed to download the release $releaseTag from the GitHub repository $repoOrgPlusRepo" -IsError
133-
throw
134-
}
135-
136-
$targetPathForExtractedZip = "$targetVersionPath/tmp/extracted"
137-
138-
Expand-Archive -Path $targetPathForZip -DestinationPath $targetPathForExtractedZip | Out-String | Write-Verbose
139-
140-
$extractedSubFolder = $targetPathForExtractedZip
141-
if($releaseArtifactName -eq "") {
142-
$extractedSubFolder = (Get-ChildItem -Path $targetPathForExtractedZip -Directory -Force).FullName
143-
}
144-
145-
Write-Verbose "===> Copying all extracted contents into $targetVersionPath from $($extractedSubFolder)/$moduleSourceFolder/*."
146-
147-
Copy-Item -Path "$($extractedSubFolder)/$moduleSourceFolder/*" -Destination "$targetVersionPath" -Recurse -Force | Out-String | Write-Verbose
148-
149-
Remove-Item -Path "$targetVersionPath/tmp" -Force -Recurse
150-
Write-ToConsoleLog "The directory for $targetVersionPath has been created and populated." -IsSuccess
151155
} else {
152156
Write-ToConsoleLog "The directory for $targetVersionPath already exists and has content in it, so we are not overwriting it." -IsSuccess
153157
Write-Verbose "===> Content already exists in $releaseDirectory. Skipping"

src/ALZ/Private/Tools/Get-TerraformTool.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function Get-TerraformTool {
4747
Write-ToConsoleLog "Unable to query Terraform version '$version' from HashiCorp API. HTTP status code: $($versionResponse.StatusCode)" -IsError
4848
throw "Unable to query Terraform version, please check the supplied version and try again..."
4949
}
50-
$release = ($versionResponse).Content
50+
$release = ($versionResponse).Content | ConvertFrom-Json
5151
}
5252

5353
Write-Verbose "Required version of Terraform is $version"

src/ALZ/Public/Deploy-Accelerator.ps1

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,15 @@ function Deploy-Accelerator {
221221
)]
222222
[Alias("hrts")]
223223
[Alias("httpRequestTimeoutSeconds")]
224-
[int] $http_request_timeout_seconds
224+
[int] $http_request_timeout_seconds,
225+
226+
[Parameter(
227+
Mandatory = $false,
228+
HelpMessage = "[OPTIONAL] The version of Terraform to download and use. Defaults to '1.14.9'. Specify 'latest' to download the latest stable release. Environment variable: ALZ_terraform_version. Config file input: terraform_version."
229+
)]
230+
[Alias("tv")]
231+
[Alias("terraformVersion")]
232+
[string] $terraform_version = "1.14.9"
225233
)
226234

227235
$ProgressPreference = "SilentlyContinue"
@@ -355,9 +363,9 @@ function Deploy-Accelerator {
355363
if ($skipInternetChecks) {
356364
Write-ToConsoleLog "Skipping Terraform tool check as you used the skipInternetCheck parameter. Please ensure you have the most recent version of Terraform installed" -IsWarning
357365
} else {
358-
Write-ToConsoleLog "Checking you have the latest version of Terraform installed..." -IsSuccess
366+
Write-ToConsoleLog "Checking you have the correct version of Terraform installed..." -IsSuccess
359367
$terraformToolParams = @{
360-
version = "latest"
368+
version = $terraform_version
361369
toolsPath = $toolsPath
362370
maxRetryCount = $http_request_max_retry_count
363371
retryIntervalSeconds = $http_request_retry_interval_seconds

0 commit comments

Comments
 (0)