-
Notifications
You must be signed in to change notification settings - Fork 0
/
github_api.go
135 lines (119 loc) · 3.71 KB
/
github_api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"fmt"
"github.com/google/go-github/github"
"gopkg.in/fatih/set.v0"
)
func getAllRepositories(client *github.Client, organization string) ([]*github.Repository, error) {
var (
repositories []*github.Repository
resp = new(github.Response)
listOpts = &github.RepositoryListByOrgOptions{"sources", github.ListOptions{PerPage: 100}}
)
// Get all pages
resp.NextPage = 1
for resp.NextPage != 0 {
listOpts.Page = resp.NextPage
fetched, newResp, err := client.Repositories.ListByOrg(organization, listOpts)
resp = newResp
if err != nil {
return nil, err
}
repositories = append(repositories, fetched...)
}
return repositories, nil
}
func processRepository(client *github.Client, repository *github.Repository, excludedBranches []string, dryRun bool) error {
var (
owner = *repository.Owner.Login
repoName = *repository.Name
)
// Collect branches than are currently in use as target or source branch in open PRs, to avoid deleting them
openPRs, err := pullRequestsByState(client, owner, repoName, "open")
if err != nil {
return err
}
excluded := buildExclusionList(excludedBranches, openPRs)
// Collect all closed PRs to scan
closedPRs, err := pullRequestsByState(client, owner, repoName, "closed")
if err != nil {
return err
}
// Collect all existing branches, try not to delete already deleted branches
existingBranches, err := listBranches(client, owner, repoName)
if err != nil {
return err
}
for _, closedPR := range closedPRs {
var (
sourceBranch = *closedPR.Head.Ref
sourceRepo = *closedPR.Head.User.Login
)
for _, branch := range existingBranches {
// Delete if:
// -> the old source branch matches an existing source branch
// -> the source branch was on the same repository (don't touch forks, leave it to jessfraz/ghb0t)
// -> the branch is not in the exclusion list
if branch == sourceBranch && sourceRepo == owner && !excluded.Has(sourceBranch) {
if !dryRun {
if _, err := client.Git.DeleteRef(owner, repoName, fmt.Sprintf("refs/%s", sourceBranch)); err != nil {
return err
}
}
fmt.Printf("%s/%s#%d => unused branch %s deleted.\n", owner, repoName, *closedPR.Number, sourceBranch)
}
}
}
return nil
}
func pullRequestsByState(client *github.Client, owner string, repoName string, state string) ([]*github.PullRequest, error) {
var (
pullRequests []*github.PullRequest
resp = new(github.Response)
listOpts = &github.PullRequestListOptions{state, "", "", "", "", github.ListOptions{PerPage: 100}}
)
// Get all pages
resp.NextPage = 1
for resp.NextPage != 0 {
listOpts.Page = resp.NextPage
fetched, newResp, err := client.PullRequests.List(owner, repoName, listOpts)
resp = newResp
if err != nil {
return nil, err
}
pullRequests = append(pullRequests, fetched...)
}
return pullRequests, nil
}
func buildExclusionList(excludedBranches []string, openPRs []*github.PullRequest) *set.SetNonTS {
excluded := set.NewNonTS()
for _, branch := range excludedBranches {
excluded.Add(branch)
}
for _, openPR := range openPRs {
excluded.Add(*openPR.Base.Ref)
excluded.Add(*openPR.Head.Ref)
}
return excluded
}
func listBranches(client *github.Client, owner string, repoName string) ([]string, error) {
var (
branchNames []string
resp = new(github.Response)
listOpts = &github.ListOptions{PerPage: 100}
)
// Get all pages
resp.NextPage = 1
for resp.NextPage != 0 {
listOpts.Page = resp.NextPage
fetched, newResp, err := client.Repositories.ListBranches(owner, repoName, listOpts)
resp = newResp
if err != nil {
return nil, err
}
for _, branch := range fetched {
branchNames = append(branchNames, *branch.Name)
}
}
return branchNames, nil
}