diff --git a/tools/GitHubTools.psm1 b/tools/GitHubTools.psm1 index bc5ad6b3fb..bb4bb43309 100644 --- a/tools/GitHubTools.psm1 +++ b/tools/GitHubTools.psm1 @@ -229,4 +229,102 @@ function New-GitHubPR Invoke-RestMethod -Method Post -Uri $uri -Body $body -Headers $headers } -Export-ModuleMember -Function Copy-GitRepository,Submit-GitChanges,New-GitHubPR +function Publish-GitHubRelease +{ + param( + [Parameter(Mandatory)] + [string] + $Organization, + + [Parameter(Mandatory)] + [string] + $Repository, + + [Parameter(Mandatory)] + [string] + $Tag, + + [Parameter(Mandatory)] + [string] + $ReleaseName, + + [Parameter(Mandatory)] + [string] + $Description, + + [Parameter(Mandatory)] + [string] + $GitHubToken, + + [Parameter()] + [Alias('Branch', 'Commit')] + [string] + $Commitish, + + [Parameter()] + [string[]] + $AssetPath, + + [switch] + $Draft, + + [switch] + $Prerelease + ) + + $restParams = @{ + tag_name = $Tag + name = $ReleaseName + body = $Description + draft = [bool]$Draft + prerelease = [bool]$Prerelease + } + + if ($Commitish) + { + $restParams.target_commitish = $Commitish + } + + $restBody = ConvertTo-Json -InputObject $restParams + $uri = "https://api.github.com/repos/$Organization/$Repository/releases" + $headers = @{ + Accept = 'application/vnd.github.v3+json' + Authorization = "token $GitHubToken" + } + + $response = Invoke-RestMethod -Method Post -Uri $uri -Body $restBody -Headers $headers + + $releaseId = $response.id + $assetBaseUri = "https://uploads.github.com/repos/$Organization/$Repository/releases/$releaseId/assets" + foreach ($asset in $AssetPath) + { + $extension = [System.IO.Path]::GetExtension($asset) + $fileName = [uri]::EscapeDataString([System.IO.Path]::GetFileName($asset)) + $contentType = 'text/plain' + switch ($extension) + { + { $_ -in '.zip','.vsix' } + { + $contentType = 'application/zip' + break + } + + '.json' + { + $contentType = 'application/json' + break + } + } + + $assetUri = "${assetBaseUri}?name=$fileName" + $headers = @{ + Authorization = "token $GitHubToken" + } + # This can be very slow, but it does work + $null = Invoke-RestMethod -Method Post -Uri $assetUri -InFile $asset -ContentType $contentType -Headers $headers + } + + return $response +} + +Export-ModuleMember -Function Copy-GitRepository,Submit-GitChanges,New-GitHubPR,Publish-GitHubRelease diff --git a/tools/postReleaseScripts/publishGHRelease.ps1 b/tools/postReleaseScripts/publishGHRelease.ps1 new file mode 100644 index 0000000000..435c2f715c --- /dev/null +++ b/tools/postReleaseScripts/publishGHRelease.ps1 @@ -0,0 +1,79 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +#requires -Version 6.0 + +param( + [Parameter(Mandatory)] + [semver] + $Version, + + [Parameter(Mandatory)] + [string] + $GitHubToken, + + [Parameter(Mandatory)] + [string] + $Repository, + + [Parameter()] + [string] + $TargetFork = 'PowerShell', + + [Parameter()] + [string] + $ChangelogPath = "$PSScriptRoot/../../CHANGELOG.md", + + [Parameter()] + [string[]] + $AssetPath +) + +Import-Module "$PSScriptRoot/../GitHubTools.psm1" -Force + +<# +.SYNOPSIS +Get the release description from the CHANGELOG + +.DESCRIPTION +Gets the latest CHANGELOG entry from the CHANGELOG for use as the GitHub release description + +.PARAMETER ChangelogPath +Path to the changelog file +#> + +function GetDescriptionFromChangelog +{ + param( + [Parameter(Mandatory)] + [string] + $ChangelogPath + ) + + $lines = Get-Content -Path $ChangelogPath + # First two lines are the title and newline + # Third looks like '## vX.Y.Z-releasetag' + $sb = [System.Text.StringBuilder]::new($lines[2]) + # Read through until the next '## vX.Y.Z-releasetag' H2 + for ($i = 3; -not $lines[$i].StartsWith('## '); $i++) + { + $null = $sb.Append("`n").Append($lines[$i]) + } + + return $sb.ToString() +} + +$tag = "v$Version" + +$releaseParams = @{ + Organization = $TargetFork + Repository = $Repository + Tag = $tag + ReleaseName = $tag + Branch = "release/$Version" + AssetPath = $AssetPath + Prerelease = [bool]($Version.PreReleaseLabel) + Description = GetDescriptionFromChangelog -ChangelogPath $ChangelogPath + GitHubToken = $GitHubToken +} +Publish-GitHubRelease @releaseParams