@@ -11,6 +11,18 @@ import (
1111 "github.com/xlab/treeprint"
1212)
1313
14+ // RequestAction controls what to do about the review request.
15+ type RequestAction byte
16+
17+ const (
18+ // RequestApply will request a review from the user/team if not already requested.
19+ RequestApply = iota
20+ // RequestRemove will remove the review request from the user/team.
21+ RequestRemove
22+ // RequestIgnore always leaves the review request as it is.
23+ RequestIgnore
24+ )
25+
1426// deduplicateReviews returns a list of reviews with at most 1 review per
1527// author, where approval/changes requested reviews are preferred over comments
1628// and later reviews are preferred over earlier ones.
@@ -60,6 +72,7 @@ type ReviewByUserRequirement struct {
6072 gh * client.GitHub
6173 user string
6274 desiredState string
75+ action RequestAction
6376}
6477
6578var _ Requirement = & ReviewByUserRequirement {}
@@ -88,8 +101,9 @@ func (r *ReviewByUserRequirement) IsSatisfied(pr *github.PullRequest, details tr
88101 }
89102 r .gh .Logger .Debugf ("User %s has not reviewed PR %d yet" , r .user , pr .GetNumber ())
90103
91- // If not a dry run, make the user a reviewer if he's not already.
92- if ! r .gh .DryRun {
104+ // If not a dry run, change the review request according to the action.
105+ if ! r .gh .DryRun && r .action != RequestIgnore {
106+ // Check if this user is already requested for review.
93107 requested := false
94108 reviewers , err := r .gh .ListPRReviewers (pr .GetNumber ())
95109 if err != nil {
@@ -104,20 +118,44 @@ func (r *ReviewByUserRequirement) IsSatisfied(pr *github.PullRequest, details tr
104118 }
105119 }
106120
107- if requested {
108- r .gh .Logger .Debugf ("Review of user %s already requested on PR %d" , r .user , pr .GetNumber ())
109- } else {
110- r .gh .Logger .Debugf ("Requesting review from user %s on PR %d" , r .user , pr .GetNumber ())
111- if _ , _ , err := r .gh .Client .PullRequests .RequestReviewers (
112- r .gh .Ctx ,
113- r .gh .Owner ,
114- r .gh .Repo ,
115- pr .GetNumber (),
116- github.ReviewersRequest {
117- Reviewers : []string {r .user },
118- },
119- ); err != nil {
120- r .gh .Logger .Errorf ("Unable to request review from user %s on PR %d: %v" , r .user , pr .GetNumber (), err )
121+ switch r .action {
122+ case RequestApply :
123+ switch {
124+ case requested :
125+ r .gh .Logger .Debugf ("Review of user %s already requested on PR %d" , r .user , pr .GetNumber ())
126+ case r .user == pr .GetUser ().GetLogin ():
127+ r .gh .Logger .Debugf ("Review of user %s is not requested on PR %d because he's the author" , r .user , pr .GetNumber ())
128+ default :
129+ r .gh .Logger .Debugf ("Requesting review from user %s on PR %d" , r .user , pr .GetNumber ())
130+ if _ , _ , err := r .gh .Client .PullRequests .RequestReviewers (
131+ r .gh .Ctx ,
132+ r .gh .Owner ,
133+ r .gh .Repo ,
134+ pr .GetNumber (),
135+ github.ReviewersRequest {
136+ Reviewers : []string {r .user },
137+ },
138+ ); err != nil {
139+ r .gh .Logger .Errorf ("Unable to request review from user %s on PR %d: %v" , r .user , pr .GetNumber (), err )
140+ }
141+ }
142+ case RequestRemove :
143+ switch {
144+ case ! requested :
145+ r .gh .Logger .Debugf ("Review of user %s already not requested on PR %d" , r .user , pr .GetNumber ())
146+ default :
147+ r .gh .Logger .Debugf ("Removing review request from user %s on PR %d" , r .user , pr .GetNumber ())
148+ if _ , err := r .gh .Client .PullRequests .RemoveReviewers (
149+ r .gh .Ctx ,
150+ r .gh .Owner ,
151+ r .gh .Repo ,
152+ pr .GetNumber (),
153+ github.ReviewersRequest {
154+ Reviewers : []string {r .user },
155+ },
156+ ); err != nil {
157+ r .gh .Logger .Errorf ("Unable to remove review request from user %s on PR %d: %v" , r .user , pr .GetNumber (), err )
158+ }
121159 }
122160 }
123161 }
@@ -138,8 +176,12 @@ func (r *ReviewByUserRequirement) WithDesiredState(s utils.ReviewState) *ReviewB
138176}
139177
140178// ReviewByUser asserts that the PR has been reviewed by the given user.
141- func ReviewByUser (gh * client.GitHub , user string ) * ReviewByUserRequirement {
142- return & ReviewByUserRequirement {gh : gh , user : user }
179+ func ReviewByUser (gh * client.GitHub , user string , action RequestAction ) * ReviewByUserRequirement {
180+ return & ReviewByUserRequirement {
181+ gh : gh ,
182+ user : user ,
183+ action : action ,
184+ }
143185}
144186
145187// ReviewByTeamMembersRequirement asserts that count members of the given team
@@ -150,6 +192,7 @@ type ReviewByTeamMembersRequirement struct {
150192 team string
151193 count uint
152194 desiredState string
195+ action RequestAction
153196}
154197
155198var _ Requirement = & ReviewByTeamMembersRequirement {}
@@ -177,7 +220,8 @@ func (r *ReviewByTeamMembersRequirement) IsSatisfied(pr *github.PullRequest, det
177220
178221 // If not a dry run, request a team review if no member has reviewed yet,
179222 // and the team review has not been requested.
180- if ! r .gh .DryRun {
223+ if ! r .gh .DryRun && r .action != RequestIgnore {
224+ // Check if the team or any of its members are already requested for review.
181225 var teamRequested bool
182226 var usersRequested []string
183227
@@ -210,24 +254,45 @@ func (r *ReviewByTeamMembersRequirement) IsSatisfied(pr *github.PullRequest, det
210254 }
211255 }
212256
213- switch {
214- case teamRequested :
215- r .gh .Logger .Debugf ("Review of team %s already requested on PR %d" , r .team , pr .GetNumber ())
216- case len (usersRequested ) > 0 :
217- r .gh .Logger .Debugf ("Members %v of team %s already requested on (or reviewed) PR %d" ,
218- usersRequested , r .team , pr .GetNumber ())
219- default :
220- r .gh .Logger .Debugf ("Requesting review from team %s on PR %d" , r .team , pr .GetNumber ())
221- if _ , _ , err := r .gh .Client .PullRequests .RequestReviewers (
222- r .gh .Ctx ,
223- r .gh .Owner ,
224- r .gh .Repo ,
225- pr .GetNumber (),
226- github.ReviewersRequest {
227- TeamReviewers : []string {r .team },
228- },
229- ); err != nil {
230- r .gh .Logger .Errorf ("Unable to request review from team %s on PR %d: %v" , r .team , pr .GetNumber (), err )
257+ switch r .action {
258+ case RequestApply :
259+ switch {
260+ case teamRequested :
261+ r .gh .Logger .Debugf ("Review of team %s already requested on PR %d" , r .team , pr .GetNumber ())
262+ case len (usersRequested ) > 0 :
263+ r .gh .Logger .Debugf ("Members %v of team %s already requested on (or reviewed) PR %d" ,
264+ usersRequested , r .team , pr .GetNumber ())
265+ default :
266+ r .gh .Logger .Debugf ("Requesting review from team %s on PR %d" , r .team , pr .GetNumber ())
267+ if _ , _ , err := r .gh .Client .PullRequests .RequestReviewers (
268+ r .gh .Ctx ,
269+ r .gh .Owner ,
270+ r .gh .Repo ,
271+ pr .GetNumber (),
272+ github.ReviewersRequest {
273+ TeamReviewers : []string {r .team },
274+ },
275+ ); err != nil {
276+ r .gh .Logger .Errorf ("Unable to request review from team %s on PR %d: %v" , r .team , pr .GetNumber (), err )
277+ }
278+ }
279+ case RequestRemove :
280+ switch {
281+ case ! teamRequested :
282+ r .gh .Logger .Debugf ("Review of team %s already not requested on PR %d" , r .team , pr .GetNumber ())
283+ default :
284+ r .gh .Logger .Debugf ("Removing review request from team %s on PR %d" , r .team , pr .GetNumber ())
285+ if _ , err := r .gh .Client .PullRequests .RemoveReviewers (
286+ r .gh .Ctx ,
287+ r .gh .Owner ,
288+ r .gh .Repo ,
289+ pr .GetNumber (),
290+ github.ReviewersRequest {
291+ TeamReviewers : []string {r .team },
292+ },
293+ ); err != nil {
294+ r .gh .Logger .Errorf ("Unable to remove review request from team %s on PR %d: %v" , r .team , pr .GetNumber (), err )
295+ }
231296 }
232297 }
233298 }
@@ -283,11 +348,12 @@ func (r *ReviewByTeamMembersRequirement) WithDesiredState(s utils.ReviewState) *
283348//
284349// The number of required reviews, or the state of the reviews (e.g., to filter
285350// only for approval reviews) can be modified using WithCount and WithDesiredState.
286- func ReviewByTeamMembers (gh * client.GitHub , team string ) * ReviewByTeamMembersRequirement {
351+ func ReviewByTeamMembers (gh * client.GitHub , team string , action RequestAction ) * ReviewByTeamMembersRequirement {
287352 return & ReviewByTeamMembersRequirement {
288- gh : gh ,
289- team : team ,
290- count : 1 ,
353+ gh : gh ,
354+ team : team ,
355+ count : 1 ,
356+ action : action ,
291357 }
292358}
293359
0 commit comments