Skip to content

Commit 1b4e77f

Browse files
committed
WIP: Replacing changelog script
1 parent e9cf5ff commit 1b4e77f

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

tools/Update-Changelog.ps1

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
#requires -Version 6.0
5+
6+
using module PowerShellForGitHub
7+
8+
<#
9+
.SYNOPSIS
10+
Updates the CHANGELOG file with PRs merged since the last release.
11+
.DESCRIPTION
12+
Expects the Git repositories to be checked out correctly as it does not
13+
change branches or pull. Handles any merge option for PRs, but is a little
14+
slow as it queries all closed PRs first.
15+
#>
16+
[CmdletBinding(SupportsShouldProcess)]
17+
param(
18+
[Parameter(Mandatory)]
19+
[ValidateSet("vscode-powershell", "PowerShellEditorServices")]
20+
[string]$RepositoryName,
21+
22+
[Parameter(Mandatory)]
23+
[ValidateScript({ $_.StartsWith("v") })]
24+
[string]$Version
25+
)
26+
27+
# TODO: Refactor into functions to map over these.
28+
$RepoNames = "vscode-powershell", "PowerShellEditorServices"
29+
30+
# NOTE: This a side effect neccesary for Git operations to work.
31+
Set-Location (Resolve-Path "$PSScriptRoot/../../$RepositoryName")
32+
33+
# Get the repo object, latest release, and commits since its tag.
34+
$Repo = Get-GitHubRepository -OwnerName PowerShell -RepositoryName $RepositoryName
35+
$Release = $Repo | Get-GitHubRelease | Select-Object -First 1
36+
$Commits = git rev-list "$($Release.tag_name)..."
37+
# NOTE: This is a slow API as it gets all closed PRs, and then filters.
38+
$PullRequests = $Repo | Get-GitHubPullRequest -State Closed |
39+
Where-Object { $_.merge_commit_sha -in $Commits } |
40+
Where-Object { $_.user.UserName -notmatch "\[bot\]$" } |
41+
Where-Object { $_.labels.LabelName -notcontains "Ignore" }
42+
43+
$SkipThanks = @(
44+
'andschwa'
45+
'daxian-dbw'
46+
'PaulHigin'
47+
'rjmholt'
48+
'SteveL-MSFT'
49+
'TylerLeonhardt'
50+
)
51+
52+
$LabelEmoji = @{
53+
'Issue-Enhancement' = ''
54+
'Issue-Bug' = '🐛'
55+
'Issue-Performance' = '⚡️'
56+
'Area-Build & Release' = '👷'
57+
'Area-Code Formatting' = '💎'
58+
'Area-Configuration' = '🔧'
59+
'Area-Debugging' = '🔍'
60+
'Area-Documentation' = '📖'
61+
'Area-Engine' = '🚂'
62+
'Area-Folding' = '📚'
63+
'Area-Integrated Console' = '📟'
64+
'Area-IntelliSense' = '🧠'
65+
'Area-Logging' = '💭'
66+
'Area-Pester' = '🐢'
67+
'Area-Script Analysis' = '‍🕵️'
68+
'Area-Snippets' = '✂️'
69+
'Area-Startup' = '🛫'
70+
'Area-Symbols & References' = '🔗'
71+
'Area-Tasks' = ''
72+
'Area-Test' = '🚨'
73+
'Area-Threading' = '⏱️'
74+
'Area-UI' = '📺'
75+
'Area-Workspaces' = '📁'
76+
}
77+
78+
$CloseKeywords = @(
79+
'close'
80+
'closes'
81+
'closed'
82+
'fix'
83+
'fixes'
84+
'fixed'
85+
'resolve'
86+
'resolves'
87+
'resolved'
88+
)
89+
90+
$IssueRegex = "(" + ($CloseKeywords -join "|") + ")\s+(?<issue>\S+)"
91+
92+
$Bullets = $PullRequests | ForEach-Object {
93+
# Map all the labels to emoji (or use a default).
94+
# NOTE: Whitespacing here is weird.
95+
$emoji = if ($_.labels) {
96+
$LabelEmoji[$_.labels.LabelName] -join ""
97+
} else { '#️⃣ 🙏' }
98+
# Get a linked issue number if it exists (or use the PR).
99+
$link = if ($_.body -match $IssueRegex) {
100+
$issue = $Matches.issue
101+
$number = if ($issue -match "(?<number>\d+)$") {
102+
$Matches.number
103+
} else { Write-Error "Couldn't find issue number!" }
104+
# Handle links to issues in both or repos, in both shortcode and URLs.
105+
$name = $RepoNames | Where-Object { $issue -match $_ } | Select-Object -First 1
106+
"$name #$number"
107+
} else { "$RepositoryName #$($_.number)" }
108+
# Thank the contributor if they are not one of us.
109+
$thanks = if ($_.user.UserName -notin $SkipThanks) {
110+
"(Thanks @$($_.user.UserName)!)"
111+
}
112+
# Put the bullet point together.
113+
"-", $emoji, "[$link]($($_.html_url))", "-", "$($_.title).", $thanks -join " "
114+
}
115+
116+
$ChangelogPath = "CHANGELOG.md"
117+
$CurrentChangelog = Get-Content -Path $ChangelogPath
118+
# TODO: Handle vscode-powershell edge case.
119+
$NewChangelog = @(
120+
"## $Version"
121+
"### $([datetime]::Now.ToString('dddd, MMMM dd, yyyy'))`n"
122+
$Bullets
123+
)
124+
@(
125+
$CurrentChangelog[0..1]
126+
$NewChangelog
127+
$CurrentChangelog[1..$CurrentChangelog.Length]
128+
) | Set-Content -Encoding utf8NoBOM -Path $ChangelogPath
129+
130+
if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogPath", "git")) {
131+
$branch = git branch --show-current
132+
if ($branch -ne "release/$version") {
133+
git checkout -b "release/$version"
134+
}
135+
git add $ChangelogPath
136+
git commit -m "Update CHANGELOG for $Version"
137+
git push
138+
}
139+
140+
# TODO: Do this in a separate function (will require reading from disk).
141+
$ReleaseParams = @{
142+
Draft = $true
143+
Tag = $Version
144+
Name = $Version
145+
Body = $NewChangelog
146+
PreRelease = $Version -match "-preview"
147+
}
148+
$Repo | New-GitHubRelease @ReleaseParams

0 commit comments

Comments
 (0)