From d58be0bcff47db0ed99d277734e1f18fa1a95e67 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 31 Oct 2026 17:31:39 +0100 Subject: [PATCH] fix(pull): keep review body in sync when its comment is edited (#40058) A review's text is stored on both the review and its timeline comment, but editing it in the web UI or through the issue comment API only updated the comment. The reviews API kept returning the old body afterwards. Extracted out of https://github.com/go-gitea/gitea/pull/39865. *Written by Claude.* Co-authored-by: Giteabot --- models/issues/comment.go | 5 +++++ tests/integration/api_pull_review_test.go | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/models/issues/comment.go b/models/issues/comment.go index 02de587fb25..d39caf0aa95 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -1208,6 +1208,11 @@ func UpdateComment(ctx context.Context, c *Comment, contentVersion int, doer *us if affected == 0 { return ErrCommentAlreadyChanged } + if c.Type == CommentTypeReview { + if _, err := db.GetEngine(ctx).ID(c.ReviewID).Cols("content").NoAutoTime().Update(&Review{Content: c.Content}); err != nil { // updated_unix picks a reviewer's latest review + return err + } + } if err := c.LoadIssue(ctx); err != nil { return err } diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index 6ab2fb4546e..94d13f7d079 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -153,6 +153,12 @@ func testAPIPullReviewGeneral(t *testing.T) { assert.EqualValues(t, "APPROVED", review.State) assert.Equal(t, 3, review.CodeCommentsCount) + 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) + req = NewRequest(t, http.MethodGet, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID)).AddTokenAuth(token) + assert.Equal(t, "just one nit", DecodeJSON(t, MakeRequest(t, req, http.StatusOK), &api.PullReview{}).Body) + // test dismiss review req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.DismissPullReviewOptions{ Message: "test",