Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rebase: remove existed comments #13

Merged
merged 1 commit into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 0 additions & 83 deletions internal/linters/git-flow/rebase-suggestion/rebase-suggestion.go

This file was deleted.

172 changes: 172 additions & 0 deletions internal/linters/git-flow/rebase-suggestion/rebase_suggestion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
Copyright 2024 Qiniu Cloud (qiniu.com).

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rebase_suggestion

import (
"bytes"
"context"
"fmt"
"regexp"
"strings"
"text/template"

"github.com/cr-bot/config"
"github.com/cr-bot/internal/linters"
"github.com/google/go-github/v57/github"
"github.com/qiniu/x/log"
)

var lintName = "rebase-suggestion"

func init() {
linters.RegisterCommentHandler(lintName, rebaseSuggestionHandler)
}

func rebaseSuggestionHandler(linterConfig config.Linter, agent linters.Agent, event github.PullRequestEvent) error {
var (
org = event.GetRepo().GetOwner().GetLogin()
repo = event.GetRepo().GetName()
number = event.GetNumber()
)

preFilterCommits, err := listMatchedCommitMessages(context.Background(), agent, org, repo, number)
if err != nil {
return err
}

existedComments, err := listExistedComments(context.Background(), agent, org, repo, number)
if err != nil {
return err
}

return handle(context.Background(), agent, org, repo, number, preFilterCommits, existedComments)
}

var rebaseSuggestionFlag = "**[REBASE SUGGESTION]**"

var rebaseSuggestionTmpl = rebaseSuggestionFlag + ` This PR has commit message like:
{{range .}}
> {{.}}
{{end}}

Which seems insignificant, recommend to use ` + "`git rebase <upstream> <branch>`" + `to reorganize your PR.

<details>

If you have any questions about this comment, feel free to raise an issue here:

- **https://github.com/qiniu/cr-bot/issues**

</details>
`

func handle(ctx context.Context, agent linters.Agent, org, repo string, number int, prefilterCommits []*github.RepositoryCommit, existedComments []*github.IssueComment) error {
var commitMessages []string
for _, commit := range prefilterCommits {
commitMessages = append(commitMessages, *commit.Commit.Message)
}

tmpl, err := template.New("rebase-suggestion").Parse(rebaseSuggestionTmpl)
if err != nil {
return err
}

var buf bytes.Buffer
if err = tmpl.Execute(&buf, commitMessages); err != nil {
return err
}

var expectedComment = buf.String()

// check if comment already existed
for _, comment := range existedComments {
if comment.Body != nil && *comment.Body == expectedComment {
log.Infof("comment already existed: %v", comment.Body)
return nil
}
}

// remove old comments
for _, comment := range existedComments {
if comment.Body != nil && strings.Contains(*comment.Body, rebaseSuggestionFlag) {
_, err := agent.GitHubClient().Issues.DeleteComment(context.Background(), org, repo, *comment.ID)
if err != nil {
log.Warnf("delete comment failed: %v", err)
continue
}
}
}

// add new comment
if len(commitMessages) > 0 {
c, resp, err := agent.GitHubClient().Issues.CreateComment(context.Background(), org, repo, number, &github.IssueComment{
Body: &expectedComment,
})
if err != nil {
return err
}
if resp.StatusCode != 201 {
log.Errorf("create comment failed: %v", resp)
return fmt.Errorf("create comment failed: %v", resp.Body)
}

log.Infof("create comment success: %v", c)
}

return nil
}

func listMatchedCommitMessages(ctx context.Context, agent linters.Agent, org, repo string, number int) ([]*github.RepositoryCommit, error) {
var preFilterCommits []*github.RepositoryCommit
opts := &github.ListOptions{}
commits, response, err := agent.GitHubClient().PullRequests.ListCommits(context.Background(), org, repo, number, opts)
if err != nil {
return preFilterCommits, err
}

if response.StatusCode != 200 {
log.Errorf("list commits failed: %v", response)
return preFilterCommits, fmt.Errorf("list commits failed: %v", response.Body)
}

pattern := `^Merge (.*) into (.*)$`
reg := regexp.MustCompile(pattern)

for _, commit := range commits {
if commit.Commit != nil && commit.Commit.Message != nil {
if reg.MatchString(*commit.Commit.Message) {
preFilterCommits = append(preFilterCommits, commit)
}
}
}

return preFilterCommits, nil
}

func listExistedComments(ctx context.Context, agent linters.Agent, org, repo string, number int) ([]*github.IssueComment, error) {
comments, resp, err := agent.GitHubClient().Issues.ListComments(ctx, org, repo, number, &github.IssueListCommentsOptions{})
if err != nil {
return nil, err
}

if resp.StatusCode != 200 {
log.Errorf("list comments failed: %v", resp)
return nil, fmt.Errorf("list comments failed: %v", resp.Body)
}

return comments, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package rebase_suggestion

import (
"bytes"
"testing"
"text/template"
)

func TestRebaseSuggestionTmpl(t *testing.T) {
tmpl, err := template.New("rebase_suggestion").Parse(rebaseSuggestionTmpl)
if err != nil {
t.Fatal(err)
}

var buf bytes.Buffer
err = tmpl.Execute(&buf, []string{"commit1", "commit2"})
if err != nil {
t.Fatal(err)
}

t.Log(buf.String())
}
9 changes: 5 additions & 4 deletions server.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
Copyright 2024 Qiniu Cloud (qiniu.com).

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand Down Expand Up @@ -158,12 +158,13 @@ func (s *Server) handle(log *xlog.Logger, ctx context.Context, event *github.Pul
lingerConfig.WorkDir = r.Directory() + "/" + lingerConfig.WorkDir
}

log.Infof("running %s on repo %v with config %v", name, fmt.Sprintf("%s/%s", org, repo), lingerConfig)

agent := linters.NewAgent(s.gc, s.gitClientFactory, s.config)
if err := fn(lingerConfig, agent, *event); err != nil {
log.Errorf("failed to run linter: %v", err)
return err
}
log.Infof("commented on PR %d (%s) successfully\n", num, org+"/"+repo)
}

return nil
Expand Down