Public/Get-ALZGithubRelease.ps1
#################################### # Get-ALZGithubRelease.ps1 # #################################### # Version: 0.1.0 # Based on Invoke-GitHubReleaseFetcher by Jack Tracey: # Source: https://github.com/jtracey93/PublicScripts/blob/master/GitHub/PowerShell/Invoke-GitHubReleaseFetcher.ps1 <# .SYNOPSIS Checks for the releases of a GitHub repository and downloads the latest release or all releases and pulls it into a specified directory, one for each version. .DESCRIPTION Checks for the releases of a GitHub repository and downloads the latest release or all releases and pulls it into a specified directory, one for each version. .EXAMPLE .NOTES # Release notes 16/03/2023 - V0.1.0: - Initial release. #> function Get-ALZGithubRelease { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0, HelpMessage = "The IaC provider to use for the ALZ environment.")] [ValidateSet("bicep", "terraform")] [Alias("Iac")] [Alias("i")] [string] $alzIacProvider, [Parameter(Mandatory = $false, Position = 1, HelpMessage = "Please the provide the full URL of the GitHub repository you wish to check for the latest release.")] [string] $githubRepoUrl = "", [Parameter(Mandatory = $false, Position = 2, HelpMessage = "The releases to download. Specify 'all' to download all releases or 'latest' to download the latest release. Defaults to the latest release.")] [array] [Alias("version")] [Alias("v")] $release = "latest", [Parameter(Mandatory = $false, Position = 3, HelpMessage = "The directory to download the releases to. Defaults to the current directory.")] [string] [Alias("Output")] [Alias("OutputDirectory")] [Alias("O")] $directoryForReleases = "$PWD/releases", [Parameter(Mandatory = $false, Position = 4, HelpMessage = "An array of strings contianing the paths to the directories or files that you wish to keep when downloading and extracting from the releases.")] [array] $directoryAndFilesToKeep = $null, [Parameter(Mandatory = $false, Position = 4, HelpMessage = "Whether to just query the API and return the release versions.")] [switch] $queryOnly ) # Set the repository URL if not provided $bicepModuleUrl = "https://github.com/Azure/ALZ-Bicep" $terraformModuleUrl = "https://github.com/Azure/alz-terraform-accelerator" if($githubRepoUrl -eq "") { if($alzIacProvider -eq "bicep") { $githubRepoUrl = $bicepModuleUrl } elseif($alzIacProvider -eq "terraform") { $githubRepoUrl = $terraformModuleUrl } } $parentDirectory = $directoryForReleases # Bicep specific path setup if($alzIacProvider -eq "bicep") { $directoryForReleases = Join-Path $directoryForReleases "upstream-releases" } # Split Repo URL into parts $repoOrgPlusRepo = $githubRepoUrl.Split("/")[-2..-1] -join "/" Write-Verbose "=====> Checking for release on GitHub Repo: $repoOrgPlusRepo" # Get releases on repo $repoReleaseUrl = "https://api.github.com/repos/$repoOrgPlusRepo/releases/$release" if($release -ne "latest") { $repoReleaseUrl = "https://api.github.com/repos/$repoOrgPlusRepo/releases/tags/$release" } $releaseData = Invoke-RestMethod $repoReleaseUrl -SkipHttpErrorCheck -StatusCodeVariable "statusCode" if($statusCode -eq 404) { Write-Error "The release $release does not exist in the GitHub repository $githubRepoUrl - $repoReleaseUrl" throw "The release $release does not exist in the GitHub repository $githubRepoUrl - $repoReleaseUrl" } # Handle transient errors like throttling if($statusCode -ge 400 -and $statusCode -le 599) { Write-InformationColored "Retrying as got the Status Code $statusCode, which may be a tranisent error." -ForegroundColor Yellow -InformationAction Continue $releaseData = Invoke-RestMethod $repoReleaseUrl -RetryIntervalSec 3 -MaximumRetryCount 100 } $releaseTag = $releaseData.tag_name if($queryOnly) { return $releaseTag } # Check if directory exists Write-Verbose "=====> Checking if directory for releases exists: $directoryForReleases" if (!(Test-Path $directoryForReleases)) { Write-Verbose "Directory does not exist for releases, will now create: $directoryForReleases" New-Item -ItemType Directory -Path $directoryForReleases | Out-String | Write-Verbose } # Check the directory for this release $releaseDirectory = "$directoryForReleases/$releaseTag" Write-Verbose "===> Checking if directory for release version exists: $releaseDirectory" if (!(Test-Path $releaseDirectory)) { Write-Verbose "Directory does not exist for release $releaseTag, will now create: $releaseDirectory" New-Item -ItemType Directory -Path $releaseDirectory | Out-String | Write-Verbose } Write-Verbose "===> Checking if any content exists inside of $releaseDirectory" $contentInReleaseDirectory = Get-ChildItem -Path $releaseDirectory -Recurse -ErrorAction SilentlyContinue if ($null -eq $contentInReleaseDirectory) { Write-Verbose "===> Pulling and extracting release $releaseTag into $releaseDirectory" New-Item -ItemType Directory -Path "$releaseDirectory/tmp" | Out-String | Write-Verbose Invoke-WebRequest -Uri "https://github.com/$repoOrgPlusRepo/archive/refs/tags/$releaseTag.zip" -OutFile "$releaseDirectory/tmp/$releaseTag.zip" -RetryIntervalSec 3 -MaximumRetryCount 100 | Out-String | Write-Verbose Expand-Archive -Path "$releaseDirectory/tmp/$releaseTag.zip" -DestinationPath "$releaseDirectory/tmp/extracted" | Out-String | Write-Verbose $extractedSubFolder = Get-ChildItem -Path "$releaseDirectory/tmp/extracted" -Directory if ($null -ne $directoryAndFilesToKeep) { foreach ($path in $directoryAndFilesToKeep) { Write-Verbose "===> Moving $path into $releaseDirectory." Move-Item -Path "$($extractedSubFolder.FullName)/$($path)" -Destination "$releaseDirectory" -ErrorAction SilentlyContinue | Out-String | Write-Verbose } } if ($null -eq $directoryAndFilesToKeep) { Write-Verbose "===> Moving all extracted contents into $releaseDirectory." Move-Item -Path "$($extractedSubFolder.FullName)/*" -Destination "$releaseDirectory" -ErrorAction SilentlyContinue | Out-String | Write-Verbose } Remove-Item -Path "$releaseDirectory/tmp" -Force -Recurse } else { Write-InformationColored "The release directory for this version already exists and has content in it, so we are not over-writing it." -ForegroundColor Yellow -InformationAction Continue Write-Verbose "===> Content already exists in $releaseDirectory. Skipping" } # Check and replace the .env file release version if it is Bicep if($alzIacProvider -eq "bicep") { $envFilePath = Join-Path -Path $parentDirectory -ChildPath ".env" if(Test-Path $envFilePath) { Write-Verbose "===> Replacing the .env file release version with $releaseTag" (Get-Content $envFilePath) -replace "UPSTREAM_RELEASE_VERSION=.*", "UPSTREAM_RELEASE_VERSION=$releaseTag" | Set-Content $envFilePath } } return $releaseTag } |