/
mergeBlocker.go
120 lines (110 loc) · 3.79 KB
/
mergeBlocker.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
package cmd
import (
"context"
"fmt"
"github.com/google/go-github/v30/github"
"github.com/integr8ly/delorean/pkg/services"
"github.com/spf13/cobra"
"strings"
)
type mergeBlockerCmdOptions struct {
baseBranch string
isDeletion bool
}
var mergeBlockerCmdOpts = &mergeBlockerCmdOptions{}
const MergeBlockerLabel = "tide/merge-blocker"
// mergeBlockerCmd represents the mergeBlocker command
var mergeBlockerCmd = &cobra.Command{
Use: "merge-blocker",
Short: "Change or delete merge blockers",
Long: `A merge blocker can block all merges against a given branch. The merge-blocker command can be used to create or delete merge blockers`,
Run: func(cmd *cobra.Command, args []string) {
var token string
var err error
if token, err = requireValue(GithubTokenKey); err != nil {
handleError(err)
}
client := newGithubClient(token)
repoInfo := &githubRepoInfo{owner: integreatlyGHOrg, repo: integreatlyOperatorRepo}
if err = DoMergeBlocker(cmd.Context(), client.Issues, repoInfo, mergeBlockerCmdOpts); err != nil {
handleError(err)
}
},
}
func DoMergeBlocker(ctx context.Context, client services.GithubIssuesService, repoInfo *githubRepoInfo, cmdOpts *mergeBlockerCmdOptions) error {
if cmdOpts.isDeletion {
if _, err := closeMergeBlocker(ctx, client, repoInfo, cmdOpts.baseBranch); err != nil {
return err
}
} else {
if _, err := createMergeBlocker(ctx, client, repoInfo, cmdOpts.baseBranch); err != nil {
return err
}
}
return nil
}
func createMergeBlocker(ctx context.Context, client services.GithubIssuesService, repoInfo *githubRepoInfo, branch string) (*github.Issue, error) {
existing, err := searchMergeBlockers(ctx, client, repoInfo, branch)
if err != nil {
return nil, err
}
if existing != nil {
fmt.Println(fmt.Sprintf("Merge blocker issue is already created: %s", existing.GetHTMLURL()))
return existing, nil
}
title := fmt.Sprintf("Merge Blocker|branch:%s", branch)
state := "open"
issue := &github.IssueRequest{
Title: &title,
Labels: &([]string{MergeBlockerLabel}),
State: &state,
}
created, _, err := client.Create(ctx, repoInfo.owner, repoInfo.repo, issue)
if err != nil {
return nil, err
}
fmt.Println(fmt.Sprintf("Merge blocker issue created: %s", created.GetHTMLURL()))
return created, nil
}
func closeMergeBlocker(ctx context.Context, client services.GithubIssuesService, repoInfo *githubRepoInfo, branch string) (*github.Issue, error) {
existing, err := searchMergeBlockers(ctx, client, repoInfo, branch)
if err != nil {
return nil, err
}
if existing == nil {
return existing, fmt.Errorf("no merge blocker issue for the given branch: %s", branch)
}
state := "closed"
issue := &github.IssueRequest{
Title: existing.Title,
Labels: &([]string{MergeBlockerLabel}),
State: &state,
}
updated, _, err := client.Edit(ctx, repoInfo.owner, repoInfo.repo, *existing.Number, issue)
if err != nil {
return nil, err
}
fmt.Println(fmt.Sprintf("Merge blocker issue closed: %s", updated.GetHTMLURL()))
return updated, nil
}
func searchMergeBlockers(ctx context.Context, client services.GithubIssuesService, repoInfo *githubRepoInfo, branch string) (*github.Issue, error) {
opts := &github.IssueListByRepoOptions{
State: "open",
Labels: []string{MergeBlockerLabel},
}
issues, _, err := client.ListByRepo(ctx, repoInfo.owner, repoInfo.repo, opts)
if err != nil {
return nil, err
}
for _, issue := range issues {
if strings.Index(*issue.Title, fmt.Sprintf("branch:%s", branch)) > -1 {
return issue, nil
}
}
return nil, nil
}
func init() {
releaseCmd.AddCommand(mergeBlockerCmd)
mergeBlockerCmd.Flags().StringVarP(&mergeBlockerCmdOpts.baseBranch, "branch", "b", "master", "name of the branch to block merge")
mergeBlockerCmd.Flags().BoolVarP(&mergeBlockerCmdOpts.isDeletion, "delete", "d", false, "Delete the merge blocker instead of create")
}