mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-09 17:37:20 -06:00
fix(pull): don't add a timeline entry for pending API reviews (#40260)
Pending reviews created through the API went through `SubmitReview`, which added a timeline entry and sent notifications before the review was submitted, so submitting it later showed the review twice. - Pending reviews skip the timeline entry and notifications until submitted, like on GitHub - `CreatePullReview` rejects comments without a `path` or a positive line with 422, like GitHub - Already duplicated reviews stay as they are Fixes https://github.com/go-gitea/gitea/issues/40259 Assisted-by: Claude Code:claude-opus-5-5 --------- Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
committed by
GitHub
parent
462ab3801a
commit
884884308d
@@ -545,6 +545,10 @@ func SubmitReview(ctx context.Context, doer *user_model.User, issue *Issue, revi
|
||||
}
|
||||
}
|
||||
|
||||
if reviewType == ReviewTypePending {
|
||||
return review, nil, committer.Commit()
|
||||
}
|
||||
|
||||
comm, err := CreateComment(ctx, &CreateCommentOptions{
|
||||
Type: CommentTypeReview,
|
||||
Doer: doer,
|
||||
|
||||
@@ -86,6 +86,7 @@ type CreatePullReviewOptions struct {
|
||||
// CreatePullReviewComment represent a review comment for creation api
|
||||
type CreatePullReviewComment struct {
|
||||
// the tree path
|
||||
// required: true
|
||||
Path string `json:"path"`
|
||||
Body string `json:"body"`
|
||||
// if comment to old file line or 0
|
||||
|
||||
@@ -487,6 +487,13 @@ func CreatePullReview(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/error"
|
||||
|
||||
opts := web.GetForm[*api.CreatePullReviewOptions](ctx)
|
||||
for _, comment := range opts.Comments {
|
||||
if comment.Path == "" || (comment.NewLineNum <= 0 && comment.OldLineNum <= 0) {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, "review comments require a path and a positive new_position or old_position")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index"))
|
||||
if err != nil {
|
||||
ctx.APIErrorAuto(err)
|
||||
|
||||
@@ -332,6 +332,9 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if reviewType == issues_model.ReviewTypePending {
|
||||
return review, nil, nil
|
||||
}
|
||||
|
||||
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comm.Content)
|
||||
if err != nil {
|
||||
|
||||
3
templates/swagger/v1-openapi3.generated.json
generated
3
templates/swagger/v1-openapi3.generated.json
generated
@@ -4590,6 +4590,9 @@
|
||||
"x-go-name": "Path"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"type": "object",
|
||||
"x-go-package": "gitea.dev/modules/structs"
|
||||
},
|
||||
|
||||
3
templates/swagger/v1-swagger.generated.json
generated
3
templates/swagger/v1-swagger.generated.json
generated
@@ -27027,6 +27027,9 @@
|
||||
"CreatePullReviewComment": {
|
||||
"description": "CreatePullReviewComment represent a review comment for creation api",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"body": {
|
||||
"type": "string",
|
||||
|
||||
@@ -113,6 +113,20 @@ func testAPIPullReviewGeneral(t *testing.T) {
|
||||
assert.EqualValues(t, comment.UpdatedUnix, reviewComments[0].Updated.Unix())
|
||||
assert.Equal(t, comment.HTMLURL(t.Context()), reviewComments[0].HTMLURL)
|
||||
|
||||
for _, invalidComment := range []api.CreatePullReviewComment{
|
||||
{Body: "missing path", NewLineNum: 1},
|
||||
{Path: "README.md", Body: "missing line"},
|
||||
} {
|
||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{
|
||||
Comments: []api.CreatePullReviewComment{
|
||||
{Path: "README.md", Body: "comment before invalid anchor", NewLineNum: 1},
|
||||
invalidComment,
|
||||
},
|
||||
}).AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, &issues_model.Comment{IssueID: pullIssue.ID, Content: "comment before invalid anchor"})
|
||||
|
||||
// test CreatePullReview
|
||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{
|
||||
Body: "body1",
|
||||
@@ -153,6 +167,7 @@ func testAPIPullReviewGeneral(t *testing.T) {
|
||||
assert.EqualValues(t, "APPROVED", review.State)
|
||||
assert.Equal(t, 3, review.CodeCommentsCount)
|
||||
|
||||
unittest.AssertCount(t, &issues_model.Comment{ReviewID: review.ID, Type: issues_model.CommentTypeReview}, 1)
|
||||
reviewComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ReviewID: review.ID, Type: issues_model.CommentTypeReview})
|
||||
req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d", repo.OwnerName, repo.Name, reviewComment.ID), &api.EditIssueCommentOption{Body: "just one nit"}).AddTokenAuth(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue))
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
Reference in New Issue
Block a user