releng: add New-TerminalStackedChangelog (#11065)

I've done this process enough times that I should have written a script
to do it a while ago. This one is rough, but the whole changelog process
is pretty rough.

This script takes multiple revision ranges and produces something that
looks like a rough untranslated changelog, with indicators for how many
of the provided ranges had the same change (deduplicated by title.)

I use a process like this to build the Stable and Preview release notes
out of a set of revision ranges.
This commit is contained in:
Dustin L. Howett 2021-09-23 13:05:38 -05:00 committed by GitHub
parent e75f848cf3
commit 3b7049c5b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 0 deletions

View File

@ -1,6 +1,7 @@
apc
calt
ccmp
changelog
cybersecurity
Apc
clickable
@ -41,6 +42,7 @@ Lorigin
maxed
mkmk
mru
noreply
nje
ogonek
ok'd

View File

@ -53,6 +53,7 @@ oldnewthing
opengl
osgwiki
pabhojwa
panos
paulcam
pauldotknopf
PGP

View File

@ -0,0 +1,82 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#################################
# New-TerminalStackedChangelog generates a markdown file with attribution
# over a set of revision ranges.
# Dustin uses it when he's writing the changelog.
#
## For example, generating the changelog for both 1.9 and 1.10 might look like this:
# $ New-TerminalStackedChangelog 1.9..release-1.9, 1.10..release-1.10
## The output will be a markdown-like document. Each commit will be converted into a
## single-line entry with attribution and an optional count:
#
# * Foo the bar (thanks @PanosP!)
# * [2] Fix the bug
#
# Entries with a count were present in both changelists.
#
# If you don't have the release tags/branches checked out locally, you might
# need to do something like:
#
# $ New-TerminalStackedChangelog origin/release-1.8..origin/release-1.9
[CmdletBinding()]
Param(
[string[]]$RevisionRanges
)
Function Test-MicrosoftPerson($email) {
Return $email -like "*@microsoft.com" -Or $email -like "pankaj.d*"
}
Function Generate-Thanks($Entry) {
# We don't need to thank ourselves for doing our jobs
If ($_.Microsoft) {
""
} ElseIf (-Not [string]::IsNullOrEmpty($_.PossibleUsername)) {
" (thanks @{0}!)" -f $_.PossibleUsername
} Else {
" (thanks @<{0}>!)" -f $_.Email
}
}
$usernameRegex = [regex]::new("(?:\d+\+)?(?<name>[^@]+)@users.noreply.github.com")
Function Get-PossibleUserName($email) {
$match = $usernameRegex.Match($email)
if ($null -Ne $match) {
return $match.Groups["name"].Value
}
return $null
}
$Entries = @()
ForEach ($RevisionRange in $RevisionRanges) {
# --pretty=format notes:
# - %an: author name
# - %x1C: print a literal FS (0x1C), which will be used as a delimiter
# - %ae: author email
# - %x1C: another FS
# - %s: subject, the title of the commit
$NewEntries = & git log $RevisionRange "--pretty=format:%an%x1C%ae%x1C%s" |
ConvertFrom-CSV -Delimiter "`u{001C}" -Header Author,Email,Subject
$Entries += $NewEntries | % { [PSCustomObject]@{
Author = $_.Author;
Email = $_.Email;
Subject = $_.Subject;
Microsoft = (Test-MicrosoftPerson $_.Email);
PossibleUsername = (Get-PossibleUserName $_.Email);
} }
}
$Unique = $Entries | Group-Object Subject | %{ $_.Group[0] | Add-Member Count $_.Count -Force -PassThru }
$Unique | % {
$c = ""
If ($_.Count -Gt 1) {
$c = "[{0}] " -f $_.Count
}
"* {0}{1}{2}" -f ($c, $_.Subject, (Generate-Thanks $_))
}