Skip to content

Commit afbfa18

Browse files
Merge pull request #3458 from PowerShell/andschwa/release-improvements
Automate more of the release
2 parents 83d0edb + 2bf2359 commit afbfa18

File tree

3 files changed

+100
-46
lines changed

3 files changed

+100
-46
lines changed

.vsts-ci/azure-pipelines-release.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ jobs:
3131
- job: 'ReleaseBuild'
3232
displayName: 'Build release'
3333
pool:
34-
name: 'Package ES Standard Build'
35-
demands: DotNetFramework
34+
name: '1ES'
35+
demands: ImageOverride -equals MMS2019
3636
variables:
3737
- group: ESRP
3838
steps:

docs/development.md

+4-14
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,11 @@ Import-Module ./tools/ReleaseTools.psm1
6868
Update-Changelog -RepositoryName PowerShellEditorServices -Version <version>
6969
Update-Changelog -RepositoryName vscode-powershell -Version <version>
7070
# Amend changelog as necessary
71-
Update-Version -RepositoryName PowerShellEditorServices
72-
Update-Version -RepositoryName vscode-powershell
73-
# Push branches to GitHub and ADO
74-
# Open PRs for review
7571
# Download and test assets (assert correct PSES is included)
76-
New-DraftRelease -RepositoryName PowerShellEditorServices
77-
New-DraftRelease -RepositoryName vscode-powershell
78-
# Point releases to branches for automatic tagging
79-
# Upload PowerShellEditorServices.zip (for other extensions)
80-
# Upload VSIX and Install-VSCode.ps1
81-
# Publish draft releases and merge (don't squash!) branches
72+
New-DraftRelease -RepositoryName PowerShellEditorServices -Assets "PowerShellEditorServices.zip"
73+
New-DraftRelease -RepositoryName vscode-powershell -Assets "powershell-YYYY.M.X.vsix", "Install-VSCode.ps1"
8274
# Check telemetry for stability before releasing
75+
# Publish draft releases and merge (don't squash!) branches
8376
vsce publish --packagePath ./PowerShell-<version>.vsix
8477
# Update Install-VSCode.ps1 on gallery
8578
Publish-Script -Path ./Install-VSCode.ps1 -NuGetApiKey (Get-Secret "PowerShell Gallery API Key" -AsPlainText)
@@ -98,7 +91,7 @@ For PowerShellEditor Services, we simply follow semantic versioning, e.g.
9891
generally used directly: it's a library consumed by other projects which
9992
themselves use preview releases for beta testing.
10093

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

138131
* `Update-Changelog` should verify the version is in the correct format
139132
* `Update-Changelog` could be faster by not downloading _every_ PR
140-
* `Update-Changelog` should use exactly two emoji and in the right order
141-
* `Update-Version` could be run by `Update-Changelog`
142-
* The build should emit an appropriately named VSIX instead of us manually renaming it
143133
* A `Publish-Binaries` function could be written to push the binaries out

tools/ReleaseTools.psm1

+94-30
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,13 @@ function Get-Bullets {
3737
'TylerLeonhardt'
3838
)
3939

40-
$LabelEmoji = @{
40+
$IssueEmojis = @{
4141
'Issue-Enhancement' = ''
4242
'Issue-Bug' = '🐛'
4343
'Issue-Performance' = '⚡️'
44+
}
45+
46+
$AreaEmojis = @{
4447
'Area-Build & Release' = '👷'
4548
'Area-Code Formatting' = '💎'
4649
'Area-Configuration' = '🔧'
@@ -81,12 +84,9 @@ function Get-Bullets {
8184
process {
8285
$PullRequests | ForEach-Object {
8386
# Map all the labels to emoji (or use a default).
84-
# NOTE: Whitespacing here is weird.
85-
$emoji = if ($_.labels) {
86-
$LabelEmoji[$_.labels.LabelName] -join ""
87-
} else {
88-
'#️⃣ 🙏'
89-
}
87+
$labels = if ($_.labels) { $_.labels.LabelName } else { "" }
88+
$issueEmoji = $IssueEmojis[$labels] + "#️⃣" | Select-Object -First 1
89+
$areaEmoji = $AreaEmojis[$labels] + "🙏" | Select-Object -First 1
9090

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

107107
# Put the bullet point together.
108-
("-", $emoji, "[$link]($($_.html_url))", "-", "$($_.title).", $thanks -join " ").Trim()
108+
("-", $issueEmoji, $areaEmoji, "[$link]($($_.html_url))", "-", "$($_.title).", $thanks -join " ").Trim()
109109
}
110110
}
111111
}
@@ -139,13 +139,17 @@ function Get-FirstChangelog {
139139
Creates and checks out `release/v<version>` if not already on it.
140140
#>
141141
function Update-Branch {
142+
[CmdletBinding(SupportsShouldProcess)]
142143
param(
143144
[Parameter(Mandatory)]
144145
[string]$Version
145146
)
146-
$branch = git branch --show-current
147-
if ($branch -ne "release/v$Version") {
148-
git checkout -b "release/v$Version"
147+
$Branch = git branch --show-current
148+
$NewBranch = "release/v$Version"
149+
if ($Branch -ne $NewBranch) {
150+
if ($PSCmdlet.ShouldProcess($NewBranch, "git checkout -b")) {
151+
git checkout -b $NewBranch
152+
}
149153
}
150154
}
151155

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

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

238-
if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git")) {
239-
Update-Branch -Version $Version.Substring(1) # Has "v" prefix
241+
Update-Branch -Version $Version.Substring(1) # Has "v" prefix
242+
243+
if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git commit")) {
240244
git add $ChangelogFile
241245
git commit -m "Update CHANGELOG for ``$Version``"
242246
}
243247

248+
Update-Version -RepositoryName $RepositoryName
249+
244250
Pop-Location
245251
}
246252

@@ -250,18 +256,18 @@ function Update-Changelog {
250256
.DESCRIPTION
251257
Note that our Git tags and changelog prefix all versions with `v`.
252258
253-
PowerShellEditorServices: version is `x.y.z-preview.d`
259+
PowerShellEditorServices: version is `X.Y.Z-preview`
254260
255261
- PowerShellEditorServices.psd1:
256-
- `ModuleVersion` variable with `'x.y.z'` string, no pre-release info
262+
- `ModuleVersion` variable with `'X.Y.Z'` string, no pre-release info
257263
- PowerShellEditorServices.Common.props:
258-
- `VersionPrefix` field with `x.y.z`
264+
- `VersionPrefix` field with `X.Y.Z`
259265
- `VersionSuffix` field with pre-release portion excluding hyphen
260266
261-
vscode-powershell: version is `yyyy.mm.x-preview`
267+
vscode-powershell: version is `YYYY.M.X-preview`
262268
263269
- package.json:
264-
- `version` field with `"x.y.z"` and no prefix or suffix
270+
- `version` field with `"X.Y.Z"` and no prefix or suffix
265271
- `preview` field set to `true` or `false` if version is a preview
266272
- `name` field has `-preview` appended similarly
267273
- `displayName` field has ` Preview` appended similarly
@@ -322,11 +328,62 @@ function Update-Version {
322328
}
323329
}
324330

331+
Update-Branch -Version $Version
332+
325333
if ($PSCmdlet.ShouldProcess("$RepositoryName/v$Version", "git commit")) {
326-
Update-Branch -Version $Version
327334
git commit -m "Bump version to ``v$Version``"
335+
} # TODO: Git reset to unstage
336+
337+
New-ReleasePR -RepositoryName $RepositoryName
338+
339+
Pop-Location
340+
}
341+
342+
<#
343+
.SYNOPSIS
344+
Creates a new draft GitHub PR from the release branch.
345+
.DESCRIPTION
346+
Pushes the release branch to `origin` and then opens a draft PR.
347+
#>
348+
function New-ReleasePR {
349+
[CmdletBinding(SupportsShouldProcess)]
350+
param(
351+
[Parameter(Mandatory)]
352+
[ValidateSet([RepoNames])]
353+
[string]$RepositoryName
354+
)
355+
# NOTE: This a side effect neccesary for Git operations to work.
356+
Push-Location -Path "$PSScriptRoot/../../$RepositoryName"
357+
358+
$Version = Get-Version -RepositoryName $RepositoryName
359+
$Branch = "release/v$Version"
360+
361+
Update-Branch -Version $Version
362+
363+
if ($PSCmdlet.ShouldProcess("$RepositoryName/$Branch", "git push")) {
364+
Write-Host "Pushing branch ``$Branch``..."
365+
git push origin $Branch
328366
}
329367

368+
$LabelParams = @{
369+
OwnerName = "PowerShell"
370+
RepositoryName = $RepositoryName
371+
Label = "Ignore"
372+
}
373+
374+
$PRParams = @{
375+
Head = $Branch
376+
Base = "master"
377+
Draft = $true
378+
Title = "Release ``v$Version``"
379+
Body = "Automated PR for new release!"
380+
WhatIf = $WhatIfPreference
381+
Confirm = $ConfirmPreference
382+
}
383+
384+
$PR = Get-GitHubLabel @LabelParams | New-GitHubPullRequest @PRParams
385+
Write-Host "Draft PR URL: $($PR.html_url)"
386+
330387
Pop-Location
331388
}
332389

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

347-
[Parameter(ValueFromPipeline)]
405+
[Parameter()]
348406
[string[]]$Assets
349407
)
350408
$Version = Get-Version -RepositoryName $RepositoryName
351409
$Changelog = (Get-FirstChangelog -RepositoryName $RepositoryName) -join "`n"
352410
$ReleaseParams = @{
353-
Draft = $true
354411
# NOTE: We rely on GitHub to create the tag at that branch.
355-
Tag = "v$Version"
356-
Committish = "release/v$Version"
357-
Name = "v$Version"
358-
Body = $ChangeLog
359-
PreRelease = [bool]$Version.PreReleaseLabel
360-
OwnerName = "PowerShell"
412+
Tag = "v$Version"
413+
Committish = "release/v$Version"
414+
Name = "v$Version"
415+
Body = $ChangeLog
416+
Draft = $true
417+
PreRelease = [bool]$Version.PreReleaseLabel
418+
OwnerName = "PowerShell"
361419
RepositoryName = $RepositoryName
420+
WhatIf = $WhatIfPreference
421+
Confirm = $ConfirmPreference
362422
}
363423

364424
$Release = New-GitHubRelease @ReleaseParams
365-
$Assets | New-GitHubReleaseAsset -Release $Release.Id
425+
if ($Release) {
426+
Write-Host "Draft release URL: $($Release.html_url)"
427+
Write-Host "Uploading assets..."
428+
$Assets | New-GitHubReleaseAsset -Release $Release.Id
429+
}
366430
}

0 commit comments

Comments
 (0)