Skip to content

Commit fdf5df9

Browse files
thepuddsgopherbot
authored andcommitted
cmd/gerritbot: automatically flag common issues in PRs
In this CL, we add a set of checks that automatically run against a new GitHub PR after it is imported into Gerrit in order to flag common issues, such as missing a bug reference or ending the first line of the commit with a period. See below for the current set of defined rules. The intent is to save maintainer time, as well as perhaps make a better initial experience for a new contributor via faster feedback with potentially helpful linked resources. By attempting to engage a new contributor as soon as possible along with some pointers, we also hope to get them to reply (successfully) in Gerrit, which in turn helps a potential reviewer see that the contributor knows how to use Gerrit. The package comment in rules.go provides an overview of the implementation approach. The rules themselves are defined as short functions in rules.go. We currently have 100% test coverage within the rules package. Sample results from running on a corpus of 1000 GitHub PRs that were imported into Gerrit: Avg. findings per CL: 1.42 CLs with findings: 74.5% CL hit % Finding -------- ------------------------------------------------ 9.9% title: no package found 0.1% title: no colon then single space after package 13.0% title: no lowercase word after a first colon 2.0% title: ends with period 20.8% body: short 6.1% body: no sentence candidates found 21.7% body: long lines 10.5% body: might use markdown 2.2% body: still contains PR instructions 0.9% body: contains Signed-off-by 43.9% body: no bug reference candidate found 9.3% body: bug format looks incorrect 1.5% body: no bug reference candidate at end See golang/go#61573 for additional background. Updates golang/go#61316 Fixes golang/go#61573 Change-Id: I866cf650608d6ce9c6783aabc17a219f1815908c Reviewed-on: https://go-review.googlesource.com/c/build/+/513397 Auto-Submit: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Damien Neil <[email protected]> Run-TryBot: t hepudds <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
1 parent 2349f06 commit fdf5df9

File tree

4 files changed

+1259
-2
lines changed

4 files changed

+1259
-2
lines changed

cmd/gerritbot/gerritbot.go

+54-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"cloud.google.com/go/compute/metadata"
2929
"github.com/google/go-github/v48/github"
3030
"github.com/gregjones/httpcache"
31+
"golang.org/x/build/cmd/gerritbot/internal/rules"
3132
"golang.org/x/build/gerrit"
3233
"golang.org/x/build/internal/https"
3334
"golang.org/x/build/internal/secret"
@@ -729,7 +730,8 @@ func (b *bot) importGerritChangeFromPR(ctx context.Context, pr *github.PullReque
729730
pushOpts = "%ready"
730731
}
731732

732-
if cl == nil {
733+
newCL := cl == nil
734+
if newCL {
733735
// Add this informational message only on CL creation.
734736
msg := fmt.Sprintf("This Gerrit CL corresponds to GitHub PR %s.\n\nAuthor: %s", prShortLink(pr), author)
735737
pushOpts += ",m=" + url.QueryEscape(msg)
@@ -766,7 +768,57 @@ Please visit Gerrit at %s.
766768
* You should word wrap the PR description at ~76 characters unless you need longer lines (e.g., for tables or URLs).
767769
* See the [Sending a change via GitHub](https://go.dev/doc/contribute#sending_a_change_github) and [Reviews](https://go.dev/doc/contribute#reviews) sections of the Contribution Guide as well as the [FAQ](https://github.com/golang/go/wiki/GerritBot/#frequently-asked-questions) for details.`,
768770
pr.Head.GetSHA(), changeURL)
769-
return b.postGitHubMessageNoDup(ctx, repo.GetOwner().GetLogin(), repo.GetName(), pr.GetNumber(), "", msg)
771+
err = b.postGitHubMessageNoDup(ctx, repo.GetOwner().GetLogin(), repo.GetName(), pr.GetNumber(), "", msg)
772+
if err != nil {
773+
return err
774+
}
775+
776+
if newCL {
777+
// Check if we spot any problems with the CL according to our internal
778+
// set of rules, and if so, add an unresolved comment to Gerrit.
779+
// If the author responds to this, it also helps a reviewer see the author has
780+
// registered for a Gerrit account and knows how to reply in Gerrit.
781+
// TODO: see CL 509135 for possible follow-ups, including possibly always
782+
// asking explicitly if the CL is ready for review even if there are no problems,
783+
// and possibly reminder comments followed by ultimately automatically
784+
// abandoning the CL if the author never replies.
785+
change, err := rules.ParseCommitMessage(repo.GetName(), cmsg)
786+
if err != nil {
787+
return fmt.Errorf("failed to parse commit message for %s: %v", prShortLink(pr), err)
788+
}
789+
problems := rules.Check(change)
790+
if len(problems) > 0 {
791+
summary := rules.FormatResults(problems)
792+
// If needed, summary contains advice for how to edit the commit message.
793+
msg := fmt.Sprintf("Hello %v, I've spotted some possible problems.\n\n"+
794+
"These findings are based on simple heuristics. If a finding appears wrong, briefly reply here saying so. "+
795+
"Otherwise, please address any problems and update the GitHub PR. "+
796+
"When complete, mark this comment as 'Done' and click the [blue 'Reply' button](https://github.com/golang/go/wiki/GerritBot#i-left-a-reply-to-a-comment-in-gerrit-but-no-one-but-me-can-see-it) above.\n\n"+
797+
"%s\n\n"+
798+
"(In general for Gerrit code reviews, the CL author is expected to close out each piece of feedback by "+
799+
"marking it as 'Done' if implemented as suggested or otherwise reply to each review comment. "+
800+
"See the [Review](https://go.dev/doc/contribute#review) section of the Contributing Guide for details.)",
801+
author, summary)
802+
803+
gcl, err := b.gerritChangeForPR(pr)
804+
if err != nil {
805+
return fmt.Errorf("could not look up CL after creation for %s: %v", prShortLink(pr), err)
806+
}
807+
unresolved := true
808+
ri := gerrit.ReviewInput{
809+
Comments: map[string][]gerrit.CommentInput{
810+
"/PATCHSET_LEVEL": {{Message: msg, Unresolved: &unresolved}},
811+
},
812+
}
813+
// TODO: instead of gcl.ID, we might need to do something similar to changeTriple in cmd/coordinator.
814+
err = b.gerritClient.SetReview(ctx, gcl.ChangeID, gcl.ID, ri)
815+
if err != nil {
816+
return fmt.Errorf("could not add findings comment to CL for %s: %v", prShortLink(pr), err)
817+
}
818+
}
819+
}
820+
821+
return nil
770822
}
771823

772824
var changeIdentRE = regexp.MustCompile(`(?m)^Change-Id: (I[0-9a-fA-F]{40})\n?`)

0 commit comments

Comments
 (0)