Last active
August 6, 2024 00:54
-
-
Save gabriel-vanca/4e6a2f17ff946d2d51a3ad7222eb29a9 to your computer and use it in GitHub Desktop.
Get-ReleaseFromGithub
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Test-Repo { | |
param ( | |
[Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [String] $Repo | |
) | |
$repoName = $NULL | |
try { | |
$testUri = "https://api.github.com/repos/$Repo" | |
$temp = (Invoke-RestMethod -Method GET -Uri $testUri) | |
$repoName = $temp.name | |
Write-Host "Repo $repoName is valid" -ForegroundColor DarkGreen | |
} catch { | |
throw "Invalid repo" | |
} | |
try { | |
$testUri = "https://api.github.com/repos/$Repo/releases?per_page=100" | |
$temp = (Invoke-RestMethod -Method GET -Uri $testUri) | |
$releaseCount = ($temp | Where-Object prerelease -like $False).Count | |
$prereleaseCount = ($temp | Where-Object prerelease -like $True).Count | |
Write-Host "Repo $repoName has $releaseCount full releases and $prereleaseCount prereleases within the last 100 releases" -ForegroundColor DarkGreen | |
if(($releaseCount -eq 0) -and ($prereleaseCount -eq 0)) { | |
throw "No valid releases" | |
} | |
} catch { | |
throw "No valid releases" | |
} | |
return $True | |
} | |
function New-TemporaryDirectory { | |
[Cmdletbinding()] | |
[Alias('newtempdir')] | |
param() | |
do { | |
# Outer loop checks against race condition | |
do { | |
# Inner loop checks against collision | |
$tempDirPath = Join-Path $env:TEMP ($([System.IO.Path]::GetRandomFileName()) + ".tmp") | |
} while (Test-Path $tempDirPath) | |
$tempFile = New-Item -ItemType Directory -Path $tempDirPath -ErrorAction SilentlyContinue | |
} while (-not $tempFile) | |
return $tempFile | |
} | |
function Get-ReleaseFromGithub { | |
[CmdletBinding( | |
DefaultParameterSetName="LatestReleaseFiles" | |
)] | |
param ( | |
[Parameter(Mandatory = $True, ParameterSetName = "LatestReleaseFiles", Position = 0)] | |
[Parameter(Mandatory = $True, ParameterSetName = "LatestPrereleaseFiles", Position = 0)] | |
[Parameter(Mandatory = $True, ParameterSetName = "TargetedReleaseFiles", Position = 0)] | |
[Parameter(Mandatory = $True, ParameterSetName = "LatestReleaseExtensions", Position = 0)] | |
[Parameter(Mandatory = $True, ParameterSetName = "LatestPrereleaseExtensions", Position = 0)] | |
[Parameter(Mandatory = $True, ParameterSetName = "TargetedReleaseExtensions", Position = 0)] | |
[ValidateNotNullOrEmpty()] | |
[string] $Repo, | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestReleaseFiles", Position = 1)] | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestPrereleaseFiles", Position = 1)] | |
[Parameter(Mandatory = $False, ParameterSetName = "TargetedReleaseFiles", Position = 1)] | |
[string[]] $Files = $NULL, | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestReleaseExtensions", Position = 1)] | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestPrereleaseExtensions", Position = 1)] | |
[Parameter(Mandatory = $False, ParameterSetName = "TargetedReleaseExtensions", Position = 1)] | |
[string[]] $Extensions = $NULL, | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestReleaseFiles", Position = 2)] | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestReleaseExtensions", Position = 2)] | |
[Switch] $IncludePreleases, | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestPrereleaseFiles", Position = 2)] | |
[Parameter(Mandatory = $False, ParameterSetName = "LatestPrereleaseExtensions", Position = 2)] | |
[Switch] $IncludePreleasesOnly, | |
[Parameter(Mandatory = $True, ParameterSetName = "TargetedReleaseFiles", Position = 2)] | |
[Parameter(Mandatory = $True, ParameterSetName = "TargetedReleaseExtensions", Position = 2)] | |
[ValidateNotNullOrEmpty()] | |
[string] $Tag, | |
[Parameter(Mandatory = $False, Position = 3)] | |
[ValidateScript({ Test-Path $_ })] | |
[string] $DestinationPath = $NULL | |
) | |
BEGIN { | |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls13 | |
} | |
PROCESS { | |
# See API reference https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28 | |
switch -Wildcard ($PSCmdlet.ParameterSetName) { | |
"LatestRelease*" { | |
if($IncludePreleases) { | |
# Releases and Prereleases | |
$releasesUri = "https://api.github.com/repos/$Repo/releases?per_page=1" | |
} else { | |
# Releases only | |
$releasesUri = "https://api.github.com/repos/$Repo/releases/latest" | |
} | |
try { | |
$fullReleaseSet = Invoke-RestMethod -Method GET -Uri $releasesUri | |
$Tag = $fullReleaseSet.tag_name | |
} | |
catch { | |
Test-Repo $Repo | |
} | |
break; | |
} | |
"LatestPrerelease*" { | |
# Prereleases only | |
$releasesUri = "https://api.github.com/repos/$Repo/releases?per_page=100" | |
# Using "| Select-Object -First 1" over "[0]" so as not to get a "InvalidOperation: Cannot index into a null array." error when there are no matching releases | |
# Make sure the Invoke segment is in () ; otherwise you'll get an empty array | |
try { | |
$fullReleaseSet = (Invoke-RestMethod -Method GET -Uri $releasesUri) | Where-Object prerelease -like $True | Sort-Object @{Expression = "tag_name"; Descending = $true} | Select-Object -First 1 | |
$Tag = $fullReleaseSet.tag_name | |
} | |
catch { | |
Test-Repo $Repo | |
} | |
break; | |
} | |
"TargetedRelease*" { | |
$releasesUri = "https://api.github.com/repos/$Repo/releases/tags/$Tag" | |
try { | |
$fullReleaseSet = Invoke-RestMethod -Method GET -Uri $releasesUri | |
} | |
catch { | |
if(Test-Repo $Repo) { | |
throw "Tag not valid" | |
} | |
} | |
# -ieq is the explicitly case-insensitive version of -eq. | |
if($fullReleaseSet.tag_name -ieq $Tag) { | |
Write-Verbose "Targeted release obtained succesfully" | |
} else { | |
throw "Targeted release failed" | |
} | |
break; | |
} | |
} | |
if($fullReleaseSet -and $Tag) { | |
Write-Host "Release obtained succesfully" | |
} else { | |
throw "Obtaining release failed for unknown reasons" | |
} | |
$fullReleaseSet.assets | foreach-object{$_ | Add-Member -MemberType NoteProperty -Name extension -Value ([io.path]::GetExtension($_.name)) } | |
$fullReleaseSet.assets | foreach-object{$_ | Add-Member -MemberType NoteProperty -Name nameWithoutExtension -Value ([io.path]::GetFileNameWithoutExtension($_.name))} | |
$releaseAssets = $NULL | |
switch -Wildcard ($PSCmdlet.ParameterSetName) { | |
"*Files*" { | |
$releaseAssets = $fullReleaseSet.assets | Where-Object {($.name -in $Files) -or ($.nameWithoutExtension -in $Files)} | |
break; | |
} | |
"*Extensions*" { | |
$releaseAssets = $fullReleaseSet.assets | Where-Object {$.extension -in $Extensions} | |
break; | |
} | |
} | |
if(!$releaseAssets) { | |
throw "No matching assets" | |
} | |
$tempDir = New-TemporaryDirectory | |
foreach ($currentAsset in $releaseAssets) { | |
} | |
$download = "https://github.com/$repo/releases/download/$tag/$file" | |
$name = $file.Split(".")[0] | |
$zip = "$name-$tag.zip" | |
$dir = "$name-$tag" | |
Write-Host Dowloading latest release | |
Invoke-WebRequest $download -Out $zip | |
Write-Host Extracting release files | |
Expand-Archive $zip -Force | |
# Cleaning up target dir | |
Remove-Item $name -Recurse -Force -ErrorAction SilentlyContinue | |
# Moving from temp dir to target dir | |
Move-Item $dir\$name -Destination $name -Force | |
# Removing temp files | |
Remove-Item $zip -Force | |
Remove-Item $dir -Recurse -Force | |
} | |
END { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment