Public/Publish-GithubRelease.ps1
function Publish-GithubRelease { <# .SYNOPSIS Publish a new release on a Github repository .FUNCTIONALITY CI/CD .EXAMPLE Publish-GithubRelease -AccessToken $mySecretToken -TagName "v1.0" Create a new release for the tag "v1.0". The name of the repository is assumed to be the same as the BHProjectName. .EXAMPLE Publish-GithubRelease -AccessToken $mySecretToken -TagName "v0.1" -Name "Beta Version 0.1" -PreRelease Create a new pre-release for the tag "v0.1". .EXAMPLE Publish-GithubRelease -AccessToken $mySecretToken -TagName "v1.0" -Draft Create a draft for a release on tag "v1.0". .EXAMPLE $release = @{ AccessToken = "00000000000000000000000" TagName = "v1.0" Name = "Version 1.0" ReleaseText = "First version of my cool thing" Draft = $true PreRelease = $false RepositoryName = "MyGithubRepository" } Publish-GithubRelease @release Create a new draft release by using splatting (more info at "about_splatting"). .LINK https://developer.github.com/v3/repos/releases/ .LINK https://blog.github.com/2013-05-16-personal-api-tokens/ #> [CmdletBinding()] param( # Personal API Token for authentication # # This sha string must be generated by a user that has push access to # the repository. # More information can be found at: # https://blog.github.com/2013-05-16-personal-api-tokens/ [Parameter( Mandatory )] [ValidateNotNullOrEmpty()] [String] $AccessToken, # Name of the Github user or organization hosting the repository [Parameter( Mandatory )] [ValidateNotNullOrEmpty()] [Alias('Owner')] [String] $RepositoryOwner, # Name of the Github repository # # Default: $env:BHProjectName [Parameter()] [ValidateNotNullOrEmpty()] [String] $RepositoryName = (Get-ProjectName), # Name of the tag [Parameter( Mandatory )] [ValidateNotNullOrEmpty()] [String] $TagName, # Specifies the commitish value that determines where the Git tag is # created from. Can be any branch or commit SHA. # # Unused if the Git tag already exists. # Default: the repository's default branch (usually master). [Alias("Commit")] [String] $TargetCommit, # Name of the release [String] $Name, # Text describing the contents of the tag. [Alias('Body')] [String] $ReleaseText, # Create a draft (unpublished) release [Switch] $Draft, # Identify the release as a prerelease [Switch] $PreRelease, # Path to the artifact to upload to the release [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateScript( { if (-not (Test-Path $_ -PathType Leaf)) { $exception = ([System.ArgumentException]"File not found") $errorId = 'ParameterValue.FileNotFound' $errorCategory = 'ObjectNotFound' $errorTarget = $_ $errorItem = New-Object -TypeName System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $errorTarget $errorItem.ErrorDetails = "No file could be found with the provided path '$_'." $PSCmdlet.ThrowTerminatingError($errorItem) } return $true } )] [Alias('File', 'FullName', 'Path')] [String[]] $Artifact ) begin { $body = @{ "tag_name" = $TagName } if ($PSBoundParameters.ContainsKey("TargetCommit")) { $body["target_commitish"] = $TargetCommit } if ($PSBoundParameters.ContainsKey("Name")) { $body["name"] = $Name } if ($PSBoundParameters.ContainsKey("ReleaseText")) { $body["body"] = $ReleaseText } if ($PSBoundParameters.ContainsKey("Draft")) { $body["draft"] = $true } if ($PSBoundParameters.ContainsKey("PreRelease")) { $body["prerelease"] = $true } $releaseParams = @{ Uri = "https://api.github.com/repos/{0}/{1}/releases" -f $RepositoryOwner, $RepositoryName Method = 'POST' Headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String( [Text.Encoding]::ASCII.GetBytes($AccessToken + ":x-oauth-basic") ) } ContentType = 'application/json' Body = $body | ConvertTo-Json ErrorAction = "Stop" } try { Set-TlsLevel -Tls12 $release = Invoke-RestMethod @releaseParams $release } catch { throw $_ } finally { Set-TlsLevel -Revert } } process { if ($Artifact) { foreach ($file in (Get-Item $Artifact)) { $body = [System.IO.File]::ReadAllBytes($file.FullName) $uri = $release.upload_url -replace "\{\?name,label\}", "?name=$($file.Name)" $assetParams = @{ Uri = $uri Method = 'POST' Headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String( [Text.Encoding]::ASCII.GetBytes($AccessToken + ":x-oauth-basic") ) } ContentType = "application/octet-stream" Body = $body } try { Set-TlsLevel -Tls12 Invoke-RestMethod @assetParams } catch { throw $_ } finally { Set-TlsLevel -Revert } } } } } |