Skip to content

Commit 666038a

Browse files
authored
Fix bug when pushing to a pull request which enabled dismiss approval automatically (#25882) (#26158)
Fix #25858 Backport #25882 The option `dissmiss stale approvals` was listed on protected branch but never implemented. This PR fixes that. <img width="1006" alt="图片" src="https://github.com/go-gitea/gitea/assets/81045/60bfa968-4db7-4c24-b8be-2e5978f91bb9"> <img width="1021" alt="图片" src="https://github.com/go-gitea/gitea/assets/81045/8dabc14d-2dfe-40c2-94ed-24fcbf6e0e8f">
1 parent 5461476 commit 666038a

File tree

7 files changed

+252
-163
lines changed

7 files changed

+252
-163
lines changed

models/issues/issue.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ func GetIssueWithAttrsByID(id int64) (*Issue, error) {
552552

553553
// GetIssuesByIDs return issues with the given IDs.
554554
func GetIssuesByIDs(ctx context.Context, issueIDs []int64) (IssueList, error) {
555-
issues := make([]*Issue, 0, 10)
555+
issues := make([]*Issue, 0, len(issueIDs))
556556
return issues, db.GetEngine(ctx).In("id", issueIDs).Find(&issues)
557557
}
558558

models/issues/pull.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,13 @@ func (pr *PullRequest) LoadRequestedReviewers(ctx context.Context) error {
314314
return err
315315
}
316316

317-
if len(reviews) > 0 {
318-
err = LoadReviewers(ctx, reviews)
319-
if err != nil {
320-
return err
321-
}
322-
for _, review := range reviews {
323-
pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer)
324-
}
317+
if err = reviews.LoadReviewers(ctx); err != nil {
318+
return err
325319
}
320+
for _, review := range reviews {
321+
pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer)
322+
}
323+
326324
return nil
327325
}
328326

models/issues/review.go

Lines changed: 2 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -162,27 +162,6 @@ func (r *Review) LoadReviewer(ctx context.Context) (err error) {
162162
return err
163163
}
164164

165-
// LoadReviewers loads reviewers
166-
func LoadReviewers(ctx context.Context, reviews []*Review) (err error) {
167-
reviewerIds := make([]int64, len(reviews))
168-
for i := 0; i < len(reviews); i++ {
169-
reviewerIds[i] = reviews[i].ReviewerID
170-
}
171-
reviewers, err := user_model.GetPossibleUserByIDs(ctx, reviewerIds)
172-
if err != nil {
173-
return err
174-
}
175-
176-
userMap := make(map[int64]*user_model.User, len(reviewers))
177-
for _, reviewer := range reviewers {
178-
userMap[reviewer.ID] = reviewer
179-
}
180-
for _, review := range reviews {
181-
review.Reviewer = userMap[review.ReviewerID]
182-
}
183-
return nil
184-
}
185-
186165
// LoadReviewerTeam loads reviewer team
187166
func (r *Review) LoadReviewerTeam(ctx context.Context) (err error) {
188167
if r.ReviewerTeamID == 0 || r.ReviewerTeam != nil {
@@ -236,50 +215,6 @@ func GetReviewByID(ctx context.Context, id int64) (*Review, error) {
236215
}
237216
}
238217

239-
// FindReviewOptions represent possible filters to find reviews
240-
type FindReviewOptions struct {
241-
db.ListOptions
242-
Type ReviewType
243-
IssueID int64
244-
ReviewerID int64
245-
OfficialOnly bool
246-
}
247-
248-
func (opts *FindReviewOptions) toCond() builder.Cond {
249-
cond := builder.NewCond()
250-
if opts.IssueID > 0 {
251-
cond = cond.And(builder.Eq{"issue_id": opts.IssueID})
252-
}
253-
if opts.ReviewerID > 0 {
254-
cond = cond.And(builder.Eq{"reviewer_id": opts.ReviewerID})
255-
}
256-
if opts.Type != ReviewTypeUnknown {
257-
cond = cond.And(builder.Eq{"type": opts.Type})
258-
}
259-
if opts.OfficialOnly {
260-
cond = cond.And(builder.Eq{"official": true})
261-
}
262-
return cond
263-
}
264-
265-
// FindReviews returns reviews passing FindReviewOptions
266-
func FindReviews(ctx context.Context, opts FindReviewOptions) ([]*Review, error) {
267-
reviews := make([]*Review, 0, 10)
268-
sess := db.GetEngine(ctx).Where(opts.toCond())
269-
if opts.Page > 0 {
270-
sess = db.SetSessionPagination(sess, &opts)
271-
}
272-
return reviews, sess.
273-
Asc("created_unix").
274-
Asc("id").
275-
Find(&reviews)
276-
}
277-
278-
// CountReviews returns count of reviews passing FindReviewOptions
279-
func CountReviews(opts FindReviewOptions) (int64, error) {
280-
return db.GetEngine(db.DefaultContext).Where(opts.toCond()).Count(&Review{})
281-
}
282-
283218
// CreateReviewOptions represent the options to create a review. Type, Issue and Reviewer are required.
284219
type CreateReviewOptions struct {
285220
Content string
@@ -512,76 +447,6 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co
512447
return review, comm, committer.Commit()
513448
}
514449

515-
// GetReviewOptions represent filter options for GetReviews
516-
type GetReviewOptions struct {
517-
IssueID int64
518-
ReviewerID int64
519-
Dismissed util.OptionalBool
520-
}
521-
522-
// GetReviews return reviews based on GetReviewOptions
523-
func GetReviews(ctx context.Context, opts *GetReviewOptions) ([]*Review, error) {
524-
if opts == nil {
525-
return nil, fmt.Errorf("opts are nil")
526-
}
527-
528-
sess := db.GetEngine(ctx)
529-
530-
if opts.IssueID != 0 {
531-
sess = sess.Where("issue_id=?", opts.IssueID)
532-
}
533-
if opts.ReviewerID != 0 {
534-
sess = sess.Where("reviewer_id=?", opts.ReviewerID)
535-
}
536-
if !opts.Dismissed.IsNone() {
537-
sess = sess.Where("dismissed=?", opts.Dismissed.IsTrue())
538-
}
539-
540-
reviews := make([]*Review, 0, 4)
541-
return reviews, sess.Find(&reviews)
542-
}
543-
544-
// GetReviewsByIssueID gets the latest review of each reviewer for a pull request
545-
func GetReviewsByIssueID(issueID int64) ([]*Review, error) {
546-
reviews := make([]*Review, 0, 10)
547-
548-
sess := db.GetEngine(db.DefaultContext)
549-
550-
// Get latest review of each reviewer, sorted in order they were made
551-
if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND dismissed = ? AND original_author_id = 0 GROUP BY issue_id, reviewer_id) ORDER BY review.updated_unix ASC",
552-
issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, false).
553-
Find(&reviews); err != nil {
554-
return nil, err
555-
}
556-
557-
teamReviewRequests := make([]*Review, 0, 5)
558-
if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id <> 0 AND original_author_id = 0 GROUP BY issue_id, reviewer_team_id) ORDER BY review.updated_unix ASC",
559-
issueID).
560-
Find(&teamReviewRequests); err != nil {
561-
return nil, err
562-
}
563-
564-
if len(teamReviewRequests) > 0 {
565-
reviews = append(reviews, teamReviewRequests...)
566-
}
567-
568-
return reviews, nil
569-
}
570-
571-
// GetReviewersFromOriginalAuthorsByIssueID gets the latest review of each original authors for a pull request
572-
func GetReviewersFromOriginalAuthorsByIssueID(issueID int64) ([]*Review, error) {
573-
reviews := make([]*Review, 0, 10)
574-
575-
// Get latest review of each reviewer, sorted in order they were made
576-
if err := db.GetEngine(db.DefaultContext).SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND original_author_id <> 0 GROUP BY issue_id, original_author_id) ORDER BY review.updated_unix ASC",
577-
issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
578-
Find(&reviews); err != nil {
579-
return nil, err
580-
}
581-
582-
return reviews, nil
583-
}
584-
585450
// GetReviewByIssueIDAndUserID get the latest review of reviewer for a pull request
586451
func GetReviewByIssueIDAndUserID(ctx context.Context, issueID, userID int64) (*Review, error) {
587452
review := new(Review)
@@ -633,7 +498,7 @@ func MarkReviewsAsNotStale(issueID int64, commitID string) (err error) {
633498
}
634499

635500
// DismissReview change the dismiss status of a review
636-
func DismissReview(review *Review, isDismiss bool) (err error) {
501+
func DismissReview(ctx context.Context, review *Review, isDismiss bool) (err error) {
637502
if review.Dismissed == isDismiss || (review.Type != ReviewTypeApprove && review.Type != ReviewTypeReject) {
638503
return nil
639504
}
@@ -644,7 +509,7 @@ func DismissReview(review *Review, isDismiss bool) (err error) {
644509
return ErrReviewNotExist{}
645510
}
646511

647-
_, err = db.GetEngine(db.DefaultContext).ID(review.ID).Cols("dismissed").Update(review)
512+
_, err = db.GetEngine(ctx).ID(review.ID).Cols("dismissed").Update(review)
648513

649514
return err
650515
}

models/issues/review_list.go

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package issues
5+
6+
import (
7+
"context"
8+
9+
"code.gitea.io/gitea/models/db"
10+
user_model "code.gitea.io/gitea/models/user"
11+
"code.gitea.io/gitea/modules/container"
12+
"code.gitea.io/gitea/modules/util"
13+
14+
"xorm.io/builder"
15+
)
16+
17+
type ReviewList []*Review
18+
19+
// LoadReviewers loads reviewers
20+
func (reviews ReviewList) LoadReviewers(ctx context.Context) error {
21+
reviewerIds := make([]int64, len(reviews))
22+
for i := 0; i < len(reviews); i++ {
23+
reviewerIds[i] = reviews[i].ReviewerID
24+
}
25+
reviewers, err := user_model.GetPossibleUserByIDs(ctx, reviewerIds)
26+
if err != nil {
27+
return err
28+
}
29+
30+
userMap := make(map[int64]*user_model.User, len(reviewers))
31+
for _, reviewer := range reviewers {
32+
userMap[reviewer.ID] = reviewer
33+
}
34+
for _, review := range reviews {
35+
review.Reviewer = userMap[review.ReviewerID]
36+
}
37+
return nil
38+
}
39+
40+
func (reviews ReviewList) LoadIssues(ctx context.Context) error {
41+
issueIds := container.Set[int64]{}
42+
for i := 0; i < len(reviews); i++ {
43+
issueIds.Add(reviews[i].IssueID)
44+
}
45+
46+
issues, err := GetIssuesByIDs(ctx, issueIds.Values())
47+
if err != nil {
48+
return err
49+
}
50+
if _, err := issues.LoadRepositories(ctx); err != nil {
51+
return err
52+
}
53+
issueMap := make(map[int64]*Issue, len(issues))
54+
for _, issue := range issues {
55+
issueMap[issue.ID] = issue
56+
}
57+
58+
for _, review := range reviews {
59+
review.Issue = issueMap[review.IssueID]
60+
}
61+
return nil
62+
}
63+
64+
// FindReviewOptions represent possible filters to find reviews
65+
type FindReviewOptions struct {
66+
db.ListOptions
67+
Type ReviewType
68+
IssueID int64
69+
ReviewerID int64
70+
OfficialOnly bool
71+
Dismissed util.OptionalBool
72+
}
73+
74+
func (opts *FindReviewOptions) toCond() builder.Cond {
75+
cond := builder.NewCond()
76+
if opts.IssueID > 0 {
77+
cond = cond.And(builder.Eq{"issue_id": opts.IssueID})
78+
}
79+
if opts.ReviewerID > 0 {
80+
cond = cond.And(builder.Eq{"reviewer_id": opts.ReviewerID})
81+
}
82+
if opts.Type != ReviewTypeUnknown {
83+
cond = cond.And(builder.Eq{"type": opts.Type})
84+
}
85+
if opts.OfficialOnly {
86+
cond = cond.And(builder.Eq{"official": true})
87+
}
88+
if !opts.Dismissed.IsNone() {
89+
cond = cond.And(builder.Eq{"dismissed": opts.Dismissed.IsTrue()})
90+
}
91+
return cond
92+
}
93+
94+
// FindReviews returns reviews passing FindReviewOptions
95+
func FindReviews(ctx context.Context, opts FindReviewOptions) (ReviewList, error) {
96+
reviews := make([]*Review, 0, 10)
97+
sess := db.GetEngine(ctx).Where(opts.toCond())
98+
if opts.Page > 0 && !opts.IsListAll() {
99+
sess = db.SetSessionPagination(sess, &opts)
100+
}
101+
return reviews, sess.
102+
Asc("created_unix").
103+
Asc("id").
104+
Find(&reviews)
105+
}
106+
107+
// FindLatestReviews returns only latest reviews per user, passing FindReviewOptions
108+
func FindLatestReviews(ctx context.Context, opts FindReviewOptions) (ReviewList, error) {
109+
reviews := make([]*Review, 0, 10)
110+
cond := opts.toCond()
111+
sess := db.GetEngine(ctx).Where(cond)
112+
if opts.Page > 0 {
113+
sess = db.SetSessionPagination(sess, &opts)
114+
}
115+
116+
sess.In("id", builder.
117+
Select("max ( id ) ").
118+
From("review").
119+
Where(cond).
120+
GroupBy("reviewer_id"))
121+
122+
return reviews, sess.
123+
Asc("created_unix").
124+
Asc("id").
125+
Find(&reviews)
126+
}
127+
128+
// CountReviews returns count of reviews passing FindReviewOptions
129+
func CountReviews(opts FindReviewOptions) (int64, error) {
130+
return db.GetEngine(db.DefaultContext).Where(opts.toCond()).Count(&Review{})
131+
}
132+
133+
// GetReviewersFromOriginalAuthorsByIssueID gets the latest review of each original authors for a pull request
134+
func GetReviewersFromOriginalAuthorsByIssueID(issueID int64) (ReviewList, error) {
135+
reviews := make([]*Review, 0, 10)
136+
137+
// Get latest review of each reviewer, sorted in order they were made
138+
if err := db.GetEngine(db.DefaultContext).SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND original_author_id <> 0 GROUP BY issue_id, original_author_id) ORDER BY review.updated_unix ASC",
139+
issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
140+
Find(&reviews); err != nil {
141+
return nil, err
142+
}
143+
144+
return reviews, nil
145+
}
146+
147+
// GetReviewsByIssueID gets the latest review of each reviewer for a pull request
148+
func GetReviewsByIssueID(issueID int64) (ReviewList, error) {
149+
reviews := make([]*Review, 0, 10)
150+
151+
sess := db.GetEngine(db.DefaultContext)
152+
153+
// Get latest review of each reviewer, sorted in order they were made
154+
if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND dismissed = ? AND original_author_id = 0 GROUP BY issue_id, reviewer_id) ORDER BY review.updated_unix ASC",
155+
issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, false).
156+
Find(&reviews); err != nil {
157+
return nil, err
158+
}
159+
160+
teamReviewRequests := make([]*Review, 0, 5)
161+
if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id <> 0 AND original_author_id = 0 GROUP BY issue_id, reviewer_team_id) ORDER BY review.updated_unix ASC",
162+
issueID).
163+
Find(&teamReviewRequests); err != nil {
164+
return nil, err
165+
}
166+
167+
if len(teamReviewRequests) > 0 {
168+
reviews = append(reviews, teamReviewRequests...)
169+
}
170+
171+
return reviews, nil
172+
}

0 commit comments

Comments
 (0)