@@ -17,18 +17,19 @@ import (
1717 "text/template"
1818)
1919
20- //go:embed changelog.tmpl
21- var changelogTplDefault string
20+ //go:embed changelog-entry .tmpl
21+ var changelogTmplDefault string
2222
2323type Note struct {
24- // service touched by pr
25- Service string
26- //release note type (Bug...)
24+ // service or area of codebase the pull request changes
25+ Subcategory string
26+ // release note type (Bug...)
2727 Type string
2828 // release note text
2929 Description string
30- //pr number
31- Pr int
30+ // pull request number
31+ PR int
32+ // URL of the pull request
3233 URL string
3334}
3435
@@ -38,34 +39,35 @@ func main() {
3839 fmt .Fprintln (os .Stderr , err )
3940 os .Exit (1 )
4041 }
41- var service , Type , Description , changelogTmpl , url string
42+ var subcategory , changeType , description , changelogTmpl , url string
4243 var pr int
4344 var Url bool
44- flag .BoolVar (& Url , "add-url" , false , "do not add github issue url " )
45- flag .IntVar (& pr , "pr" , - 1 , "pr number" )
46- flag .StringVar (& service , "service " , "" , "the service the pr change (not mandatory )" )
47- flag .StringVar (& Type , "type" , "" , "The pr type" )
48- flag .StringVar (& Description , "description" , "" , "the changelog-gen description entry" )
49- flag .StringVar (& changelogTmpl , "changelog-template" , "" , "the path of the file holding the template to use for the entire changelog-gen " )
45+ flag .BoolVar (& Url , "add-url" , false , "add GitHub issue URL (omitted by default due to formatting in changelog-build) " )
46+ flag .IntVar (& pr , "pr" , - 1 , "pull request number" )
47+ flag .StringVar (& subcategory , "subcategory " , "" , "the service or area of the codebase the pull request changes (optional )" )
48+ flag .StringVar (& changeType , "type" , "" , "the type of change " )
49+ flag .StringVar (& description , "description" , "" , "the changelog entry content " )
50+ flag .StringVar (& changelogTmpl , "changelog-template" , "" , "the path of the file holding the template to use for the changelog entries " )
5051 flag .Parse ()
5152
5253 if pr == - 1 {
5354 pr , url , err = getPrNumberFromGithub (pwd )
5455 if err != nil {
55- fmt .Fprintln (os .Stderr , "Must specify pr number or run in a valid github repo" )
56+ fmt .Fprintln (os .Stderr , "Must specify pull request number or run in a git repo with a GitHub remote origin:" , err )
5657 fmt .Fprintln (os .Stderr , "" )
5758 flag .Usage ()
5859 os .Exit (1 )
5960 }
6061 }
62+ fmt .Fprintln (os .Stderr , "Found matching pull request:" , url )
6163
62- if Type == "" {
64+ if changeType == "" {
6365 prompt := promptui.Select {
6466 Label : "Select a change type" ,
6567 Items : changelog .TypeValues ,
6668 }
6769
68- _ , Type , err = prompt .Run ()
70+ _ , changeType , err = prompt .Run ()
6971
7072 if err != nil {
7173 fmt .Fprintln (os .Stderr , "Must specify the change type" )
@@ -74,24 +76,30 @@ func main() {
7476 os .Exit (1 )
7577 }
7678 } else {
77- if ! changelog .TypeValid (Type ) {
79+ if ! changelog .TypeValid (changeType ) {
7880 fmt .Fprintln (os .Stderr , "Must specify a valid type" )
7981 fmt .Fprintln (os .Stderr , "" )
8082 flag .Usage ()
8183 os .Exit (1 )
8284 }
8385 }
8486
85- if Description == "" {
87+ if subcategory == "" {
88+ prompt := promptui.Prompt {Label : "Subcategory (optional)" }
89+ subcategory , err = prompt .Run ()
90+ }
91+
92+ if description == "" {
8693 prompt := promptui.Prompt {Label : "Description" }
87- Description , err = prompt .Run ()
94+ description , err = prompt .Run ()
8895 if err != nil {
8996 fmt .Fprintln (os .Stderr , "Must specify the change description" )
9097 fmt .Fprintln (os .Stderr , "" )
9198 flag .Usage ()
9299 os .Exit (1 )
93100 }
94101 }
102+
95103 var tmpl * template.Template
96104 if changelogTmpl != "" {
97105 file , err := os .ReadFile (changelogTmpl )
@@ -103,7 +111,7 @@ func main() {
103111 os .Exit (1 )
104112 }
105113 } else {
106- tmpl , err = template .New ("" ).Parse (changelogTplDefault )
114+ tmpl , err = template .New ("" ).Parse (changelogTmplDefault )
107115 if err != nil {
108116 os .Exit (1 )
109117 }
@@ -112,18 +120,20 @@ func main() {
112120 if ! Url {
113121 url = ""
114122 }
115- n := Note {Type : Type , Description : Description , Service : service , Pr : pr , URL : url }
123+ n := Note {Type : changeType , Description : description , Subcategory : subcategory , PR : pr , URL : url }
116124
117125 var buf bytes.Buffer
118126 err = tmpl .Execute (& buf , n )
119127 fmt .Printf ("\n %s\n " , buf .String ())
120128 if err != nil {
121129 os .Exit (1 )
122130 }
123- err = os .WriteFile (fmt .Sprintf ("%s/%d.txt" , pwd , pr ), buf .Bytes (), 0644 )
131+ filepath := fmt .Sprintf ("%s/%d.txt" , pwd , pr )
132+ err = os .WriteFile (filepath , buf .Bytes (), 0644 )
124133 if err != nil {
125134 os .Exit (1 )
126135 }
136+ fmt .Fprintln (os .Stderr , "Created changelog entry at" , filepath )
127137}
128138
129139func OpenGit (path string ) (* git.Repository , error ) {
@@ -149,55 +159,80 @@ func getPrNumberFromGithub(path string) (int, string, error) {
149159 return - 1 , "" , err
150160 }
151161
152- rem , err := r .Remote ( "origin" )
162+ localBranch , err := r .Branch ( ref . Name (). Short () )
153163 if err != nil {
154164 return - 1 , "" , err
155165 }
156166
157- cli := github .NewClient (nil )
167+ remote , err := r .Remote ("origin" )
168+ if err != nil {
169+ return - 1 , "" , err
170+ }
158171
159- opt := & github.PullRequestListOptions {
160- ListOptions : github.ListOptions {PerPage : 200 },
161- Sort : "updated" ,
162- Direction : "desc" ,
172+ if len (remote .Config ().URLs ) <= 0 {
173+ return - 1 , "" , errors .New ("not able to parse repo and org" )
163174 }
175+ remoteUrl := remote .Config ().URLs [0 ]
164176
165- ctx := context .Background ()
166- if len (rem .Config ().URLs ) <= 0 {
177+ re := regexp .MustCompile (`.*github\.com:(.*)/(.*)\.git` )
178+ m := re .FindStringSubmatch (remoteUrl )
179+ if len (m ) < 3 {
167180 return - 1 , "" , errors .New ("not able to parse repo and org" )
168181 }
169- repoUrl := rem .Config ().URLs [0 ]
170182
171- reg := regexp .MustCompile (`.*github\\.com:(.*)/(.*)\\.git` )
172- m := reg .FindAllStringSubmatch (repoUrl , - 1 )
173- if len (m ) > 1 {
174- if len (m [0 ]) < 2 {
175- return - 1 , "" , errors .New ("not able to parse repo and org" )
176- }
183+ cli := github .NewClient (nil )
184+
185+ ctx := context .Background ()
186+
187+ githubOrg := m [1 ]
188+ githubRepo := m [2 ]
189+
190+ opt := & github.PullRequestListOptions {
191+ ListOptions : github.ListOptions {PerPage : 200 },
192+ Sort : "updated" ,
193+ Direction : "desc" ,
177194 }
178195
179- list , _ , err := cli .PullRequests .List (ctx , m [ 0 ][ 1 ], m [ 0 ][ 2 ] , opt )
196+ list , _ , err := cli .PullRequests .List (ctx , githubOrg , githubRepo , opt )
180197 if err != nil {
181198 return - 1 , "" , err
182199 }
183- branchName := ref .Name ().Short ()
184- if branchName == "master" || branchName == "main" {
185- return - 1 , "" , errors .New ("cannot find a pr # for the main branch" )
186- }
200+
187201 for _ , pr := range list {
188- if pr .Head == nil {
202+ head := pr .GetHead ()
203+ if head == nil {
189204 continue
190205 }
191- if pr .Head .Ref == nil {
206+
207+ branch := head .GetRef ()
208+ if branch == "" {
192209 continue
193210 }
194211
195- if * pr .Head .Ref == branchName {
212+ repo := head .GetRepo ()
213+ if repo == nil {
214+ continue
215+ }
216+
217+ // Allow finding PRs from forks - localBranch.Remote will return the
218+ // remote name for branches of origin, but the remote URL for forks
219+ var gitRemote string
220+ remote , err := r .Remote (localBranch .Remote )
221+ if err != nil {
222+ gitRemote = localBranch .Remote
223+ } else {
224+ gitRemote = remote .Config ().URLs [0 ]
225+ }
226+
227+ if (gitRemote == * repo .SSHURL || gitRemote == * repo .CloneURL ) &&
228+ localBranch .Name == branch {
196229 n := pr .GetNumber ()
230+
197231 if n != 0 {
198232 return n , pr .GetHTMLURL (), nil
199233 }
200234 }
201235 }
202- return - 1 , "" , errors .New ("not found" )
236+
237+ return - 1 , "" , errors .New ("no match found" )
203238}
0 commit comments