This repository was archived by the owner on Feb 14, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
177 lines (149 loc) · 4.44 KB
/
main.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package main
import (
"context"
"log"
"os"
"strings"
"sync"
"github.com/google/go-github/v35/github"
"golang.org/x/oauth2"
)
const defaultNeedRebaseLabel = "S-needs-rebase"
const (
ACTION_TYPE_PUSH = iota
ACTION_TYPE_PULL_REQ = iota
)
func main() {
githubToken := os.Getenv("GITHUB_TOKEN")
if githubToken == "" {
log.Fatalln("$GITHUB_TOKEN is empty")
return
}
repositoryFullName := os.Getenv("GITHUB_REPOSITORY")
if repositoryFullName == "" {
log.Fatalln("$GITHUB_REPOSITORY is empty")
return
}
var actionType int
githubEventName := os.Getenv("GITHUB_EVENT_NAME")
switch githubEventName {
case "":
log.Fatalln("$GITHUB_EVENT_NAME is empty")
return
case "push":
actionType = ACTION_TYPE_PUSH
case "pull_request":
actionType = ACTION_TYPE_PULL_REQ
default:
log.Fatalln("Unsupported $GITHUB_EVENT_NAME: " + githubEventName)
return
}
githubEventPath := os.Getenv("GITHUB_EVENT_PATH")
if githubEventPath == "" {
log.Fatalln("$GITHUB_EVENT_PATH is empty")
return
}
needRebaseLabel := os.Getenv("LABEL_NEED_REBASE")
if needRebaseLabel == "" {
needRebaseLabel = defaultNeedRebaseLabel
}
log.Printf("We will supply `%v` if the pull request is unmergeable\n", needRebaseLabel)
githubClient := createGithubClient(githubToken)
if githubClient == nil {
log.Fatalln("could not create githubClient")
return
}
repoPair := strings.Split(repositoryFullName, "/")
repoOwner := repoPair[0]
repoName := repoPair[1]
switch actionType {
case ACTION_TYPE_PUSH:
log.Println("Search and mark unmergeable pull requests.")
checkWhetherPushCausedUnmergeable(githubClient, githubEventPath, repoOwner, repoName, needRebaseLabel)
case ACTION_TYPE_PULL_REQ:
log.Println("Check whether the synced pull request is mergeable or not.")
checkPrIsChangedToMergeable(githubClient, githubEventPath, repoOwner, repoName, needRebaseLabel)
default:
return
}
}
func createGithubClient(token string) *github.Client {
ts := oauth2.StaticTokenSource(
&oauth2.Token{
AccessToken: token,
},
)
tc := oauth2.NewClient(oauth2.NoContext, ts)
client := github.NewClient(tc)
return client
}
func checkWhetherPushCausedUnmergeable(githubClient *github.Client, githubEventPath string, repoOwner string, repoName string, needRebaseLabel string) {
eventData := loadJSONFileForPushEventData(githubEventPath)
if eventData == nil {
log.Fatal("Could not get eventData")
return
}
eventOriginRefName := eventData.GetRef()
if eventOriginRefName == "" {
log.Println("eventOriginRefName is empty string")
return
}
compareURL := eventData.GetCompare()
if compareURL == "" {
// avoid this.
log.Println("compareURL is empty string")
}
openedPRList := getOpenPullRequestAll(githubClient, repoOwner, repoName)
if openedPRList == nil {
return
}
wg := &sync.WaitGroup{}
for _, pr := range openedPRList {
wg.Add(1)
go func(pr *github.PullRequest) {
defer wg.Done()
number := pr.GetNumber()
ok, hasRelationShip := isRelatedToPushedBranch(pr, eventOriginRefName)
if !ok {
log.Printf("#%v mysterious result and abort it \n", number)
return
}
if !hasRelationShip {
log.Printf("#%v is not related to %v \n", number, eventOriginRefName)
return
}
checkAndMarkIfPullRequestUnmergeable(githubClient, repoOwner, repoName, pr, compareURL, needRebaseLabel)
}(pr)
}
wg.Wait()
}
func checkPrIsChangedToMergeable(githubClient *github.Client, githubEventPath string, repoOwner string, repoName string, needRebaseLabel string) {
eventData := loadJSONFileForPullRequestEventData(githubEventPath)
if eventData == nil {
log.Fatal("Could not get eventData")
return
}
if action := eventData.GetAction(); action != "synchronize" {
log.Printf("we cannot handle `#%v`", action)
return
}
prNumber := eventData.GetNumber()
if prNumber == 0 {
log.Println("we cannot get the PR number for this pull request")
return
}
_, isUnmergeable, err := shouldMarkPullRequestNeedRebase(githubClient, repoOwner, repoName, prNumber, needRebaseLabel)
if err != nil {
return
}
if isUnmergeable {
log.Printf("#%v is not mergeable. We don't do anything", prNumber)
return
}
ctx := context.Background()
if _, err := githubClient.Issues.RemoveLabelForIssue(ctx, repoOwner, repoName, prNumber, needRebaseLabel); err != nil {
log.Printf("#%v is mergeable but fail to remove the label `%v` because `%v`", prNumber, needRebaseLabel, err)
return
}
log.Printf("#%v is mergeable. We removed the label `%v`", prNumber, needRebaseLabel)
}