summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
author谈笑风生间 <makonike@anyview.fun>2023-05-25 10:06:27 +0800
committerGitHub <noreply@github.com>2023-05-24 22:06:27 -0400
commit309354c70ee994a1e8f261d7bc24e7473e601d02 (patch)
tree89a96f611eef8b37e17dcead9767ff8d9ba976ef /models
parent93c6a9a652460f89fc719024c435cacbb235d302 (diff)
downloadgitea-309354c70ee994a1e8f261d7bc24e7473e601d02.tar.gz
gitea-309354c70ee994a1e8f261d7bc24e7473e601d02.zip
New webhook trigger for receiving Pull Request review requests (#24481)
close https://github.com/go-gitea/gitea/issues/16321 Provided a webhook trigger for requesting someone to review the Pull Request. Some modifications have been made to the returned `PullRequestPayload` based on the GitHub webhook settings, including: - add a description of the current reviewer object as `RequestedReviewer` . - setting the action to either **review_requested** or **review_request_removed** based on the operation. - adding the `RequestedReviewers` field to the issues_model.PullRequest. This field will be loaded into the PullRequest through `LoadRequestedReviewers()` when `ToAPIPullRequest` is called. After the Pull Request is merged, I will supplement the relevant documentation.
Diffstat (limited to 'models')
-rw-r--r--models/issues/pull.go30
-rw-r--r--models/issues/pull_test.go29
-rw-r--r--models/issues/review.go25
-rw-r--r--models/issues/review_test.go17
-rw-r--r--models/user/user.go29
-rw-r--r--models/webhook/webhook.go7
-rw-r--r--models/webhook/webhook_test.go2
7 files changed, 130 insertions, 9 deletions
diff --git a/models/issues/pull.go b/models/issues/pull.go
index 218a265741..3f37d8d243 100644
--- a/models/issues/pull.go
+++ b/models/issues/pull.go
@@ -175,9 +175,10 @@ type PullRequest struct {
ChangedProtectedFiles []string `xorm:"TEXT JSON"`
- IssueID int64 `xorm:"INDEX"`
- Issue *Issue `xorm:"-"`
- Index int64
+ IssueID int64 `xorm:"INDEX"`
+ Issue *Issue `xorm:"-"`
+ Index int64
+ RequestedReviewers []*user_model.User `xorm:"-"`
HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *repo_model.Repository `xorm:"-"`
@@ -302,6 +303,29 @@ func (pr *PullRequest) LoadHeadRepo(ctx context.Context) (err error) {
return nil
}
+// LoadRequestedReviewers loads the requested reviewers.
+func (pr *PullRequest) LoadRequestedReviewers(ctx context.Context) error {
+ if len(pr.RequestedReviewers) > 0 {
+ return nil
+ }
+
+ reviews, err := GetReviewsByIssueID(pr.Issue.ID)
+ if err != nil {
+ return err
+ }
+
+ if len(reviews) > 0 {
+ err = LoadReviewers(ctx, reviews)
+ if err != nil {
+ return err
+ }
+ for _, review := range reviews {
+ pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer)
+ }
+ }
+ return nil
+}
+
// LoadBaseRepo loads the target repository. ErrRepoNotExist may be returned.
func (pr *PullRequest) LoadBaseRepo(ctx context.Context) (err error) {
if pr.BaseRepo != nil {
diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go
index 0b06095213..7a183ac312 100644
--- a/models/issues/pull_test.go
+++ b/models/issues/pull_test.go
@@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
)
@@ -74,6 +75,34 @@ func TestPullRequestsNewest(t *testing.T) {
}
}
+func TestLoadRequestedReviewers(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+
+ pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
+ assert.NoError(t, pull.LoadIssue(db.DefaultContext))
+ issue := pull.Issue
+ assert.NoError(t, issue.LoadRepo(db.DefaultContext))
+ assert.Len(t, pull.RequestedReviewers, 0)
+
+ user1, err := user_model.GetUserByID(db.DefaultContext, 1)
+ assert.NoError(t, err)
+
+ comment, err := issues_model.AddReviewRequest(issue, user1, &user_model.User{})
+ assert.NoError(t, err)
+ assert.NotNil(t, comment)
+
+ assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
+ assert.Len(t, pull.RequestedReviewers, 1)
+
+ comment, err = issues_model.RemoveReviewRequest(issue, user1, &user_model.User{})
+ assert.NoError(t, err)
+ assert.NotNil(t, comment)
+
+ pull.RequestedReviewers = nil
+ assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
+ assert.Empty(t, pull.RequestedReviewers)
+}
+
func TestPullRequestsOldest(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
prs, count, err := issues_model.PullRequests(1, &issues_model.PullRequestsOptions{
diff --git a/models/issues/review.go b/models/issues/review.go
index ed30bce149..06cf132a48 100644
--- a/models/issues/review.go
+++ b/models/issues/review.go
@@ -162,6 +162,27 @@ func (r *Review) LoadReviewer(ctx context.Context) (err error) {
return err
}
+// LoadReviewers loads reviewers
+func LoadReviewers(ctx context.Context, reviews []*Review) (err error) {
+ reviewerIds := make([]int64, len(reviews))
+ for i := 0; i < len(reviews); i++ {
+ reviewerIds[i] = reviews[i].ReviewerID
+ }
+ reviewers, err := user_model.GetPossibleUserByIDs(ctx, reviewerIds)
+ if err != nil {
+ return err
+ }
+
+ userMap := make(map[int64]*user_model.User, len(reviewers))
+ for _, reviewer := range reviewers {
+ userMap[reviewer.ID] = reviewer
+ }
+ for _, review := range reviews {
+ review.Reviewer = userMap[review.ReviewerID]
+ }
+ return nil
+}
+
// LoadReviewerTeam loads reviewer team
func (r *Review) LoadReviewerTeam(ctx context.Context) (err error) {
if r.ReviewerTeamID == 0 || r.ReviewerTeam != nil {
@@ -520,8 +541,8 @@ func GetReviews(ctx context.Context, opts *GetReviewOptions) ([]*Review, error)
return reviews, sess.Find(&reviews)
}
-// GetReviewersByIssueID gets the latest review of each reviewer for a pull request
-func GetReviewersByIssueID(issueID int64) ([]*Review, error) {
+// GetReviewsByIssueID gets the latest review of each reviewer for a pull request
+func GetReviewsByIssueID(issueID int64) ([]*Review, error) {
reviews := make([]*Review, 0, 10)
sess := db.GetEngine(db.DefaultContext)
diff --git a/models/issues/review_test.go b/models/issues/review_test.go
index 3221496577..0cb621812c 100644
--- a/models/issues/review_test.go
+++ b/models/issues/review_test.go
@@ -132,11 +132,22 @@ func TestGetReviewersByIssueID(t *testing.T) {
UpdatedUnix: 946684814,
})
- allReviews, err := issues_model.GetReviewersByIssueID(issue.ID)
- for _, reviewer := range allReviews {
- assert.NoError(t, reviewer.LoadReviewer(db.DefaultContext))
+ allReviews, err := issues_model.GetReviewsByIssueID(issue.ID)
+ assert.NoError(t, err)
+ for _, review := range allReviews {
+ assert.NoError(t, review.LoadReviewer(db.DefaultContext))
}
+ if assert.Len(t, allReviews, 3) {
+ for i, review := range allReviews {
+ assert.Equal(t, expectedReviews[i].Reviewer, review.Reviewer)
+ assert.Equal(t, expectedReviews[i].Type, review.Type)
+ assert.Equal(t, expectedReviews[i].UpdatedUnix, review.UpdatedUnix)
+ }
+ }
+
+ allReviews, err = issues_model.GetReviewsByIssueID(issue.ID)
assert.NoError(t, err)
+ assert.NoError(t, issues_model.LoadReviewers(db.DefaultContext, allReviews))
if assert.Len(t, allReviews, 3) {
for i, review := range allReviews {
assert.Equal(t, expectedReviews[i].Reviewer, review.Reviewer)
diff --git a/models/user/user.go b/models/user/user.go
index 57b2117bb9..07d8177b6a 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/auth/openid"
"code.gitea.io/gitea/modules/auth/password/hash"
"code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -910,6 +911,15 @@ func GetUserByID(ctx context.Context, id int64) (*User, error) {
return u, nil
}
+// GetUserByIDs returns the user objects by given IDs if exists.
+func GetUserByIDs(ctx context.Context, ids []int64) ([]*User, error) {
+ users := make([]*User, 0, len(ids))
+ err := db.GetEngine(ctx).In("id", ids).
+ Table("user").
+ Find(&users)
+ return users, err
+}
+
// GetPossibleUserByID returns the user if id > 0 or return system usrs if id < 0
func GetPossibleUserByID(ctx context.Context, id int64) (*User, error) {
switch id {
@@ -924,6 +934,25 @@ func GetPossibleUserByID(ctx context.Context, id int64) (*User, error) {
}
}
+// GetPossibleUserByIDs returns the users if id > 0 or return system users if id < 0
+func GetPossibleUserByIDs(ctx context.Context, ids []int64) ([]*User, error) {
+ uniqueIDs := container.SetOf(ids...)
+ users := make([]*User, 0, len(ids))
+ _ = uniqueIDs.Remove(0)
+ if uniqueIDs.Remove(-1) {
+ users = append(users, NewGhostUser())
+ }
+ if uniqueIDs.Remove(ActionsUserID) {
+ users = append(users, NewActionsUser())
+ }
+ res, err := GetUserByIDs(ctx, uniqueIDs.Values())
+ if err != nil {
+ return nil, err
+ }
+ users = append(users, res...)
+ return users, nil
+}
+
// GetUserByNameCtx returns user by given name.
func GetUserByName(ctx context.Context, name string) (*User, error) {
if len(name) == 0 {
diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go
index e3f6b593d9..fc2bbed083 100644
--- a/models/webhook/webhook.go
+++ b/models/webhook/webhook.go
@@ -298,6 +298,12 @@ func (w *Webhook) HasPackageEvent() bool {
(w.ChooseEvents && w.HookEvents.Package)
}
+// HasPullRequestReviewRequestEvent returns true if hook enabled pull request review request event.
+func (w *Webhook) HasPullRequestReviewRequestEvent() bool {
+ return w.SendEverything ||
+ (w.ChooseEvents && w.HookEvents.PullRequestReviewRequest)
+}
+
// EventCheckers returns event checkers
func (w *Webhook) EventCheckers() []struct {
Has func() bool
@@ -329,6 +335,7 @@ func (w *Webhook) EventCheckers() []struct {
{w.HasRepositoryEvent, webhook_module.HookEventRepository},
{w.HasReleaseEvent, webhook_module.HookEventRelease},
{w.HasPackageEvent, webhook_module.HookEventPackage},
+ {w.HasPullRequestReviewRequestEvent, webhook_module.HookEventPullRequestReviewRequest},
}
}
diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go
index e05dcaba01..de6568c321 100644
--- a/models/webhook/webhook_test.go
+++ b/models/webhook/webhook_test.go
@@ -73,7 +73,7 @@ func TestWebhook_EventsArray(t *testing.T) {
"pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone",
"pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected",
"pull_request_review_comment", "pull_request_sync", "wiki", "repository", "release",
- "package",
+ "package", "pull_request_review_request",
},
(&Webhook{
HookEvent: &webhook_module.HookEvent{SendEverything: true},