@@ -9,91 +9,85 @@ import (
9
9
"strings"
10
10
11
11
"github.com/cli/go-gh/v2/pkg/api"
12
+ "github.com/github/gh-combine/internal/github"
12
13
)
13
14
14
- func CombinePRs (ctx context.Context , graphQlClient * api.GraphQLClient , restClient * api.RESTClient , owner , repo string , matchedPRs []struct {
15
- Number int
16
- Title string
17
- Branch string
18
- Base string
19
- BaseSHA string
20
- },
21
- ) error {
15
+ func CombinePRs (ctx context.Context , graphQlClient * api.GraphQLClient , restClient * api.RESTClient , repo github.Repo , pulls github.Pulls ) error {
22
16
// Define the combined branch name
23
17
workingBranchName := combineBranchName + workingBranchSuffix
24
18
25
19
// Get the default branch of the repository
26
- repoDefaultBranch , err := getDefaultBranch (ctx , restClient , owner , repo )
20
+ repoDefaultBranch , err := getDefaultBranch (ctx , restClient , repo )
27
21
if err != nil {
28
22
return fmt .Errorf ("failed to get default branch: %w" , err )
29
23
}
30
24
31
- baseBranchSHA , err := getBranchSHA (ctx , restClient , owner , repo , repoDefaultBranch )
25
+ baseBranchSHA , err := getBranchSHA (ctx , restClient , repo , repoDefaultBranch )
32
26
if err != nil {
33
27
return fmt .Errorf ("failed to get SHA of main branch: %w" , err )
34
28
}
35
29
36
30
// Delete any pre-existing working branch
37
- err = deleteBranch (ctx , restClient , owner , repo , workingBranchName )
31
+ err = deleteBranch (ctx , restClient , repo , workingBranchName )
38
32
if err != nil {
39
33
Logger .Debug ("Working branch not found, continuing" , "branch" , workingBranchName )
40
34
}
41
35
42
36
// Delete any pre-existing combined branch
43
- err = deleteBranch (ctx , restClient , owner , repo , combineBranchName )
37
+ err = deleteBranch (ctx , restClient , repo , combineBranchName )
44
38
if err != nil {
45
39
Logger .Debug ("Combined branch not found, continuing" , "branch" , combineBranchName )
46
40
}
47
41
48
42
// Create the combined branch
49
- err = createBranch (ctx , restClient , owner , repo , combineBranchName , baseBranchSHA )
43
+ err = createBranch (ctx , restClient , repo , combineBranchName , baseBranchSHA )
50
44
if err != nil {
51
45
return fmt .Errorf ("failed to create combined branch: %w" , err )
52
46
}
53
47
54
48
// Create the working branch
55
- err = createBranch (ctx , restClient , owner , repo , workingBranchName , baseBranchSHA )
49
+ err = createBranch (ctx , restClient , repo , workingBranchName , baseBranchSHA )
56
50
if err != nil {
57
51
return fmt .Errorf ("failed to create working branch: %w" , err )
58
52
}
59
53
60
54
// Merge all PR branches into the working branch
61
55
var combinedPRs []string
62
56
var mergeFailedPRs []string
63
- for _ , pr := range matchedPRs {
64
- err := mergeBranch (ctx , restClient , owner , repo , workingBranchName , pr .Branch )
57
+ for _ , pr := range pulls {
58
+ err := mergeBranch (ctx , restClient , repo , workingBranchName , pr .Head . Ref )
65
59
if err != nil {
66
60
// Check if the error is a 409 merge conflict
67
61
if isMergeConflictError (err ) {
68
62
// Log merge conflicts at DEBUG level
69
- Logger .Debug ("Merge conflict" , "branch" , pr .Branch , "error" , err )
63
+ Logger .Debug ("Merge conflict" , "branch" , pr .Head . Ref , "error" , err )
70
64
} else {
71
65
// Log other errors at WARN level
72
- Logger .Warn ("Failed to merge branch" , "branch" , pr .Branch , "error" , err )
66
+ Logger .Warn ("Failed to merge branch" , "branch" , pr .Head . Ref , "error" , err )
73
67
}
74
68
mergeFailedPRs = append (mergeFailedPRs , fmt .Sprintf ("#%d" , pr .Number ))
75
69
} else {
76
- Logger .Debug ("Merged branch" , "branch" , pr .Branch )
70
+ Logger .Debug ("Merged branch" , "branch" , pr .Head . Ref )
77
71
combinedPRs = append (combinedPRs , fmt .Sprintf ("#%d - %s" , pr .Number , pr .Title ))
78
72
}
79
73
}
80
74
81
75
// Update the combined branch to the latest commit of the working branch
82
- err = updateRef (ctx , restClient , owner , repo , combineBranchName , workingBranchName )
76
+ err = updateRef (ctx , restClient , repo , combineBranchName , workingBranchName )
83
77
if err != nil {
84
78
return fmt .Errorf ("failed to update combined branch: %w" , err )
85
79
}
86
80
87
81
// Delete the temporary working branch
88
- err = deleteBranch (ctx , restClient , owner , repo , workingBranchName )
82
+ err = deleteBranch (ctx , restClient , repo , workingBranchName )
89
83
if err != nil {
90
84
Logger .Warn ("Failed to delete working branch" , "branch" , workingBranchName , "error" , err )
91
85
}
92
86
93
87
// Create the combined PR
94
88
prBody := generatePRBody (combinedPRs , mergeFailedPRs )
95
89
prTitle := "Combined PRs"
96
- err = createPullRequest (ctx , restClient , owner , repo , prTitle , combineBranchName , repoDefaultBranch , prBody )
90
+ err = createPullRequest (ctx , restClient , repo , prTitle , combineBranchName , repoDefaultBranch , prBody )
97
91
if err != nil {
98
92
return fmt .Errorf ("failed to create combined PR: %w" , err )
99
93
}
@@ -108,11 +102,11 @@ func isMergeConflictError(err error) bool {
108
102
}
109
103
110
104
// Find the default branch of a repository
111
- func getDefaultBranch (ctx context.Context , client * api.RESTClient , owner , repo string ) (string , error ) {
105
+ func getDefaultBranch (ctx context.Context , client * api.RESTClient , repo github. Repo ) (string , error ) {
112
106
var repoInfo struct {
113
107
DefaultBranch string `json:"default_branch"`
114
108
}
115
- endpoint := fmt .Sprintf ("repos/%s/%s" , owner , repo )
109
+ endpoint := fmt .Sprintf ("repos/%s/%s" , repo . Owner , repo . Repo )
116
110
err := client .Get (endpoint , & repoInfo )
117
111
if err != nil {
118
112
return "" , fmt .Errorf ("failed to get default branch: %w" , err )
@@ -121,13 +115,13 @@ func getDefaultBranch(ctx context.Context, client *api.RESTClient, owner, repo s
121
115
}
122
116
123
117
// Get the SHA of a given branch
124
- func getBranchSHA (ctx context.Context , client * api.RESTClient , owner , repo , branch string ) (string , error ) {
118
+ func getBranchSHA (ctx context.Context , client * api.RESTClient , repo github. Repo , branch string ) (string , error ) {
125
119
var ref struct {
126
120
Object struct {
127
121
SHA string `json:"sha"`
128
122
} `json:"object"`
129
123
}
130
- endpoint := fmt .Sprintf ("repos/%s/%s/git/ref/heads/%s" , owner , repo , branch )
124
+ endpoint := fmt .Sprintf ("repos/%s/%s/git/ref/heads/%s" , repo . Owner , repo . Repo , branch )
131
125
err := client .Get (endpoint , & ref )
132
126
if err != nil {
133
127
return "" , fmt .Errorf ("failed to get SHA of branch %s: %w" , branch , err )
@@ -154,14 +148,14 @@ func generatePRBody(combinedPRs, mergeFailedPRs []string) string {
154
148
}
155
149
156
150
// deleteBranch deletes a branch in the repository
157
- func deleteBranch (ctx context.Context , client * api.RESTClient , owner , repo , branch string ) error {
158
- endpoint := fmt .Sprintf ("repos/%s/%s/git/refs/heads/%s" , owner , repo , branch )
151
+ func deleteBranch (ctx context.Context , client * api.RESTClient , repo github. Repo , branch string ) error {
152
+ endpoint := fmt .Sprintf ("repos/%s/%s/git/refs/heads/%s" , repo . Owner , repo . Repo , branch )
159
153
return client .Delete (endpoint , nil )
160
154
}
161
155
162
156
// createBranch creates a new branch in the repository
163
- func createBranch (ctx context.Context , client * api.RESTClient , owner , repo , branch , sha string ) error {
164
- endpoint := fmt .Sprintf ("repos/%s/%s/git/refs" , owner , repo )
157
+ func createBranch (ctx context.Context , client * api.RESTClient , repo github. Repo , branch , sha string ) error {
158
+ endpoint := fmt .Sprintf ("repos/%s/%s/git/refs" , repo . Owner , repo . Repo )
165
159
payload := map [string ]string {
166
160
"ref" : "refs/heads/" + branch ,
167
161
"sha" : sha ,
@@ -174,8 +168,8 @@ func createBranch(ctx context.Context, client *api.RESTClient, owner, repo, bran
174
168
}
175
169
176
170
// mergeBranch merges a branch into the base branch
177
- func mergeBranch (ctx context.Context , client * api.RESTClient , owner , repo , base , head string ) error {
178
- endpoint := fmt .Sprintf ("repos/%s/%s/merges" , owner , repo )
171
+ func mergeBranch (ctx context.Context , client * api.RESTClient , repo github. Repo , base , head string ) error {
172
+ endpoint := fmt .Sprintf ("repos/%s/%s/merges" , repo . Owner , repo . Repo )
179
173
payload := map [string ]string {
180
174
"base" : base ,
181
175
"head" : head ,
@@ -188,21 +182,21 @@ func mergeBranch(ctx context.Context, client *api.RESTClient, owner, repo, base,
188
182
}
189
183
190
184
// updateRef updates a branch to point to the latest commit of another branch
191
- func updateRef (ctx context.Context , client * api.RESTClient , owner , repo , branch , sourceBranch string ) error {
185
+ func updateRef (ctx context.Context , client * api.RESTClient , repo github. Repo , branch , sourceBranch string ) error {
192
186
// Get the SHA of the source branch
193
187
var ref struct {
194
188
Object struct {
195
189
SHA string `json:"sha"`
196
190
} `json:"object"`
197
191
}
198
- endpoint := fmt .Sprintf ("repos/%s/%s/git/ref/heads/%s" , owner , repo , sourceBranch )
192
+ endpoint := fmt .Sprintf ("repos/%s/%s/git/ref/heads/%s" , repo . Owner , repo . Repo , sourceBranch )
199
193
err := client .Get (endpoint , & ref )
200
194
if err != nil {
201
195
return fmt .Errorf ("failed to get SHA of source branch: %w" , err )
202
196
}
203
197
204
198
// Update the branch to point to the new SHA
205
- endpoint = fmt .Sprintf ("repos/%s/%s/git/refs/heads/%s" , owner , repo , branch )
199
+ endpoint = fmt .Sprintf ("repos/%s/%s/git/refs/heads/%s" , repo . Owner , repo . Repo , branch )
206
200
payload := map [string ]interface {}{
207
201
"sha" : ref .Object .SHA ,
208
202
"force" : true ,
@@ -215,8 +209,8 @@ func updateRef(ctx context.Context, client *api.RESTClient, owner, repo, branch,
215
209
}
216
210
217
211
// createPullRequest creates a new pull request
218
- func createPullRequest (ctx context.Context , client * api.RESTClient , owner , repo , title , head , base , body string ) error {
219
- endpoint := fmt .Sprintf ("repos/%s/%s/pulls" , owner , repo )
212
+ func createPullRequest (ctx context.Context , client * api.RESTClient , repo github. Repo , title , head , base , body string ) error {
213
+ endpoint := fmt .Sprintf ("repos/%s/%s/pulls" , repo . Owner , repo . Repo )
220
214
payload := map [string ]string {
221
215
"title" : title ,
222
216
"head" : head ,
0 commit comments