@@ -20,11 +20,29 @@ import (
2020 "code.gitea.io/gitea/modules/log"
2121 "code.gitea.io/gitea/modules/optional"
2222 "code.gitea.io/gitea/modules/setting"
23+ "code.gitea.io/gitea/modules/util"
2324 notify_service "code.gitea.io/gitea/services/notify"
2425)
2526
2627var notEnoughLines = regexp .MustCompile (`fatal: file .* has only \d+ lines?` )
2728
29+ // ErrDismissRequestOnClosedPR represents an error when an user tries to dismiss a review associated to a closed or merged PR.
30+ type ErrDismissRequestOnClosedPR struct {}
31+
32+ // IsErrDismissRequestOnClosedPR checks if an error is an ErrDismissRequestOnClosedPR.
33+ func IsErrDismissRequestOnClosedPR (err error ) bool {
34+ _ , ok := err .(ErrDismissRequestOnClosedPR )
35+ return ok
36+ }
37+
38+ func (err ErrDismissRequestOnClosedPR ) Error () string {
39+ return "can't dismiss a review associated to a closed or merged PR"
40+ }
41+
42+ func (err ErrDismissRequestOnClosedPR ) Unwrap () error {
43+ return util .ErrPermissionDenied
44+ }
45+
2846// checkInvalidation checks if the line of code comment got changed by another commit.
2947// If the line got changed the comment is going to be invalidated.
3048func checkInvalidation (ctx context.Context , c * issues_model.Comment , doer * user_model.User , repo * git.Repository , branch string ) error {
@@ -382,6 +400,21 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string,
382400 return nil , fmt .Errorf ("reviews's repository is not the same as the one we expect" )
383401 }
384402
403+ issue := review .Issue
404+
405+ if issue .IsClosed {
406+ return nil , ErrDismissRequestOnClosedPR {}
407+ }
408+
409+ if issue .IsPull {
410+ if err := issue .LoadPullRequest (ctx ); err != nil {
411+ return nil , err
412+ }
413+ if issue .PullRequest .HasMerged {
414+ return nil , ErrDismissRequestOnClosedPR {}
415+ }
416+ }
417+
385418 if err := issues_model .DismissReview (ctx , review , isDismiss ); err != nil {
386419 return nil , err
387420 }
0 commit comments