Skip to content

Commit 569d41b

Browse files
committed
Add Orgs sharding for Blunderbuss
Using a pointer lets sharding determine whether a config had been provided so they can be properly compared. If one is not provided, this also instantiates one in `setDefaults()`, which is called following the sharding logic. Signed-off-by: Dale Haiducek <[email protected]>
1 parent 2b7da0b commit 569d41b

File tree

8 files changed

+599
-31
lines changed

8 files changed

+599
-31
lines changed

cmd/deck/main_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,8 +888,9 @@ func TestHandlePluginConfig(t *testing.T) {
888888
}},
889889
},
890890
Blunderbuss: plugins.Blunderbuss{
891-
ExcludeApprovers: true,
892-
},
891+
BlunderbussConfig: &plugins.BlunderbussConfig{
892+
ExcludeApprovers: true,
893+
}},
893894
}
894895
pluginAgent := &plugins.ConfigAgent{}
895896
pluginAgent.Set(&c)

pkg/genyaml/genyaml.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ func fieldType(field *ast.Field, recurse bool) (string, bool) {
296296
case *ast.SelectorExpr:
297297
// SelectorExpr are not object types yet reference one, thus continue with DFS.
298298
isSelect = true
299+
case *ast.StarExpr:
300+
// Encountered a pointer--overwrite typeName with ast.Expr
301+
typeName = fmt.Sprint(x.X)
299302
}
300303

301304
return recurse || isSelect

pkg/plugins/blunderbuss/blunderbuss.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,43 @@ func helpProvider(config *plugins.Configuration, _ []config.OrgRepo) (*pluginhel
6464
two := 2
6565
yamlSnippet, err := plugins.CommentMap.GenYaml(&plugins.Configuration{
6666
Blunderbuss: plugins.Blunderbuss{
67-
ReviewerCount: &two,
68-
MaxReviewerCount: 3,
69-
ExcludeApprovers: true,
70-
UseStatusAvailability: true,
71-
IgnoreAuthors: []string{},
67+
BlunderbussConfig: &plugins.BlunderbussConfig{
68+
ReviewerCount: &two,
69+
MaxReviewerCount: 3,
70+
ExcludeApprovers: true,
71+
UseStatusAvailability: true,
72+
IgnoreAuthors: []string{},
73+
},
74+
Orgs: map[string]plugins.BlunderbussOrgConfig{
75+
"": {
76+
BlunderbussConfig: &plugins.BlunderbussConfig{
77+
ReviewerCount: &two,
78+
MaxReviewerCount: 3,
79+
ExcludeApprovers: true,
80+
UseStatusAvailability: true,
81+
IgnoreAuthors: []string{},
82+
},
83+
Repos: map[string]plugins.BlunderbussRepoConfig{
84+
"": {
85+
BlunderbussConfig: plugins.BlunderbussConfig{
86+
ReviewerCount: &two,
87+
MaxReviewerCount: 3,
88+
ExcludeApprovers: true,
89+
UseStatusAvailability: true,
90+
IgnoreAuthors: []string{},
91+
},
92+
},
93+
},
94+
},
95+
},
7296
},
7397
})
7498
if err != nil {
7599
logrus.WithError(err).Warnf("cannot generate comments for %s plugin", PluginName)
76100
}
77101
pluginHelp := &pluginhelp.PluginHelp{
78-
Description: "The blunderbuss plugin automatically requests reviews from reviewers when a new PR is created. The reviewers are selected based on the reviewers specified in the OWNERS files that apply to the files modified by the PR.",
102+
Description: "The blunderbuss plugin automatically requests reviews from reviewers when a new PR is created. " +
103+
"The reviewers are selected based on the reviewers specified in the OWNERS files that apply to the files modified by the PR.",
79104
Config: map[string]string{
80105
"": configString(reviewCount),
81106
},
@@ -137,14 +162,14 @@ func handlePullRequestEvent(pc plugins.Agent, pre github.PullRequestEvent) error
137162
pc.GitHubClient,
138163
pc.OwnersClient,
139164
pc.Logger,
140-
pc.PluginConfig.Blunderbuss,
165+
pc.PluginConfig.BlunderbussFor(pre.Repo.Owner.Login, pre.Repo.Name),
141166
pre.Action,
142167
&pre.PullRequest,
143168
&pre.Repo,
144169
)
145170
}
146171

147-
func handlePullRequest(ghc githubClient, roc repoownersClient, log *logrus.Entry, config plugins.Blunderbuss, action github.PullRequestEventAction, pr *github.PullRequest, repo *github.Repo) error {
172+
func handlePullRequest(ghc githubClient, roc repoownersClient, log *logrus.Entry, config plugins.BlunderbussConfig, action github.PullRequestEventAction, pr *github.PullRequest, repo *github.Repo) error {
148173
if !(action == github.PullRequestActionOpened || action == github.PullRequestActionReadyForReview) || assign.CCRegexp.MatchString(pr.Body) {
149174
return nil
150175
}
@@ -176,7 +201,7 @@ func handleGenericCommentEvent(pc plugins.Agent, ce github.GenericCommentEvent)
176201
pc.GitHubClient,
177202
pc.OwnersClient,
178203
pc.Logger,
179-
pc.PluginConfig.Blunderbuss,
204+
pc.PluginConfig.BlunderbussFor(ce.Repo.Owner.Login, ce.Repo.Name),
180205
ce.Action,
181206
ce.IsPR,
182207
ce.Number,
@@ -186,7 +211,7 @@ func handleGenericCommentEvent(pc plugins.Agent, ce github.GenericCommentEvent)
186211
)
187212
}
188213

189-
func handleGenericComment(ghc githubClient, roc repoownersClient, log *logrus.Entry, config plugins.Blunderbuss, action github.GenericCommentEventAction, isPR bool, prNumber int, issueState string, repo *github.Repo, body string) error {
214+
func handleGenericComment(ghc githubClient, roc repoownersClient, log *logrus.Entry, config plugins.BlunderbussConfig, action github.GenericCommentEventAction, isPR bool, prNumber int, issueState string, repo *github.Repo, body string) error {
190215
if action != github.GenericCommentActionCreated || !isPR || issueState == "closed" {
191216
return nil
192217
}

pkg/plugins/blunderbuss/blunderbuss_test.go

Lines changed: 184 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ func TestHandlePullRequest(t *testing.T) {
643643
pr := github.PullRequest{Number: 5, User: github.User{Login: "author"}, Body: tc.body, Draft: tc.draft}
644644
repo := github.Repo{Owner: github.User{Login: "org"}, Name: "repo"}
645645
fghc := newFakeGitHubClient(&pr, tc.filesChanged)
646-
c := plugins.Blunderbuss{
646+
c := plugins.BlunderbussConfig{
647647
ReviewerCount: &tc.reviewerCount,
648648
MaxReviewerCount: 0,
649649
ExcludeApprovers: false,
@@ -667,6 +667,70 @@ func TestHandlePullRequest(t *testing.T) {
667667
}
668668
}
669669

670+
func TestHandlePullRequestShardedConfig(t *testing.T) {
671+
froc := &fakeRepoownersClient{
672+
foc: &fakeOwnersClient{
673+
owners: map[string]string{
674+
"a.go": "1",
675+
},
676+
leafReviewers: map[string]sets.Set[string]{
677+
"a.go": sets.New("al"),
678+
},
679+
},
680+
}
681+
682+
var tc = struct {
683+
action github.PullRequestEventAction
684+
body string
685+
filesChanged []string
686+
reviewerCount int
687+
expectedRequested []string
688+
draft bool
689+
ignoreDrafts bool
690+
ignoreAuthors []string
691+
}{
692+
action: github.PullRequestActionOpened,
693+
filesChanged: []string{"a.go"},
694+
draft: false,
695+
ignoreDrafts: true,
696+
reviewerCount: 1,
697+
}
698+
699+
pr := github.PullRequest{Number: 5, User: github.User{Login: "author"}, Body: tc.body, Draft: tc.draft}
700+
repo := github.Repo{Owner: github.User{Login: "org"}, Name: "repo"}
701+
fghc := newFakeGitHubClient(&pr, tc.filesChanged)
702+
c := &plugins.Configuration{
703+
Blunderbuss: plugins.Blunderbuss{
704+
BlunderbussConfig: &plugins.BlunderbussConfig{
705+
ReviewerCount: &tc.reviewerCount,
706+
MaxReviewerCount: 0,
707+
ExcludeApprovers: false,
708+
IgnoreDrafts: tc.ignoreDrafts,
709+
IgnoreAuthors: tc.ignoreAuthors,
710+
},
711+
Orgs: map[string]plugins.BlunderbussOrgConfig{
712+
"org": {
713+
Repos: map[string]plugins.BlunderbussRepoConfig{
714+
"org/repo": {
715+
BlunderbussConfig: plugins.BlunderbussConfig{
716+
IgnoreAuthors: []string{"author"},
717+
}}}}}}}
718+
bc := c.BlunderbussFor(repo.Owner.Login, repo.Name)
719+
720+
if err := handlePullRequest(
721+
fghc, froc, logrus.WithField("plugin", PluginName),
722+
bc, tc.action, &pr, &repo,
723+
); err != nil {
724+
t.Fatalf("unexpected error from handle: %v", err)
725+
}
726+
727+
sort.Strings(fghc.requested)
728+
sort.Strings(tc.expectedRequested)
729+
if !reflect.DeepEqual(fghc.requested, tc.expectedRequested) {
730+
t.Fatalf("expected the requested reviewers to be %q, but got %q.", tc.expectedRequested, fghc.requested)
731+
}
732+
}
733+
670734
func TestHandleGenericComment(t *testing.T) {
671735
froc := &fakeRepoownersClient{
672736
foc: &fakeOwnersClient{
@@ -740,7 +804,7 @@ func TestHandleGenericComment(t *testing.T) {
740804
pr := github.PullRequest{Number: 5, User: github.User{Login: "author"}}
741805
fghc := newFakeGitHubClient(&pr, tc.filesChanged)
742806
repo := github.Repo{Owner: github.User{Login: "org"}, Name: "repo"}
743-
config := plugins.Blunderbuss{
807+
config := plugins.BlunderbussConfig{
744808
ReviewerCount: &tc.reviewerCount,
745809
MaxReviewerCount: 0,
746810
ExcludeApprovers: false,
@@ -762,17 +826,125 @@ func TestHandleGenericComment(t *testing.T) {
762826
}
763827
}
764828

829+
func TestHandleGenericCommentShardedConfig(t *testing.T) {
830+
froc := &fakeRepoownersClient{
831+
foc: &fakeOwnersClient{
832+
owners: map[string]string{
833+
"a.go": "1",
834+
"b.go": "2",
835+
},
836+
leafReviewers: map[string]sets.Set[string]{
837+
"a.go": sets.New("al"),
838+
"b.go": sets.New("bob"),
839+
"c.go": sets.New("sarah"),
840+
"d.go": sets.New("busy-user"),
841+
},
842+
},
843+
}
844+
845+
overrideOrgReviewerCount := 2
846+
overrideRepoReviewerCount := 3
847+
var testcases = []struct {
848+
name string
849+
orgConfig map[string]plugins.BlunderbussOrgConfig
850+
expectedRequested int
851+
}{
852+
{
853+
name: "overrides default config with org config",
854+
orgConfig: map[string]plugins.BlunderbussOrgConfig{
855+
"org": {
856+
BlunderbussConfig: &plugins.BlunderbussConfig{
857+
ReviewerCount: &overrideOrgReviewerCount,
858+
MaxReviewerCount: overrideOrgReviewerCount,
859+
}},
860+
},
861+
expectedRequested: 2,
862+
},
863+
{
864+
name: "overrides default and org config with repo config",
865+
orgConfig: map[string]plugins.BlunderbussOrgConfig{
866+
"org": {
867+
BlunderbussConfig: &plugins.BlunderbussConfig{
868+
ReviewerCount: &overrideOrgReviewerCount,
869+
MaxReviewerCount: overrideOrgReviewerCount,
870+
},
871+
Repos: map[string]plugins.BlunderbussRepoConfig{
872+
"org/repo": {
873+
BlunderbussConfig: plugins.BlunderbussConfig{
874+
ReviewerCount: &overrideRepoReviewerCount,
875+
MaxReviewerCount: overrideRepoReviewerCount,
876+
}}}},
877+
},
878+
expectedRequested: 3,
879+
},
880+
{
881+
name: "Uses org config with invalid repo config key",
882+
orgConfig: map[string]plugins.BlunderbussOrgConfig{
883+
"org": {
884+
BlunderbussConfig: &plugins.BlunderbussConfig{
885+
ReviewerCount: &overrideOrgReviewerCount,
886+
MaxReviewerCount: overrideOrgReviewerCount,
887+
},
888+
Repos: map[string]plugins.BlunderbussRepoConfig{
889+
"repo": {
890+
BlunderbussConfig: plugins.BlunderbussConfig{
891+
ReviewerCount: &overrideRepoReviewerCount,
892+
MaxReviewerCount: overrideRepoReviewerCount,
893+
}}}},
894+
},
895+
expectedRequested: 2,
896+
},
897+
}
898+
899+
for _, tc := range testcases {
900+
t.Run(tc.name, func(t *testing.T) {
901+
pr := github.PullRequest{Number: 5, User: github.User{Login: "author"}}
902+
fghc := newFakeGitHubClient(&pr, []string{"a.go", "b.go", "c.go", "d.go"})
903+
defaultReviewerCount := 1
904+
repo := github.Repo{Owner: github.User{Login: "org"}, Name: "repo"}
905+
906+
config := &plugins.Configuration{
907+
Blunderbuss: plugins.Blunderbuss{
908+
BlunderbussConfig: &plugins.BlunderbussConfig{
909+
IgnoreAuthors: []string{"bob"},
910+
ReviewerCount: &defaultReviewerCount,
911+
UseStatusAvailability: false,
912+
},
913+
Orgs: tc.orgConfig,
914+
}}
915+
bc := config.BlunderbussFor(repo.Owner.Login, repo.Name)
916+
917+
if err := handleGenericComment(
918+
fghc, froc, logrus.WithField("plugin", PluginName), bc,
919+
github.GenericCommentActionCreated, true, pr.Number, "open", &repo, "/auto-cc",
920+
); err != nil {
921+
t.Fatalf("unexpected error from handle: %v", err)
922+
}
923+
924+
if tc.expectedRequested != len(fghc.requested) {
925+
t.Fatalf("expected the requested reviewers to be %d, but got %d.", tc.expectedRequested, len(fghc.requested))
926+
}
927+
})
928+
}
929+
}
930+
765931
func TestHandleGenericCommentEvent(t *testing.T) {
766932
pc := plugins.Agent{
767-
PluginConfig: &plugins.Configuration{},
933+
PluginConfig: &plugins.Configuration{
934+
Blunderbuss: plugins.Blunderbuss{
935+
BlunderbussConfig: &plugins.BlunderbussConfig{},
936+
}},
768937
}
769938
ce := github.GenericCommentEvent{}
770939
handleGenericCommentEvent(pc, ce)
771940
}
772941

773942
func TestHandlePullRequestEvent(t *testing.T) {
774943
pc := plugins.Agent{
775-
PluginConfig: &plugins.Configuration{},
944+
PluginConfig: &plugins.Configuration{
945+
Blunderbuss: plugins.Blunderbuss{
946+
BlunderbussConfig: &plugins.BlunderbussConfig{},
947+
}},
776948
}
777949
pre := github.PullRequestEvent{}
778950
handlePullRequestEvent(pc, pre)
@@ -791,17 +963,21 @@ func TestHelpProvider(t *testing.T) {
791963
configInfoIncludes []string
792964
}{
793965
{
794-
name: "Empty config",
795-
config: &plugins.Configuration{},
966+
name: "Empty config",
967+
config: &plugins.Configuration{
968+
Blunderbuss: plugins.Blunderbuss{
969+
BlunderbussConfig: &plugins.BlunderbussConfig{},
970+
}},
796971
enabledRepos: enabledRepos,
797972
configInfoIncludes: []string{configString(0)},
798973
},
799974
{
800975
name: "ReviewerCount specified",
801976
config: &plugins.Configuration{
802977
Blunderbuss: plugins.Blunderbuss{
803-
ReviewerCount: &[]int{2}[0],
804-
},
978+
BlunderbussConfig: &plugins.BlunderbussConfig{
979+
ReviewerCount: &[]int{2}[0],
980+
}},
805981
},
806982
enabledRepos: enabledRepos,
807983
configInfoIncludes: []string{configString(2)},

0 commit comments

Comments
 (0)