diff --git a/.github/actions/spelling/allow/allow.txt b/.github/actions/spelling/allow/allow.txt index e4abdb7d8..35742a611 100644 --- a/.github/actions/spelling/allow/allow.txt +++ b/.github/actions/spelling/allow/allow.txt @@ -1,6 +1,7 @@ apc calt ccmp +changelog cybersecurity Apc clickable @@ -41,6 +42,7 @@ Lorigin maxed mkmk mru +noreply nje ogonek ok'd diff --git a/.github/actions/spelling/allow/names.txt b/.github/actions/spelling/allow/names.txt index 27ba53635..3635d3723 100644 --- a/.github/actions/spelling/allow/names.txt +++ b/.github/actions/spelling/allow/names.txt @@ -53,6 +53,7 @@ oldnewthing opengl osgwiki pabhojwa +panos paulcam pauldotknopf PGP diff --git a/tools/ReleaseEngineering/New-TerminalStackedChangelog.ps1 b/tools/ReleaseEngineering/New-TerminalStackedChangelog.ps1 new file mode 100644 index 000000000..0c2ad8b5c --- /dev/null +++ b/tools/ReleaseEngineering/New-TerminalStackedChangelog.ps1 @@ -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+\+)?(?[^@]+)@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 $_)) +}