Modules/businessdev.ALbuild.Containers/Public/Get-BcArtifact.ps1
|
function Get-BcArtifact { <# .SYNOPSIS Downloads and caches a Business Central artifact (application + platform packages). .DESCRIPTION Downloads the application package for the given artifact URL and, unless suppressed, the matching platform package (the same URL with the country replaced by 'platform'). Each package is a ZIP; it is extracted into the artifact cache and reused on subsequent calls. .PARAMETER ArtifactUrl The artifact URL (see Find-BcArtifactUrl). .PARAMETER CacheFolder Root cache folder. Defaults to the configured ArtifactCacheFolder. .PARAMETER IncludePlatform Also download/extract the platform package. Default: $true. .PARAMETER Force Re-download even if a cached copy exists. .EXAMPLE Get-BcArtifact -ArtifactUrl (Find-BcArtifactUrl -Country w1 -Select Latest) .OUTPUTS PSCustomObject with ApplicationPath, PlatformPath, Version, Country. #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [string] $ArtifactUrl, [string] $CacheFolder, [bool] $IncludePlatform = $true, [switch] $Force ) process { if (-not $CacheFolder) { $CacheFolder = Get-ALbuildConfig -Name 'ArtifactCacheFolder' } $info = Get-BcArtifactVersion -ArtifactUrl $ArtifactUrl $downloadAndExtract = { param([string] $url, [string] $targetFolder, [bool] $force) if ((Test-Path -LiteralPath $targetFolder) -and -not $force) { # Cached marker file indicates a complete extraction. if (Test-Path -LiteralPath (Join-Path $targetFolder '.albuild-complete')) { return $targetFolder } Remove-Item -LiteralPath $targetFolder -Recurse -Force -ErrorAction SilentlyContinue } $tempZip = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.Guid]::NewGuid().ToString() + '.zip') try { Write-ALbuildLog "Downloading artifact $url ..." $attempt = 0 while ($true) { $attempt++ try { Invoke-WebRequest -Uri $url -OutFile $tempZip -UseBasicParsing -TimeoutSec 600 -ErrorAction Stop; break } catch { if ($attempt -ge 3) { throw "Failed to download artifact '$url': $($_.Exception.Message)" } Start-Sleep -Seconds (5 * $attempt) } } New-Item -Path $targetFolder -ItemType Directory -Force | Out-Null Expand-Archive -LiteralPath $tempZip -DestinationPath $targetFolder -Force Set-Content -LiteralPath (Join-Path $targetFolder '.albuild-complete') -Value (Get-Date -Format 'o') -Encoding UTF8 return $targetFolder } finally { if (Test-Path -LiteralPath $tempZip) { Remove-Item -LiteralPath $tempZip -Force -ErrorAction SilentlyContinue } } } $versionFolder = Join-Path $CacheFolder ($info.Type) | Join-Path -ChildPath $info.Version.ToString() $appFolder = & $downloadAndExtract $ArtifactUrl (Join-Path $versionFolder $info.Country) ([bool]$Force) $platformFolder = $null if ($IncludePlatform) { $platformUrl = $ArtifactUrl -replace "/$([regex]::Escape($info.Country))$", '/platform' $platformFolder = & $downloadAndExtract $platformUrl (Join-Path $versionFolder 'platform') ([bool]$Force) } return [PSCustomObject]@{ ApplicationPath = $appFolder PlatformPath = $platformFolder Version = $info.Version Country = $info.Country Type = $info.Type } } } |