Skip to content

Commit 16f5abc

Browse files
Added Format-Release function (#1569)
1 parent 776de7d commit 16f5abc

1 file changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<#
2+
.SYNOPSIS
3+
Get a formatted list of all Pull-Request titles that contributed to a given release.
4+
5+
.DESCRIPTION
6+
Get a formatted list of all Pull-Request titles that contributed to a given release.
7+
Pull Request titles should have the format '[<Category>] <Title>'. Any Pull Request that does not followed this format is printed to the invoking terminal with a warning.
8+
9+
.PARAMETER TargetReleaseTag
10+
Mandatory. The intended release tag. This Tag must be newer than the latest in the target repository. For example 'v1.0.0'.
11+
12+
.PARAMETER PersonalAccessToken
13+
Mandatory. The Token used to fetch the Pull Request information from GitHub.
14+
15+
.PARAMETER RepositoryOwner
16+
Optional. The owning organization of the target repository. For example 'Azure'.
17+
18+
.PARAMETER RepositoryName
19+
Optional. The target repository name. For example 'Resource Modules'.
20+
21+
.PARAMETER TargetBranch
22+
Optional. The target branch to fetch the Pull Request information for. For example 'main'.
23+
24+
.PARAMETER PreviousReleaseTag
25+
Optional. The previous release tag to get the diff in Pull Requests for. Defaults to the latest release. For eaxample 'v0.0.0'
26+
27+
.EXAMPLE
28+
Get-FormattedGitHubRelease -TargetReleaseTag 'v0.6.0' -PersonalAccessToken '<A PAT>'
29+
30+
Get the formatted release notes for a future release with tag 'v0.6.0'.
31+
32+
.EXAMPLE
33+
Get-FormattedGitHubRelease -TargetReleaseTag 'v1.0.0' -PreviousReleaseTag 'v0.4.0' -PersonalAccessToken '<A PAT>'
34+
35+
Get the formatted release notes for a future release with tag 'v1.0.0' - containing all the Pull Requests in between tag 'v0.4.0' and 'v1.0.0'.
36+
#>
37+
function Get-FormattedGitHubRelease {
38+
39+
[CmdletBinding()]
40+
param (
41+
[Parameter(Mandatory = $true)]
42+
[string] $TargetReleaseTag,
43+
44+
[Parameter(Mandatory = $true)]
45+
[string] $PersonalAccessToken,
46+
47+
[Parameter(Mandatory = $false)]
48+
[string] $RepositoryOwner = 'Azure',
49+
50+
[Parameter(Mandatory = $false)]
51+
[string] $RepositoryName = 'ResourceModules',
52+
53+
[Parameter(Mandatory = $false)]
54+
[string] $TargetBranch = 'main',
55+
56+
[Parameter(Mandatory = $false)]
57+
[string] $PreviousReleaseTag = ''
58+
)
59+
60+
# =============================== #
61+
# Get generated release notes #
62+
# =============================== #
63+
$requestInputObject = @{
64+
Method = 'POST'
65+
Uri = "https://api.github.com/repos/$RepositoryOwner/$RepositoryName/releases/generate-notes"
66+
Headers = @{
67+
Authorization = "Bearer $PersonalAccessToken"
68+
}
69+
Body = @{
70+
tag_name = $TargetReleaseTag
71+
target_commitish = $TargetBranch
72+
previous_tag_name = $PreviousReleaseTag
73+
} | ConvertTo-Json
74+
}
75+
$response = Invoke-RestMethod @requestInputObject
76+
77+
if (-not $response.Body) {
78+
Write-Error "Request failed. Reponse: [$response]"
79+
}
80+
81+
$content = $response.Body -split '\n' | Where-Object {
82+
$_ -like '`**' -and # For example: * [Modules] Update scope @carml in https://github.com/Azure/ResourceModules/pull/0
83+
$_ -notlike '`* @*' -and # For example: @carml made their first contribution in https://github.com/Azure/ResourceModules/pull/0
84+
$_ -notlike '`*`**' # For example: **Full Changelog**: https://github.com/Azure/ResourceModules/compare/v0.0.0...v1.0.0
85+
}
86+
87+
# =================== #
88+
# Analyze content #
89+
# =================== #
90+
$correctlyFormatted = $content | Where-Object { $_ -match '$* \[.*' }
91+
$incorrectlyFormatted = $content | Where-Object { $_ -notmatch '$* \[.*' }
92+
93+
if ($incorrectlyFormatted.Count -gt 0) {
94+
Write-Verbose '#############################' -Verbose
95+
Write-Verbose '# Incorrectly formatted #' -Verbose
96+
Write-Verbose '#############################' -Verbose
97+
Write-Verbose ($incorrectlyFormatted | Out-String) -Verbose
98+
Write-Verbose '#############################' -Verbose
99+
}
100+
101+
# =================== #
102+
# Process content #
103+
# =================== #
104+
$categories = @()
105+
foreach ($line in $correctlyFormatted) {
106+
$match = [regex]::Match($line, '\[(.+)\].+')
107+
$categories += $match.Captures.Groups[1].Value
108+
}
109+
$foundCategories = $categories | Select-Object -Unique
110+
111+
$output = @()
112+
foreach ($category in $foundCategories) {
113+
$output += "***$category***"
114+
$categoryItems = $correctlyFormatted | Where-Object { $_ -match ".+\[$category\].+" }
115+
foreach ($categoryItem in $categoryItems) {
116+
$simplifiedItem = $categoryItem -replace "\* \[$category\]"
117+
$simplifiedItem = $simplifiedItem -replace 'by @.*', ''
118+
if ($simplifiedItem -like ':*') {
119+
$simplifiedItem = $simplifiedItem.Substring(1, ($simplifiedItem.Length - 1))
120+
}
121+
$output += "* $simplifiedItem".Trim()
122+
}
123+
$output += ''
124+
}
125+
126+
return $output
127+
}

0 commit comments

Comments
 (0)