1
+ <#
2
+ . SYNOPSIS
3
+ Creates a Markdown changelog file with markdown formatting.
4
+
5
+ Original version created by @vexx32
6
+ . DESCRIPTION
7
+ Uses `git log` to compare the current commit to the last tagged commit,
8
+ and parses the output into CSV data. This is then processed and PR body
9
+ of submitted Pull Requests are added to the output file.
10
+ . PARAMETER Path
11
+ The file location to save the markdown text to. The file will be
12
+ overwritten if it already contains data.
13
+ . PARAMETER CommitID
14
+ The commit tag or hash that is used to identify the commit to
15
+ compare with. By default, the last value given by `git tag`
16
+ will be used.
17
+ . PARAMETER HeadCommitID
18
+ The commit tag or hash that represents the current version
19
+ of the repository. HEAD by default.
20
+ . PARAMETER ApiKey
21
+ The Github API key to use when looking up commit authors'
22
+ Github user names.
23
+ . PARAMETER IncludeDetails
24
+ Add PR body to each entry in the change log
25
+ . PARAMETER Append
26
+ Append changelog to the top of the existing file
27
+ . EXAMPLE
28
+ New-Changelog.ps1 -Path File.md -ApiKey $GHApiKey
29
+ Retrieves the commits since the last tagged commit and creates a
30
+ Markdown-formatted plaintext file called File.md in the current
31
+ location.
32
+ . NOTES
33
+ The Github API limitation of 60 requests per minute is -barely-
34
+ usable without authentication. Authenticated requests have a
35
+ substantially higher limit on requests per minute.
36
+ #>
37
+ [CmdletBinding ()]
38
+ param (
39
+ [Parameter (Mandatory , Position = 0 )]
40
+ [ValidateScript ( { Test-Path $_ - IsValid })]
41
+ [string ]
42
+ $Path ,
43
+
44
+ [Parameter (Position = 1 )]
45
+ [ValidatePattern (' [a-f0-9]{6,40}|v?(\d+\.)+\d+(-\w+\d+)?' )]
46
+ [string ]
47
+ $CommitID = (git tag | Select-Object - Last 1 ),
48
+
49
+ [Parameter (Position = 2 )]
50
+ [ValidatePattern (' [a-f0-9]{6,40}|v?(\d+\.)+\d+(-\w+\d+)?|HEAD' )]
51
+ [string ]
52
+ $HeadCommitID = ' HEAD' ,
53
+
54
+ [Parameter ()]
55
+ [Alias (' OauthToken' )]
56
+ [string ]
57
+ $ApiKey ,
58
+
59
+ [Parameter ()]
60
+ [switch ]
61
+ $IncludeDetails ,
62
+
63
+ [Parameter ()]
64
+ [switch ]
65
+ $Append
66
+ )
67
+ $RequestParams = @ { }
68
+ if ($ApiKey ) {
69
+ $RequestParams = @ {
70
+ SessionVariable = ' AuthSession'
71
+ Headers = @ { Authorization = " token $ApiKey " }
72
+ }
73
+ Invoke-RestMethod @RequestParams - Uri ' https://api.github.com/' | Out-String | Write-Verbose
74
+ }
75
+ $gitParams = @ (
76
+ ' --no-pager'
77
+ ' log'
78
+ ' --first-parent'
79
+ " $CommitID ..$HeadCommitID "
80
+ ' --format="%H"'
81
+ ' --'
82
+ ' .'
83
+ ' ":(exclude)*.md"'
84
+ )
85
+ $commits = & git @gitParams
86
+
87
+ $prs = @ ()
88
+ foreach ($commit in $commits ) {
89
+ $result = Invoke-RestMethod @RequestParams - Uri " https://api.github.com/search/issues?q=$ ( $commit ) is%3Amerged"
90
+ if ($result.total_count -gt 0 ) {
91
+ $prs += $result.items | Sort-Object - Property score - Descending | Select-Object - First 1
92
+ }
93
+ }
94
+ $prs = $prs | Sort-Object - Property number - Unique
95
+ $mdTable = @ (" # Release notes for $CommitID `:" )
96
+ foreach ($pr in $prs ) {
97
+ $prData = Invoke-RestMethod @RequestParams - Uri $pr.url
98
+ $mdTable += " - ### $ ( $prData.title ) (#$ ( $prData.number ) ) by @$ ( $prData.user.login ) "
99
+ if ($IncludeDetails -and $prData.body ) {
100
+ $mdTable += " ------"
101
+ foreach ($line in $prData.body.Split (" `n " )) {
102
+ $mdTable += " $line "
103
+ }
104
+ }
105
+ }
106
+ if ($Append ) {
107
+ if (Test-Path $Path ) {
108
+ $currentContent = Get-Content - Path $Path
109
+ }
110
+ else { $currentContent = @ () }
111
+ $mdTable + $currentContent | Set-Content - Path $Path
112
+ }
113
+ else { $mdTable | Set-Content - Path $Path }
0 commit comments