Skip to content

Automate more of the release #3458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .vsts-ci/azure-pipelines-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ jobs:
- job: 'ReleaseBuild'
displayName: 'Build release'
pool:
name: 'Package ES Standard Build'
demands: DotNetFramework
name: '1ES'
demands: ImageOverride -equals MMS2019
variables:
- group: ESRP
steps:
Expand Down
18 changes: 4 additions & 14 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,11 @@ Import-Module ./tools/ReleaseTools.psm1
Update-Changelog -RepositoryName PowerShellEditorServices -Version <version>
Update-Changelog -RepositoryName vscode-powershell -Version <version>
# Amend changelog as necessary
Update-Version -RepositoryName PowerShellEditorServices
Update-Version -RepositoryName vscode-powershell
# Push branches to GitHub and ADO
# Open PRs for review
# Download and test assets (assert correct PSES is included)
New-DraftRelease -RepositoryName PowerShellEditorServices
New-DraftRelease -RepositoryName vscode-powershell
# Point releases to branches for automatic tagging
# Upload PowerShellEditorServices.zip (for other extensions)
# Upload VSIX and Install-VSCode.ps1
# Publish draft releases and merge (don't squash!) branches
New-DraftRelease -RepositoryName PowerShellEditorServices -Assets "PowerShellEditorServices.zip"
New-DraftRelease -RepositoryName vscode-powershell -Assets "powershell-YYYY.M.X.vsix", "Install-VSCode.ps1"
# Check telemetry for stability before releasing
# Publish draft releases and merge (don't squash!) branches
vsce publish --packagePath ./PowerShell-<version>.vsix
# Update Install-VSCode.ps1 on gallery
Publish-Script -Path ./Install-VSCode.ps1 -NuGetApiKey (Get-Secret "PowerShell Gallery API Key" -AsPlainText)
Expand All @@ -98,7 +91,7 @@ For PowerShellEditor Services, we simply follow semantic versioning, e.g.
generally used directly: it's a library consumed by other projects which
themselves use preview releases for beta testing.

For the VS Code PowerShell Extension, our version follows `vYYYY.MM.X`, that is:
For the VS Code PowerShell Extension, our version follows `vYYYY.M.X`, that is:
current year, current month, and patch version (not day). This is not semantic
versioning because of issues with how the VS Code marketplace and extension
hosting API itself uses our version number. This scheme _does not_ mean we
Expand Down Expand Up @@ -137,7 +130,4 @@ use the same code which includes dependencies).

* `Update-Changelog` should verify the version is in the correct format
* `Update-Changelog` could be faster by not downloading _every_ PR
* `Update-Changelog` should use exactly two emoji and in the right order
* `Update-Version` could be run by `Update-Changelog`
* The build should emit an appropriately named VSIX instead of us manually renaming it
* A `Publish-Binaries` function could be written to push the binaries out
124 changes: 94 additions & 30 deletions tools/ReleaseTools.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ function Get-Bullets {
'TylerLeonhardt'
)

$LabelEmoji = @{
$IssueEmojis = @{
'Issue-Enhancement' = '✨'
'Issue-Bug' = '🐛'
'Issue-Performance' = '⚡️'
}

$AreaEmojis = @{
'Area-Build & Release' = '👷'
'Area-Code Formatting' = '💎'
'Area-Configuration' = '🔧'
Expand Down Expand Up @@ -81,12 +84,9 @@ function Get-Bullets {
process {
$PullRequests | ForEach-Object {
# Map all the labels to emoji (or use a default).
# NOTE: Whitespacing here is weird.
$emoji = if ($_.labels) {
$LabelEmoji[$_.labels.LabelName] -join ""
} else {
'#️⃣ 🙏'
}
$labels = if ($_.labels) { $_.labels.LabelName } else { "" }
$issueEmoji = $IssueEmojis[$labels] + "#️⃣" | Select-Object -First 1
$areaEmoji = $AreaEmojis[$labels] + "🙏" | Select-Object -First 1

# Get a linked issue number if it exists (or use the PR).
$link = if ($_.body -match $IssueRegex) {
Expand All @@ -105,7 +105,7 @@ function Get-Bullets {
}

# Put the bullet point together.
("-", $emoji, "[$link]($($_.html_url))", "-", "$($_.title).", $thanks -join " ").Trim()
("-", $issueEmoji, $areaEmoji, "[$link]($($_.html_url))", "-", "$($_.title).", $thanks -join " ").Trim()
}
}
}
Expand Down Expand Up @@ -139,13 +139,17 @@ function Get-FirstChangelog {
Creates and checks out `release/v<version>` if not already on it.
#>
function Update-Branch {
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[string]$Version
)
$branch = git branch --show-current
if ($branch -ne "release/v$Version") {
git checkout -b "release/v$Version"
$Branch = git branch --show-current
$NewBranch = "release/v$Version"
if ($Branch -ne $NewBranch) {
if ($PSCmdlet.ShouldProcess($NewBranch, "git checkout -b")) {
git checkout -b $NewBranch
}
}
}

Expand Down Expand Up @@ -202,8 +206,7 @@ function Update-Changelog {
Where-Object { -not $_.user.UserName.EndsWith("[bot]") } |
Where-Object { "Ignore" -notin $_.labels.LabelName } |
Where-Object { -not $_.title.StartsWith("[Ignore]") } |
Where-Object { -not $_.title.StartsWith("Update CHANGELOG") } |
Where-Object { -not $_.title.StartsWith("Bump version") } |
Where-Object { -not $_.title.StartsWith("Release ``v") } |
Get-Bullets -RepositoryName $RepositoryName

$NewSection = switch ($RepositoryName) {
Expand Down Expand Up @@ -235,12 +238,15 @@ function Update-Changelog {
$CurrentChangelog[2..$CurrentChangelog.Length]
) | Set-Content -Encoding utf8NoBOM -Path $ChangelogFile

if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git")) {
Update-Branch -Version $Version.Substring(1) # Has "v" prefix
Update-Branch -Version $Version.Substring(1) # Has "v" prefix

if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git commit")) {
git add $ChangelogFile
git commit -m "Update CHANGELOG for ``$Version``"
}

Update-Version -RepositoryName $RepositoryName

Pop-Location
}

Expand All @@ -250,18 +256,18 @@ function Update-Changelog {
.DESCRIPTION
Note that our Git tags and changelog prefix all versions with `v`.

PowerShellEditorServices: version is `x.y.z-preview.d`
PowerShellEditorServices: version is `X.Y.Z-preview`

- PowerShellEditorServices.psd1:
- `ModuleVersion` variable with `'x.y.z'` string, no pre-release info
- `ModuleVersion` variable with `'X.Y.Z'` string, no pre-release info
- PowerShellEditorServices.Common.props:
- `VersionPrefix` field with `x.y.z`
- `VersionPrefix` field with `X.Y.Z`
- `VersionSuffix` field with pre-release portion excluding hyphen

vscode-powershell: version is `yyyy.mm.x-preview`
vscode-powershell: version is `YYYY.M.X-preview`

- package.json:
- `version` field with `"x.y.z"` and no prefix or suffix
- `version` field with `"X.Y.Z"` and no prefix or suffix
- `preview` field set to `true` or `false` if version is a preview
- `name` field has `-preview` appended similarly
- `displayName` field has ` Preview` appended similarly
Expand Down Expand Up @@ -322,11 +328,62 @@ function Update-Version {
}
}

Update-Branch -Version $Version

if ($PSCmdlet.ShouldProcess("$RepositoryName/v$Version", "git commit")) {
Update-Branch -Version $Version
git commit -m "Bump version to ``v$Version``"
} # TODO: Git reset to unstage

New-ReleasePR -RepositoryName $RepositoryName

Pop-Location
}

<#
.SYNOPSIS
Creates a new draft GitHub PR from the release branch.
.DESCRIPTION
Pushes the release branch to `origin` and then opens a draft PR.
#>
function New-ReleasePR {
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[ValidateSet([RepoNames])]
[string]$RepositoryName
)
# NOTE: This a side effect neccesary for Git operations to work.
Push-Location -Path "$PSScriptRoot/../../$RepositoryName"

$Version = Get-Version -RepositoryName $RepositoryName
$Branch = "release/v$Version"

Update-Branch -Version $Version

if ($PSCmdlet.ShouldProcess("$RepositoryName/$Branch", "git push")) {
Write-Host "Pushing branch ``$Branch``..."
git push origin $Branch
}

$LabelParams = @{
OwnerName = "PowerShell"
RepositoryName = $RepositoryName
Label = "Ignore"
}

$PRParams = @{
Head = $Branch
Base = "master"
Draft = $true
Title = "Release ``v$Version``"
Body = "Automated PR for new release!"
WhatIf = $WhatIfPreference
Confirm = $ConfirmPreference
}

$PR = Get-GitHubLabel @LabelParams | New-GitHubPullRequest @PRParams
Write-Host "Draft PR URL: $($PR.html_url)"

Pop-Location
}

Expand All @@ -339,28 +396,35 @@ function Update-Version {
are prefixed with a `v`. Creates a Git tag if it does not already exist.
#>
function New-DraftRelease {
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[ValidateSet([RepoNames])]
[string]$RepositoryName,

[Parameter(ValueFromPipeline)]
[Parameter()]
[string[]]$Assets
)
$Version = Get-Version -RepositoryName $RepositoryName
$Changelog = (Get-FirstChangelog -RepositoryName $RepositoryName) -join "`n"
$ReleaseParams = @{
Draft = $true
# NOTE: We rely on GitHub to create the tag at that branch.
Tag = "v$Version"
Committish = "release/v$Version"
Name = "v$Version"
Body = $ChangeLog
PreRelease = [bool]$Version.PreReleaseLabel
OwnerName = "PowerShell"
Tag = "v$Version"
Committish = "release/v$Version"
Name = "v$Version"
Body = $ChangeLog
Draft = $true
PreRelease = [bool]$Version.PreReleaseLabel
OwnerName = "PowerShell"
RepositoryName = $RepositoryName
WhatIf = $WhatIfPreference
Confirm = $ConfirmPreference
}

$Release = New-GitHubRelease @ReleaseParams
$Assets | New-GitHubReleaseAsset -Release $Release.Id
if ($Release) {
Write-Host "Draft release URL: $($Release.html_url)"
Write-Host "Uploading assets..."
$Assets | New-GitHubReleaseAsset -Release $Release.Id
}
}