Skip to content

Instantly share code, notes, and snippets.

@grenade
Last active January 4, 2016 02:49
Show Gist options
  • Select an option

  • Save grenade/8558101 to your computer and use it in GitHub Desktop.

Select an option

Save grenade/8558101 to your computer and use it in GitHub Desktop.
Create a GitHub release and upload an asset. If the release (identified by $release_tag_name) or asset (identified by $asset_name) exist, they will be replaced.
<#
.Synopsis
Get the last release.
.Example
.\github-last-release.ps1 -username GITHUB_USERNAME -token OAUTH_TOKEN -repo GITHUB_REPOSITORY -release_tag_name v1.0.0 -asset_name "C:\temp\MyRelease.zip" -asset_label "Zip archive"
#>
param (
[string] $api_base = "https://api.github.com",
[Parameter (Mandatory = $true)]
[string] $username,
[string] $password = $null,
[string] $token = $null,
[Parameter (Mandatory = $true)]
[string] $repo,
[string] $org = $username,
[string] $release_tag_prefix,
[string] $increment,
[int] $build_counter,
[string] $proxy_host = "proxy.{0}" -f $env:USERDNSDOMAIN,
[int] $proxy_port = 8080
)
if (!($token -or $password)) {
throw "Parameters: `$token or `$password are required."
}
$webProxy = $null
if(($proxy_host) -and (Test-Connection $proxy_host -Count 1 -Quiet)) {
$proxy = ("http://{0}:{1}" -f $proxy_host, $proxy_port)
Write-Host ("Setting proxy: {0}." -f $proxy)
$global:PSDefaultParameterValues = @{
'Invoke-RestMethod:Proxy' = $proxy
'Invoke-WebRequest:Proxy' = $proxy
'*:ProxyUseDefaultCredentials' = $true
}
$webProxy = New-Object System.Net.WebProxy($proxy)
$webProxy.useDefaultCredentials = $true
}
if ($release_tag_prefix) {
Write-Host ("Checking if release exists for tag prefix: {0}..." -f $release_tag_prefix)
$release_check_response = (Invoke-WebRequest -Uri ("{0}/repos/{1}/{2}/releases" -f $api_base, $org, $repo) -Headers @{ "Authorization" = ("token {0}" -f $token) } | ConvertFrom-Json)
if ($release_check_response) {
$release_check_response
$last_tag_name = ($release_check_response | Sort-Object id -descending | Where-Object { $_.tag_name.StartsWith($release_tag_prefix, "InvariantCultureIgnoreCase") } | Select-Object -first 1).tag_name
Write-Host ("Last tag: {0}" -f $last_tag_name)
$semVer = $last_tag_name.Split(".")
switch -casesensitive ($increment) {
"patch" {
$x = (($semVer[2] -as [int]) + 1)
Write-Host ("Next tag: {0}.{1}.{2}" -f $semVer[0], $semVer[1], $x)
Write-Host ("##teamcity[setParameter name='semverPatch' value='{0}']" -f $x)
Write-Host ("##teamcity[buildNumber '{0}.{1}.{2}.{3}']" -f $semVer[0], $semVer[1], $x, $build_counter)
}
"minor" {
$x = (($semVer[1] -as [int]) + 1)
Write-Host ("Next tag: {0}.{1}.{2}" -f $semVer[0], $x, $semVer[2])
Write-Host ("##teamcity[setParameter name='semverMinor' value='{0}']" -f $x)
Write-Host ("##teamcity[buildNumber '{0}.{1}.{2}.{3}']" -f $semVer[0], $x, $semVer[2], $build_counter)
}
"major" {
$x = (($semVer[0] -as [int]) + 1)
Write-Host ("Next tag: {0}.{1}.{2}" -f $x, $semVer[1], $semVer[2])
Write-Host ("##teamcity[setParameter name='semverMajor' value='{0}']" -f $x)
Write-Host ("##teamcity[buildNumber '{0}.{1}.{2}.{3}']" -f $x, $semVer[1], $semVer[2], $build_counter)
}
}
} else {
Write-Host ("No release found for tag: {0}." -f $release_tag_prefix)
}
}
<#
.Synopsis
Create a GitHub release and upload an asset.
If the release (identified by $release_tag_name) or asset (identified by $asset_name) exist, they will be replaced.
.Example
.\github-release.ps1 -username GITHUB_USERNAME -token OAUTH_TOKEN -repo GITHUB_REPOSITORY -release_tag_name v1.0.0 -asset_name "C:\temp\MyRelease.zip" -asset_label "Zip archive"
.Example
.\github-release.ps1 -api_base %gh_api_base% -upload_base %gh_upload_base% -username %gh_username% -token %gh_token% -repo %gh_repo% -release_tag_name "%gh_release_tag%" -release_body "%gh_release_body%" -release_prerelease -asset_name "%gh_asset_name%"" -asset_label "%gh_asset_label%" -proxy_host %proxy_host% -proxy_port %proxy_port%
.Link
http://developer.github.com/v3/
.Link
http://technet.microsoft.com/en-us/library/hh849898.aspx
.Link
https://gist.github.com/caspyin/2288960
.Link
http://stackoverflow.com/a/15646324/68115
#>
param (
[string] $api_base = "https://api.github.com",
[string] $upload_base = "https://uploads.github.com",
[Parameter (Mandatory = $true)]
[string] $username,
[string] $password = $null,
[string] $token = $null,
[Parameter (Mandatory = $true)]
[string] $repo,
[string] $org = $username,
[int] $release_id = 0,
[Parameter (Mandatory = $true)]
[string] $release_tag_name,
[string] $release_target_commitish = "master",
[string] $release_name = $release_tag_name,
[string] $release_body,
[switch] $release_draft,
[switch] $release_prerelease,
[int] $asset_id = 0,
[string] $asset_name,
[string] $asset_label,
[string] $proxy_host = "proxy.{0}" -f $env:USERDNSDOMAIN,
[int] $proxy_port = 8080
)
if (!($token -or $password)) {
throw "Parameters: `$token or `$password are required."
}
filter Invoke-Ternary {
<#
.SYNOPSIS
If-Then-Else-EndIf conditional statement.
.DESCRIPTION
The Invoke-Ternary cmdlet (alias ?:) is a shorthand replacement for the If-Then-Else-EndIf conditional statement.
#>
[CmdletBinding()]
param([Parameter(Mandatory = $true, Position = 0)]
[scriptblock] $Decider
,[Parameter(Mandatory = $true, Position = 1)]
[scriptblock] $IfTrue
,[Parameter(Mandatory = $true, Position = 2)]
[scriptblock] $IfFalse)
process {
if (&$decider) { &$ifTrue } else { &$ifFalse }
}
}
Set-Alias -Name "?:" -Value "Invoke-Ternary" -Scope "Global" -Description "If-Then-Else conditional statement" -force -confirm:$false -verbose:$false -whatif:$false
$webProxy = $null
if(($proxy_host) -and (Test-Connection $proxy_host -Count 1 -Quiet)) {
$proxy = ("http://{0}:{1}" -f $proxy_host, $proxy_port)
Write-Host ("Setting proxy: {0}." -f $proxy)
$global:PSDefaultParameterValues = @{
'Invoke-RestMethod:Proxy' = $proxy
'Invoke-WebRequest:Proxy' = $proxy
'*:ProxyUseDefaultCredentials' = $true
}
$webProxy = New-Object System.Net.WebProxy($proxy)
$webProxy.useDefaultCredentials = $true
}
if ($username -and $password -and ($token -eq $null)) {
throw "Password auth not working/implemented correctly. Provide an OAuth token."
# check for oauth token
Write-Host ("Checking for OAuth token for username: {0}." -f $username)
$token_check_response = (Invoke-WebRequest -Uri ("{0}/authorizations" -f $api_base.Replace("https://", ("https://{0}:{1}@" -f $username, $password))) | ConvertFrom-Json)
#$webClient = New-Object System.Net.WebClient
#if($webProxy -ne $null) {
# $webClient.proxy = $webProxy
#}
#$webClient.Credentials = New-Object System.Net.NetworkCredential($username, $password)
#$token_check_response = ($webClient.DownloadString(("{0}/authorizations" -f $api_base)) | ConvertFrom-Json)
$token_check_response
try{
$token = ($token_check_response | Where-Object { $_.note -eq "releases" }).token
Write-Host ("OAuth token acquired for username: {0}." -f $username)
}
catch{
$token = $null
}
if ($token -eq $null) {
# generate oauth token
Write-Host ("Generating OAuth token for username: {0}." -f $username)
$data = @{
scopes = '["public_repo"]'
note = 'releases'
}
$token_create_response = (Invoke-WebRequest -Uri ("{0}/authorizations" -f $api_base.Replace("https://", ("https://{0}:{1}@" -f $username, $password))) -Body $data -Method POST | ConvertFrom-Json)
#$token_create_response = ($webClient.UploadValues(("{0}/authorizations" -f $api_base), $data) | ConvertFrom-Json)
$token_create_response
$token = $token_create_response.token
}
}
if (($release_id -eq 0) -and ($release_tag_name)) {
# check for release
Write-Host ("Checking if release exists for tag: {0}." -f $release_tag_name)
$release_check_response = (Invoke-WebRequest -Uri ("{0}/repos/{1}/{2}/releases" -f $api_base, $org, $repo) -Headers @{ "Authorization" = ("token {0}" -f $token) } | ConvertFrom-Json)
if ($release_check_response) {
$release_check_response
$release_id = ($release_check_response | Where-Object { $_.tag_name -eq $release_tag_name }).id
} else {
Write-Host ("No release found for tag: {0}." -f $release_tag_name)
$release_id = 0
}
}
if (($release_id -eq 0) -and ($release_tag_name)) {
# create release
if (!$release_body) {
throw "Parameter: `$release_body is required."
}
Write-Host ("Creating release for tag: {0}." -f $release_tag_name)
$data = @{
tag_name = $release_tag_name
target_commitish = $release_target_commitish
name = $release_name
body = $release_body
draft = ?: { $SCRIPT:MyInvocation.BoundParameters["release_draft"].IsPresent -eq $true } { $true } { $false }
prerelease = ?: { $SCRIPT:MyInvocation.BoundParameters["release_prerelease"].IsPresent -eq $true } { $true } { $false }
}
$release_create_response = (Invoke-WebRequest -Uri ("{0}/repos/{1}/{2}/releases" -f $api_base, $org, $repo) -Headers @{ "Authorization" = ("token {0}" -f $token) } -Body (ConvertTo-Json $data) -Method POST | ConvertFrom-Json)
if ($release_create_response) {
$release_create_response
$release_id = $release_create_response.id
} else {
Write-Host ("Failed to create release for tag: {0}." -f $release_tag_name)
$release_id = 0
}
} elseif (($release_id -ne 0) -and ($release_tag_name)) {
# update release
Write-Host ("Updating release for tag: {0}." -f $release_tag_name)
$data = @{
tag_name = $release_tag_name
target_commitish = $release_target_commitish
name = $release_name
body = $release_body
draft = ?: { $SCRIPT:MyInvocation.BoundParameters["release_draft"].IsPresent -eq $true } { $true } { $false }
prerelease = ?: { $SCRIPT:MyInvocation.BoundParameters["release_prerelease"].IsPresent -eq $true } { $true } { $false }
}
$release_update_response = (Invoke-WebRequest -Uri ("{0}/repos/{1}/{2}/releases/{3}" -f $api_base, $org, $repo, $release_id) -Headers @{ "Authorization" = ("token {0}" -f $token) } -Body (ConvertTo-Json $data) -Method POST | ConvertFrom-Json)
$release_update_response
$release_id = $release_update_response.id
}
if (($release_id -ne 0) -and ($asset_name)) {
# delete asset
$asset_filename = [System.IO.Path]::GetFileName($asset_name);
Write-Host ("Checking if asset: {0}, exists for release: {1}." -f $asset_filename, $release_tag_name)
$asset_check_response = (Invoke-WebRequest -Uri ("{0}/repos/{1}/{2}/releases/{3}/assets" -f $api_base, $org, $repo, $release_id) -Headers @{ "Authorization" = ("token {0}" -f $token) } | ConvertFrom-Json)
$asset_check_response
if ($asset_check_response) {
$asset_check_response
$asset_id = ($asset_check_response | Where-Object { $_.name -eq $asset_filename }).id
} else {
Write-Host ("No asset named: {0}, found for release: {1}." -f $asset_filename, $release_tag_name)
$asset_id = 0
}
if($asset_id -ne 0) {
Write-Host ("Deleting asset: {0}, with id: {1}." -f $asset_filename, $asset_id)
$url = ("{0}/repos/{1}/{2}/releases/assets/{3}" -f $api_base, $org, $repo, $asset_id)
$method = "DELETE"
Write-Host ("HTTP Request: {0} {1}" -f $method, $url)
$asset_delete_response = (Invoke-WebRequest -Uri $url -Headers @{ "Authorization" = ("token {0}" -f $token) } -Method $method)
$asset_delete_response
$asset_id = 0
} else {
Write-Host ("Asset: {0}, for release: {1} does not already exist." -f $asset_filename, $release_tag_name)
}
}
if (($release_id -ne 0) -and ($asset_id -eq 0) -and ($asset_name)) {
# upload asset
Write-Host ("Uploading asset: {0}, for release: {1}." -f $asset_filename, $release_tag_name)
$url = ("{0}/repos/{1}/{2}/releases/{3}/assets?name={4}" -f $upload_base, $org, $repo, $release_id, [System.IO.Path]::GetFileName($asset_name))
$webClient = New-Object System.Net.WebClient
if($webProxy -ne $null) {
$webClient.proxy = $webProxy
}
$webClient.Headers.Add("Authorization", ("token {0}" -f $token));
$webClient.Headers.Add("Content-Type", "application/octet-stream");
$asset_upload_binary_response = $webClient.UploadData($url, [System.IO.File]::ReadAllBytes($asset_name))
$asset_upload_response = ([System.Text.Encoding]::ASCII.GetString($asset_upload_binary_response) | ConvertFrom-Json)
$asset_upload_response
$asset_id = [int] $asset_upload_response.id
} else {
# update asset
}
if (($release_id -ne 0) -and ($asset_id -ne 0) -and ($asset_name) -and ($asset_label)) {
# label asset
Write-Host ("Labeling asset: {0}, for release: {1}, with label: {2}." -f $asset_filename, $release_tag_name, $asset_label)
$data = @{
name = $asset_name
label = $asset_label
}
$asset_label_response = (Invoke-WebRequest -Uri ("{0}/repos/{1}/{2}/releases/assets/{3}" -f $api_base, $org, $repo, $asset_id) -Headers @{ "Authorization" = ("token {0}" -f $token) } -Body (ConvertTo-Json $data) -Method POST | ConvertFrom-Json)
$asset_label_response
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment