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 = 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] $releases = @("latest"), [Parameter(Mandatory = $false, Position = 3, HelpMessage = "The directory to download the releases to. Defaults to the current directory.")] [string] $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 ) # Split Repo URL into parts $repoOrgPlusRepo = $githubRepoUrl.Split("/")[-2..-1] -join "/" Write-Verbose "=====> Checking for releases on GitHub Repo: $repoOrgPlusRepo" # Get releases on repo $repoReleasesUrl = "https://api.github.com/repos/$repoOrgPlusRepo/releases" $allRepoReleases = Invoke-RestMethod $repoReleasesUrl -RetryIntervalSec 3 -MaximumRetryCount 100 Write-Verbose "=====> All available releases on GitHub Repo: $repoOrgPlusRepo" $allRepoReleases | Select-Object name, tag_name, published_at, prerelease, draft, html_url | Format-Table -AutoSize | Out-String | Write-Verbose # Get latest release on repo $latestRepoRelease = $allRepoReleases | Where-Object { $_.prerelease -eq $false } | Where-Object { $_.draft -eq $false } | Sort-Object -Descending published_at | Select-Object -First 1 # replace latest with the tag of the latest release if ($releases -contains "latest") { $releases += $latestRepoRelease.tag_name $releases = $releases | Where-Object { $_ -ne "latest" } } Write-Verbose "=====> Latest available release on GitHub Repo: $repoOrgPlusRepo" $latestRepoRelease | Select-Object name, tag_name, published_at, prerelease, draft, html_url | Format-Table -AutoSize | Out-String | Write-Verbose # 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 } # if all is specified add all the releases to the array and remove all if ($releases -contains "all") { $releases = $allRepoReleases | Select-Object -ExpandProperty tag_name $releases = $releases | Where-Object { $_ -ne "all" } } # Remove all the releases that were not found foreach ($release in $releases) { if (($allRepoReleases | Where-Object { $_.tag_name -eq $release } | Measure-Object).Count -eq 0) { Write-Warning "Release $release was not found on GitHub Repo: $repoOrgPlusRepo" $releases = $releases | Where-Object { $_ -ne $release } } } $selectedReleases = $allRepoReleases | Where-Object { $releases -contains $_.tag_name } if($queryOnly) { return $selectedReleases } foreach ($release in $selectedReleases) { # Check the firectory for this release $releaseDirectory = "$directoryForReleases/$($release.tag_name)" Write-Verbose "===> Checking if directory for release version exists: $releaseDirectory" if (!(Test-Path $releaseDirectory)) { Write-Verbose "Directory does not exist for release $($release.tag_name), 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 $($release.tag_name) into $releaseDirectory" New-Item -ItemType Directory -Path "$releaseDirectory/tmp" | Out-String | Write-Verbose Invoke-WebRequest -Uri "https://github.com/$repoOrgPlusRepo/archive/refs/tags/$($release.tag_name).zip" -OutFile "$releaseDirectory/tmp/$($release.tag_name).zip" -RetryIntervalSec 3 -MaximumRetryCount 100 | Out-String | Write-Verbose Expand-Archive -Path "$releaseDirectory/tmp/$($release.tag_name).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-Verbose "===> Content already exists in $releaseDirectory. Skipping" } } return $selectedReleases } |