Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/dev/changelog/pullrequest.go
2492 views
1
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
//
5
// Based on https://github.com/leodido/rn2md with kind permission from the author
6
package main
7
8
import (
9
"context"
10
"strings"
11
"time"
12
13
"github.com/google/go-github/v38/github"
14
logger "github.com/sirupsen/logrus"
15
"github.com/spf13/cobra"
16
)
17
18
type PullRequestOptions struct {
19
Title string
20
Body string
21
Token string
22
ApprovalToken string
23
Org string
24
Repo string
25
BaseBranch string
26
HeadBranch string
27
}
28
29
var prOpts = &PullRequestOptions{}
30
31
var pullRequestCommand = &cobra.Command{
32
Use: "pr",
33
Long: "Creates a pull request on the GitHub repo to update the changelog.",
34
Short: "Creates a PR to update the changelog.",
35
Run: func(c *cobra.Command, args []string) {
36
client := NewClient(prOpts.Token)
37
// PRs can't be approved by the author of the PR. Thus we need two clients.
38
// One for creating the PR and one for approving it.
39
approvalClient := NewClient(prOpts.ApprovalToken)
40
context := context.Background()
41
newPr := &github.NewPullRequest{
42
Title: &prOpts.Title,
43
Body: &prOpts.Body,
44
Base: &prOpts.BaseBranch,
45
Head: &prOpts.HeadBranch,
46
}
47
pr, _, err := client.PullRequests.Create(context, prOpts.Org, prOpts.Repo, newPr)
48
if err != nil {
49
logger.WithError(err).Fatal("Error creating pull request")
50
}
51
logger.WithField("url", pr.URL).WithField("pr", pr.Number).Info("PR successfully created")
52
comment0 := "/assign"
53
newComment := &github.IssueComment{
54
Body: &comment0,
55
}
56
_, _, err = client.Issues.CreateComment(context, prOpts.Org, prOpts.Repo, *pr.Number, newComment)
57
if err != nil {
58
logger.WithError(err).Fatal("Error creating comment")
59
}
60
logger.WithField("url", pr.URL).WithField("pr", pr.Number).Info("PR approval comment added")
61
62
retries := 0
63
64
out:
65
for {
66
retries++
67
if retries > 60 {
68
logger.WithError(err).Fatal("Timeout waiting for 'size/S' label to be added by prow")
69
}
70
labels, _, err := client.Issues.ListLabelsByIssue(context, prOpts.Org, prOpts.Repo, *pr.Number, &github.ListOptions{
71
Page: 1,
72
PerPage: 20,
73
})
74
if err != nil {
75
logger.WithError(err).Fatal("Error getting labels")
76
}
77
for _, l := range labels {
78
if strings.HasPrefix(*l.Name, "size/") {
79
break out
80
}
81
}
82
time.Sleep(time.Second)
83
}
84
85
comment1 := "/approve no-issue"
86
newComment = &github.IssueComment{
87
Body: &comment1,
88
}
89
_, _, err = client.Issues.CreateComment(context, prOpts.Org, prOpts.Repo, *pr.Number, newComment)
90
if err != nil {
91
logger.WithError(err).Fatal("Error creating comment")
92
}
93
logger.WithField("url", pr.URL).WithField("pr", pr.Number).Info("PR approval comment added")
94
95
labels, _, err := client.Issues.AddLabelsToIssue(context, prOpts.Org, prOpts.Repo, *pr.Number, []string{"lgtm", "approved"})
96
if err != nil {
97
logger.WithError(err).Fatal("Error setting labels")
98
}
99
l := ""
100
for _, label := range labels {
101
if l != "" {
102
l += ", "
103
}
104
l += *label.Name
105
}
106
logger.WithField("labels", l).WithField("pr", pr.Number).Info("PR labels successfully added")
107
108
retries = 0
109
for {
110
retries++
111
if retries > 60 {
112
logger.WithError(err).Fatal("Timeout trying to approve PR")
113
}
114
event := "APPROVE"
115
_, _, err := approvalClient.PullRequests.CreateReview(context, prOpts.Org, prOpts.Repo, *pr.Number, &github.PullRequestReviewRequest{Event: &event})
116
if err != nil {
117
logger.WithError(err).Error("Error approving PR. Trying again in a bit.")
118
time.Sleep(time.Second)
119
} else {
120
break
121
}
122
}
123
},
124
}
125
126
func init() {
127
// Setup prFlags before the command is initialized
128
prFlags := pullRequestCommand.PersistentFlags()
129
prFlags.StringVarP(&prOpts.Token, "token", "t", prOpts.Token, "a GitHub personal API token to perform authenticated requests")
130
prFlags.StringVarP(&prOpts.ApprovalToken, "approval-token", "a", prOpts.Token, "a GitHub personal API token to perform PR approval")
131
prFlags.StringVarP(&prOpts.Org, "org", "o", prOpts.Org, "the github organization")
132
prFlags.StringVarP(&prOpts.Repo, "repo", "r", prOpts.Repo, "the github repository name")
133
prFlags.StringVarP(&prOpts.HeadBranch, "head", "H", "main", "the head branch for pull requests")
134
prFlags.StringVarP(&prOpts.BaseBranch, "base", "b", "main", "the base branch for pull requests")
135
prFlags.StringVarP(&prOpts.Title, "title", "T", "[changelog] updated changelog", "the title of the PR")
136
prFlags.StringVarP(&prOpts.Body, "body", "B", "Updated the changelog from recent PR descriptions\n\n```release-note\nNONE\n```\n/werft no-test", "the body of the PR")
137
rootCommand.AddCommand(pullRequestCommand)
138
}
139
140