functions/external/Get-PwshReleases.ps1
function Get-PwshReleases { [CmdletBinding()] param( [Parameter(Position = 0)] [ValidateScript( { $releaseVersionTest = [System.Text.RegularExpressions.Regex]::new("^(\d{1,}\.\d{1,})$").Match($PSItem) if (($releaseVersionTest.Success -eq $false) -and ($null -ne $PSItem)) { throw "The provided input is in the incorrect format. An example of an acceptable input is '7.1'." } else { $true } } )] [string]$FilterReleaseVersion, [Parameter(Position = 1)] [switch]$NoPreReleases, [Parameter(Position = 2)] [string]$FilterAssetsByPlatform, [Parameter(Position = 3)] [string]$FilterAssetsByArchitecture, [Parameter(Position = 4)] [string]$FilterAssetsByFileType ) $releases = [System.Collections.Generic.List[PwshReleaseItem]]::new() $apiUri = "https://api.github.com/repos/PowerShell/PowerShell/releases" $paginationIsFinished = $false $lastPage = $null while ($paginationIsFinished -eq $false) { Write-Verbose "Getting content from '$($apiUri)'" $currentProgressPreference = $ProgressPreference switch ($currentProgressPreference -eq "Continue") { $true { $ProgressPreference = "SilentlyContinue" break } } try { $webRequest = Invoke-WebRequest -Uri $apiUri -Method "Get" -Verbose:$false -ErrorAction "Stop" } catch { $errorDetails = $PSItem.Exception $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( [System.Exception]::new("An error occurred while retrieving data from the GitHub API."), "GitHubApiCallError", [System.Management.Automation.ErrorCategory]::ConnectionError, $errorDetails ) ) } $ProgressPreference = $currentProgressPreference $apiResponseData = $webRequest.Content | ConvertFrom-Json Write-Verbose "Parsing response data" foreach ($releaseItem in $apiResponseData) { $releaseVersionString = Get-PwshReleaseReleaseVersion -InputString $releaseItem.tag_name $allHashesRegex = [System.Text.RegularExpressions.Regex]::new("#{3} SHA256 Hashes of the release artifacts\r\s+(?'hashList'(?s).+)") $allHashesMatch = $allHashesRegex.Match($releaseItem.body) $extractHashesRegex = [System.Text.RegularExpressions.Regex]::new("- (?'fileName'.+?)\n - (?'fileHash'.+?)\n") $extractHashesMatches = $extractHashesRegex.Matches($allHashesMatch.Groups['hashList'].Value) $fileHashes = [System.Collections.Generic.List[pscustomobject]]::new() foreach ($item in $extractHashesMatches) { $fileHashes.Add( [pscustomobject]@{ "FileName" = $item.Groups['fileName'].Value.Trim(); "FileHash" = $item.Groups['fileHash'].Value.Trim(); } ) } $assetList = Invoke-PwshReleaseParseAssetItem -Assets $releaseItem.assets -FileHashes $fileHashes switch ([string]::IsNullOrEmpty($FilterAssetsByPlatform)) { $false { $assetList = [PwshReleaseAssetItem[]]($assetList | FilterAssetPlatforms -Platform $FilterAssetsByPlatform) break } } switch ([string]::IsNullOrEmpty($FilterAssetsByArchitecture)) { $false { $assetList = [PwshReleaseAssetItem[]]($assetList | FilterAssetArchitectures -Architecture $FilterAssetsByArchitecture) break } } switch ([string]::IsNullOrEmpty($FilterAssetsByFileType)) { $false { $assetList = [PwshReleaseAssetItem[]]($assetList | FilterAssetFileTypes -FileType $FilterAssetsByFileType) break } } $releases.Add( [PwshReleaseItem]@{ "Name" = $releaseItem.name; "ReleaseVersion" = $releaseVersionString; "Tag" = $releaseItem.tag_name; "ReleaseDate" = $releaseItem.published_at; "IsPreRelease" = $releaseItem.prerelease; "Assets" = $assetList; "ReleasePage" = $releaseItem.html_url; } ) } Write-Verbose "Checking for additional pages." $doesLinkKeyExist = $webRequest.Headers.ContainsKey("Link") switch ($doesLinkKeyExist) { $true { $links = Get-PwshReleaseHeaderLinks -ResponseObject $webRequest $nextPageInHeaders = $links | Where-Object { $PSItem.Rel -eq "next" } $lastPageInHeaders = $links | Where-Object { $PSItem.Rel -eq "last" } switch (($null -eq $lastPage) -and ($null -ne $lastPageInHeaders)) { $true { Write-Verbose "Last page is '$($lastPageInHeaders.Link)'" $lastPage = $lastPageInHeaders break } } switch (($apiUri -eq $lastPage.Link) -or ($doesLinkKeyExist -eq $false)) { $true { Write-Verbose "No more pages to process." $paginationIsFinished = $true break } Default { Write-Verbose "Continuing to next page." $apiUri = $nextPageInHeaders.Link break } } break } } } switch ($NoPreReleases) { $true { Write-Verbose "Filtering out pre-release items" $releases = $releases | Where-Object { $PSItem.IsPreRelease -ne $true } break } } switch ([string]::IsNullOrEmpty($FilterReleaseVersion)) { $false { Write-Verbose "Filtering release versions with '$($FilterReleaseVersion)'" $releases = $releases | Where-Object { $PSItem.ReleaseVersion -eq $FilterReleaseVersion } break } } return $releases } |