diff --git a/config.yaml b/config.yaml index 1967f7bd146eea5a605bde3dc5594678c1b11bd4..95163588853a4bd7edfbaa38ae59781ea35a6ec1 100644 --- a/config.yaml +++ b/config.yaml @@ -7,6 +7,10 @@ databaseName: "cibot" databaseUserName: "root" databasePassword: "******" lgtmCountsRequired: 1 +requiringLabels: +- lgtm +missingLabels: +- do-not-merge watchProjectFiles: - watchProjectFileOwner: openeuler watchprojectFileRepo: infrastructure diff --git a/pkg/cibot/config/config.go b/pkg/cibot/config/config.go index 875d15b2320f0e9a87b9955a91111471169d0f37..ab6b5360a67dd25000d043ba43653df2439626d5 100644 --- a/pkg/cibot/config/config.go +++ b/pkg/cibot/config/config.go @@ -21,6 +21,8 @@ type Config struct { CommandLink string `yaml:"commandLink"` ContactEmail string `yaml:"contactEmail"` LgtmCountsRequired int `yaml:"lgtmCountsRequired"` + RequiringLabels []string `yaml:"requiringLabels"` + MissingLabels []string `yaml:"missingLabels"` } type WatchProjectFile struct { diff --git a/pkg/cibot/label.go b/pkg/cibot/label.go index ec2df41608c63c34bc65bb0739ae56b1444d06f5..6ffa6062247aa873ffaaf3140ed6ccb40f1af28a 100644 --- a/pkg/cibot/label.go +++ b/pkg/cibot/label.go @@ -519,7 +519,7 @@ func (s *Server) patchRepoLabels(labels []string, owner, repo string, createNew } if !createNew { glog.Info("'createNew' flag is false, skip creating.") - return existlabel,nil + return existlabel, nil } createLabelParam := gitee.LabelPostParam{ AccessToken: s.Config.GiteeToken, diff --git a/pkg/cibot/pullrequest.go b/pkg/cibot/pullrequest.go index 8fb12f1dbaf762d86fd0306dd46503bac7d98ce1..c779688753461b9bbb15a6d245538da416b58acf 100644 --- a/pkg/cibot/pullrequest.go +++ b/pkg/cibot/pullrequest.go @@ -9,6 +9,13 @@ import ( "github.com/golang/glog" ) +const ( + cannotMergeMessage = `This pull request can not be merged. :astonished: +%s` + nonRequiringLabelsMessage = ` Labels [%s] need to be added.` + nonMissingLabelsMessage = ` Labels [%s] need to be removed.` +) + // HandlePullRequestEvent handles pull request event func (s *Server) HandlePullRequestEvent(event *gitee.PullRequestEvent) { if event == nil { @@ -144,14 +151,14 @@ func (s *Server) hasLgtmLabel(labels []gitee.Label) bool { return false } -func (s *Server) legalForMerge(labels []gitee.Label) bool { +func (s *Server) readyForMerge(labels []gitee.Label) bool { aproveLabel := 0 lgtmLabel := 0 lgtmPrefix := "" leastLgtm := 0 if s.Config.LgtmCountsRequired > 1 { leastLgtm = s.Config.LgtmCountsRequired - lgtmPrefix =fmt.Sprintf(LabelLgtmWithCommenter, "") + lgtmPrefix = fmt.Sprintf(LabelLgtmWithCommenter, "") } else { leastLgtm = 1 lgtmPrefix = LabelNameLgtm @@ -167,6 +174,14 @@ func (s *Server) legalForMerge(labels []gitee.Label) bool { return aproveLabel == 1 && lgtmLabel >= leastLgtm } +// check with the labels contraints requiring/missing to determine if mergable +func (s *Server) legalLabelsForMerge(labels []gitee.Label) ([]string, []string) { + nonRequiring, _ := s.labelDiffer(s.Config.RequiringLabels, labels) + _, nonMissing := s.labelDiffer(s.Config.MissingLabels, labels) + + return nonRequiring, nonMissing +} + // MergePullRequest with lgtm and approved label func (s *Server) MergePullRequest(event *gitee.NoteEvent) error { // get basic params @@ -187,27 +202,53 @@ func (s *Server) MergePullRequest(event *gitee.NoteEvent) error { glog.Infof("List of pr labels: %v", listofPrLabels) // ready to merge - if s.legalForMerge(listofPrLabels) { - // current pr can be merged - if event.PullRequest.Mergeable { - // remove assignees - err = s.RemoveAssigneesInPullRequest(event) - if err != nil { - glog.Errorf("unable to remove assignees. err: %v", err) - return err + if s.readyForMerge(listofPrLabels) { + nonRequiringLabels, nonMissingLabels := s.legalLabelsForMerge(listofPrLabels) + if len(nonRequiringLabels) == 0 && len(nonMissingLabels) == 0 { + // current pr can be merged + if event.PullRequest.Mergeable { + // remove assignees + err = s.RemoveAssigneesInPullRequest(event) + if err != nil { + glog.Errorf("unable to remove assignees. err: %v", err) + return err + } + // remove testers + err = s.RemoveTestersInPullRequest(event) + if err != nil { + glog.Errorf("unable to remove testers. err: %v", err) + return err + } + // merge pr + body := gitee.PullRequestMergePutParam{} + body.AccessToken = s.Config.GiteeToken + _, err = s.GiteeClient.PullRequestsApi.PutV5ReposOwnerRepoPullsNumberMerge(s.Context, owner, repo, prNumber, body) + if err != nil { + glog.Errorf("unable to merge pull request. err: %v", err) + return err + } } - // remove testers - err = s.RemoveTestersInPullRequest(event) - if err != nil { - glog.Errorf("unable to remove testers. err: %v", err) - return err + } else { + // add comment to pr to show the labels reason of not mergable + nonRequiringMsg := "" + if len(nonRequiringLabels) > 0 { + nonRequiringMsg = fmt.Sprintf(nonRequiringLabelsMessage, strings.Join(nonRequiringLabels, ",")) } - // merge pr - body := gitee.PullRequestMergePutParam{} + nonMissingMsg := "" + if len(nonMissingLabels) > 0 { + nonMissingMsg = fmt.Sprintf(nonMissingLabelsMessage, strings.Join(nonMissingLabels, ",")) + } + + // add comment back to pr + body := gitee.PullRequestCommentPostParam{} body.AccessToken = s.Config.GiteeToken - _, err = s.GiteeClient.PullRequestsApi.PutV5ReposOwnerRepoPullsNumberMerge(s.Context, owner, repo, prNumber, body) + body.Body = fmt.Sprintf(cannotMergeMessage, fmt.Sprintf("%s%s", nonRequiringMsg, nonMissingMsg)) + owner := event.Repository.Namespace + repo := event.Repository.Name + number := event.PullRequest.Number + _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body) if err != nil { - glog.Errorf("unable to merge pull request. err: %v", err) + glog.Errorf("unable to add comment in pull request: %v", err) return err } }