Tasks/New-WhiskeyGitHubRelease.ps1
function New-WhiskeyGitHubRelease { [CmdletBinding()] [Whiskey.Task('GitHubRelease')] param( [Parameter(Mandatory=$true)] [Whiskey.Context] $TaskContext, [Parameter(Mandatory=$true)] [hashtable] $TaskParameter ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $apiKeyID = $TaskParameter['ApiKeyID'] if( -not $apiKeyID ) { Stop-WhiskeyTask -TaskContext $TaskContext -Message ('Property "ApiKeyID" is mandatory. It should be set to the ID of the API key to use when talking to the GitHub API. API keys are added to your build with the "Add-WhiskeyApiKey" function.') return } $apiKey = Get-WhiskeyApiKey -Context $TaskContext -ID $apiKeyID -PropertyName 'ApiKeyID' $headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($apiKey + ":x-oauth-basic")) } $repositoryName = $TaskParameter['RepositoryName'] if( -not $repositoryName ) { Stop-WhiskeyTask -TaskContext $TaskContext -Message ('Property "RepositoryName" is mandatory. It should be the owner and repository name of the repository you want to access as a URI path, e.g. OWNER/REPO.') return } if( $repositoryName -notmatch '^[^/]+/[^/]+$' ) { Stop-WhiskeyTask -TaskContext $TaskContext -Message ('Property "RepositoryName" is invalid. It should be the owner and repository name of the repository you want to access as a URI path, e.g. OWNER/REPO.') return } $baseUri = [uri]'https://api.github.com/repos/{0}' -f $repositoryName [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12 function Invoke-GitHubApi { [CmdletBinding(DefaultParameterSetName='NoBody')] param( [Parameter(Mandatory=$true)] [uri] $Uri, [Parameter(Mandatory=$true,ParameterSetName='FileUpload')] [string] $ContentType, [Parameter(Mandatory=$true,ParameterSetName='FileUpload')] [string] $InFile, [Parameter(Mandatory=$true,ParameterSetName='JsonRequest')] $Parameter, [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = [Microsoft.PowerShell.Commands.WebRequestMethod]::Post ) $optionalParams = @{ } if( $PSCmdlet.ParameterSetName -eq 'JsonRequest' ) { if( $Parameter ) { $optionalParams['Body'] = $Parameter | ConvertTo-Json Write-WhiskeyVerbose -Context $TaskContext -Message $optionalParams['Body'] } $ContentType = 'application/json' } elseif( $PSCmdlet.ParameterSetName -eq 'FileUpload' ) { $optionalParams['InFile'] = $InFile } try { Invoke-RestMethod -Uri $Uri -Method $Method -Headers $headers -ContentType $ContentType @optionalParams } catch { if( $ErrorActionPreference -eq 'Ignore' ) { $Global:Error.RemoveAt(0) } Stop-WhiskeyTask -TaskContext $TaskContext -Message ('GitHub API call to "{0}" failed: {1}' -f $uri,$_) return } } $tag = $TaskParameter['Tag'] if( -not $tag ) { Stop-WhiskeyTask -TaskContext $TaskContext -Message ('Property "Tag" is mandatory. It should be the tag to create in your repository for this release. This is usually a version number. We recommend using the `$(WHISKEY_SEMVER2_NO_BUILD_METADATA)` variable to use the version number of the current build.') return } $release = Invoke-GitHubApi -Uri ('{0}/releases/tags/{1}' -f $baseUri,[uri]::EscapeUriString($tag)) -Method Get -ErrorAction Ignore $createOrEditMethod = [Microsoft.PowerShell.Commands.WebRequestMethod]::Post $actionDescription = 'Creating' $createOrEditUri = '{0}/releases' -f $baseUri if( $release ) { $createOrEditMethod = [Microsoft.PowerShell.Commands.WebRequestMethod]::Patch $actionDescription = 'Updating' $createOrEditUri = $release.url } $releaseData = @{ tag_name = $tag } if( $TaskParameter['Commitish'] ) { $releaseData['target_commitish'] = $TaskParameter['Commitish'] } if( $TaskParameter['Name'] ) { $releaseData['name'] = $TaskParameter['Name'] } if( $TaskParameter['Description'] ) { $releaseData['body'] = $TaskParameter['Description'] } Write-WhiskeyInfo -Context $TaskContext -Message ('{0} release "{1}" "{2}" at commit "{3}".' -f $actionDescription,$TaskParameter['Name'],$tag,$TaskContext.BuildMetadata.ScmCommitID) $release = Invoke-GitHubApi -Uri $createOrEditUri -Parameter $releaseData -Method $createOrEditMethod $release if( $TaskParameter['Assets'] ) { $existingAssets = Invoke-GitHubApi -Uri $release.assets_url -Method Get $assetIdx = 0 foreach( $asset in $TaskParameter['Assets'] ) { $basePropertyName = 'Assets[{0}]' -f $assetIdx++ $assetPath = $asset['Path'] | Resolve-WhiskeyTaskPath -TaskContext $TaskContext -PropertyName ('{0}.Path:' -f $basePropertyName) -PathType File if( -not $assetPath ) { continue } $assetName = $assetPath | Split-Path -Leaf $assetLabel = $asset['Name'] if( $assetLabel -eq $null ) { $assetLabel = "" } $existingAsset = $existingAssets | Where-Object { $_ -and $_.name -eq $assetName } if( $existingAsset ) { Write-WhiskeyInfo -Context $TaskContext -Message ('Updating file "{0}".' -f $assetName) Invoke-GitHubApi -Method Patch -Uri $existingAsset.url -Parameter @{ name = $assetName; label = $assetLabel } } else { $uri = $release.upload_url -replace '{[^}]+}$' $uri = '{0}?name={1}' -f $uri,[uri]::EscapeDataString($assetName) if( $assetLabel ) { $uri = '{0}&label={1}' -f $uri,[uri]::EscapeDataString($assetLabel) } Write-WhiskeyInfo -Context $TaskContext -Message ('Uploading file "{0}".' -f $assetPath) $contentType = $asset['ContentType'] if( -not $contentType ) { Stop-WhiskeyTask -TaskContext $TaskContext -PropertyName $basePropertyName -Message ('Property "ContentType" is mandatory. It must be the "{0}" file''s media type. For a list of acceptable types, see https://www.iana.org/assignments/media-types/media-types.xhtml.' -f $assetPath) continue } Invoke-GitHubApi -Method Post -Uri $uri -ContentType $asset['ContentType'] -InFile $assetPath } } } } |