From 0918b4cacfe5dea8c2bb3094794426765bd3f319 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 11:29:26 +0200 Subject: [PATCH 01/22] Add API to get issue/pull comments and events (timeline) Adds an API to get both comments and events in one endpoint with all required data. Closes go-gitea/gitea#13250 --- integrations/api_comment_test.go | 19 +++ modules/convert/issue_comment.go | 129 ++++++++++++++++++ modules/structs/issue_comment.go | 85 ++++++++++++ routers/api/v1/api.go | 1 + routers/api/v1/repo/issue_comment.go | 100 ++++++++++++++ routers/api/v1/swagger/issue.go | 7 + templates/swagger/v1_json.tmpl | 188 +++++++++++++++++++++++++++ 7 files changed, 529 insertions(+) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index a5513af6e300c..70a5d2b5929e6 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -178,3 +178,22 @@ func TestAPIDeleteComment(t *testing.T) { db.AssertNotExistsBean(t, &models.Comment{ID: comment.ID}) } + +func TestAPIListIssueTimeline(t *testing.T) { + defer prepareTestEnv(t)() + + comment := db.AssertExistsAndLoadBean(t, &models.Comment{}).(*models.Comment) + issue := db.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + repo := db.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) + repoOwner := db.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + + session := loginUser(t, repoOwner.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/timeline", + repoOwner.Name, repo.Name, issue.Index) + resp := session.MakeRequest(t, req, http.StatusOK) + + var comments []*api.TimelineComment + DecodeJSON(t, resp, &comments) + expectedCount := db.GetCount(t, &models.Comment{IssueID: issue.ID}) + assert.EqualValues(t, expectedCount, len(comments)) +} diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index 1610b9f0d88c2..30e3d18231f73 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -22,3 +22,132 @@ func ToComment(c *models.Comment) *api.Comment { Updated: c.UpdatedUnix.AsTime(), } } + +// ToTimelineComment converts a models.Comment to the api.TimelineComment format +func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineComment { + err := c.LoadMilestone() + if err != nil { + return nil + } + + err = c.LoadAssigneeUserAndTeam() + if err != nil { + return nil + } + + err = c.LoadResolveDoer() + if err != nil { + return nil + } + + err = c.LoadDepIssueDetails() + if err != nil { + return nil + } + + err = c.LoadTime() + if err != nil { + return nil + } + + err = c.LoadLabel() + if err != nil { + return nil + } + + comment := &api.TimelineComment{ + ID: c.ID, + Type: int64(c.Type), + Poster: ToUser(c.Poster, nil), + HTMLURL: c.HTMLURL(), + IssueURL: c.IssueURL(), + PRURL: c.PRURL(), + Body: c.Content, + Created: c.CreatedUnix.AsTime(), + Updated: c.UpdatedUnix.AsTime(), + + OldProjectID: c.OldProjectID, + ProjectID: c.ProjectID, + + OldTitle: c.OldTitle, + NewTitle: c.NewTitle, + + OldRef: c.OldRef, + NewRef: c.NewRef, + + RefAction: int64(c.RefAction), + RefCommitSHA: c.CommitSHA, + + ReviewID: c.ReviewID, + + RemovedAssignee: c.RemovedAssignee, + } + + if c.OldMilestone != nil { + comment.OldMilestone = ToAPIMilestone(c.OldMilestone) + } + if c.Milestone != nil { + comment.Milestone = ToAPIMilestone(c.Milestone) + } + + if c.Time != nil { + comment.Time = ToTrackedTime(c.Time) + } + + if c.RefIssueID != 0 { + issue, err := models.GetIssueByID(c.RefIssueID) + if err != nil { + return nil + } + comment.RefIssue = ToAPIIssue(issue) + } + + if c.RefCommentID != 0 { + com, err := models.GetCommentByID(c.RefCommentID) + if err != nil { + return nil + } + err = com.LoadPoster() + if err != nil { + return nil + } + comment.RefComment = ToComment(com) + } + + if c.Label != nil { + var org *models.User + var repo *models.Repository + if c.Label.BelongsToOrg() { + var err error + org, err = models.GetUserByID(c.Label.OrgID) + if err != nil { + return nil + } + } + if c.Label.BelongsToRepo() { + var err error + repo, err = models.GetRepositoryByID(c.Label.RepoID) + if err != nil { + return nil + } + } + comment.Label = ToLabel(c.Label, repo, org) + } + + if c.Assignee != nil { + comment.Assignee = ToUser(c.Assignee, nil) + } + if c.AssigneeTeam != nil { + comment.AssigneeTeam = ToTeam(c.AssigneeTeam) + } + + if c.ResolveDoer != nil { + comment.ResolveDoer = ToUser(c.ResolveDoer, nil) + } + + if c.DependentIssue != nil { + comment.DependentIssue = ToAPIIssue(c.DependentIssue) + } + + return comment +} diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index 0c8ac20017fbc..e8de160d0fd91 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -35,3 +35,88 @@ type EditIssueCommentOption struct { // required: true Body string `json:"body" binding:"Required"` } + +// TimelineComment represents a timeline comment (comment of any type) on a commit or issue +type TimelineComment struct { + ID int64 `json:"id"` + + // Type specifies the type of an event. + // 0 Plain comment, can be associated with a commit (CommitID > 0) and a line (LineNum > 0) + // 1 Reopen issue/pull request + // 2 Close issue/pull request + // 3 References. + // 4 Reference from a commit (not part of a pull request) + // 5 Reference from a comment + // 6 Reference from a pull request + // 7 Labels changed (if Body is "1", label was added, if not it was removed) + // 8 Milestone changed + // 9 Assignees changed + // 10 Change Title + // 11 Delete Branch + // 12 Start a stopwatch for time tracking + // 13 Stop a stopwatch for time tracking + // 14 Add time manual for time tracking + // 15 Cancel a stopwatch for time tracking + // 16 Added a due date + // 17 Modified the due date + // 18 Removed a due date + // 19 Dependency added + // 20 Dependency removed + // 21 Comment a line of code + // 22 Reviews a pull request by giving general feedback + // 23 Lock an issue, giving only collaborators access + // 24 Unlocks a previously locked issue + // 25 Change pull request's target branch + // 26 Delete time manual for time tracking + // 27 add or remove Request from one + // 28 merge pull request + // 29 push to PR head branch (information about the push is included in Body) + // 30 Project changed + // 31 Project board changed + // 32 Dismiss Review + Type int64 `json:"type"` + + HTMLURL string `json:"html_url"` + PRURL string `json:"pull_request_url"` + IssueURL string `json:"issue_url"` + Poster *User `json:"user"` + Body string `json:"body"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + + OldProjectID int64 `json:"old_project_id"` + ProjectID int64 `json:"project_id"` + OldMilestone *Milestone `json:"old_milestone"` + Milestone *Milestone `json:"milestone"` + Time *TrackedTime `json:"time"` + OldTitle string `json:"old_title"` + NewTitle string `json:"new_title"` + OldRef string `json:"old_ref"` + NewRef string `json:"new_ref"` + + RefIssue *Issue `json:"ref_issue"` + RefComment *Comment `json:"ref_comment"` + // action that was used to reference issue/PR + // 0 means the cross-reference is simply a comment + // 1 means the cross-reference should close an issue if it is resolved + // 2 means the cross-reference should reopen an issue if it is resolved + // 3 means the cross-reference will no longer affect the source + RefAction int64 `json:"ref_action"` + // commit SHA where issue/PR was referenced + RefCommitSHA string `json:"ref_commit_sha"` + + ReviewID int64 `json:"review_id"` + + Label *Label `json:"label"` + + Assignee *User `json:"assignee"` + AssigneeTeam *Team `json:"assignee_team"` + // whether the assignees were removed or added + RemovedAssignee bool `json:"removed_assignee"` + + ResolveDoer *User `json:"resolve_doer"` + + DependentIssue *Issue `json:"dependent_issue"` +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index d915b76f78973..9567396ed5eb4 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -816,6 +816,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { m.Combo("/{id}", reqToken()).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated). Delete(repo.DeleteIssueCommentDeprecated) }) + m.Get("/timeline", repo.ListIssueCommentsAndTimeline) m.Group("/labels", func() { m.Combo("").Get(repo.ListIssueLabels). Post(reqToken(), bind(api.IssueLabelsOption{}), repo.AddIssueLabels). diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 13e7de46b1f12..547cb0cd719cb 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -102,6 +102,106 @@ func ListIssueComments(ctx *context.APIContext) { ctx.JSON(http.StatusOK, &apiComments) } +// ListIssueCommentsAndTimeline list all the comments and events of an issue +func ListIssueCommentsAndTimeline(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/timeline issue issueGetCommentsAndTimeline + // --- + // summary: List all comments and events on an issue + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // - name: since + // in: query + // description: if provided, only comments updated since the specified time are returned. + // type: string + // format: date-time + // - name: before + // in: query + // description: if provided, only comments updated before the provided time are returned. + // type: string + // format: date-time + // responses: + // "200": + // "$ref": "#/responses/TimelineList" + + before, since, err := utils.GetQueryBeforeSince(ctx) + if err != nil { + ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + return + } + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) + return + } + issue.Repo = ctx.Repo.Repository + + opts := &models.FindCommentsOptions{ + IssueID: issue.ID, + Since: since, + Before: before, + Type: models.CommentTypeUnknown, + } + + comments, err := models.FindComments(opts) + if err != nil { + ctx.Error(http.StatusInternalServerError, "FindComments", err) + return + } + + if err := models.CommentList(comments).LoadPosters(); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadPosters", err) + return + } + + var apiComments []*api.TimelineComment + for i, comment := range comments { + if isXRefCommentAccessible(ctx.User, comment, issue.RepoID) { + comment.Issue = issue + apiComments = append(apiComments, convert.ToTimelineComment(comments[i], ctx.User)) + } + } + + ctx.SetTotalCountHeader(int64(len(apiComments))) + ctx.JSON(http.StatusOK, &apiComments) +} + +func isXRefCommentAccessible(user *models.User, c *models.Comment, issueRepoID int64) bool { + // Remove comments that the user has no permissions to see + if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { + var err error + // Set RefRepo for description in template + c.RefRepo, err = models.GetRepositoryByID(c.RefRepoID) + if err != nil { + return false + } + perm, err := models.GetUserRepoPermission(c.RefRepo, user) + if err != nil { + return false + } + if !perm.CanReadIssuesOrPulls(c.RefIsPull) { + return false + } + } + return true +} + // ListRepoIssueComments returns all issue-comments for a repo func ListRepoIssueComments(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/issues/comments issue issueGetRepoComments diff --git a/routers/api/v1/swagger/issue.go b/routers/api/v1/swagger/issue.go index 0f2f572020805..09e7077b200c1 100644 --- a/routers/api/v1/swagger/issue.go +++ b/routers/api/v1/swagger/issue.go @@ -36,6 +36,13 @@ type swaggerResponseCommentList struct { Body []api.Comment `json:"body"` } +// TimelineList +// swagger:response TimelineList +type swaggerResponseTimelineList struct { + // in:body + Body []api.TimelineComment `json:"body"` +} + // Label // swagger:response Label type swaggerResponseLabel struct { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index afb93c50fe1ba..aaa9636f8c50a 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -6048,6 +6048,61 @@ } } }, + "/repos/{owner}/{repo}/issues/{index}/timeline": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "List all comments and events on an issue", + "operationId": "issueGetCommentsAndTimeline", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated since the specified time are returned.", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated before the provided time are returned.", + "name": "before", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TimelineList" + } + } + } + }, "/repos/{owner}/{repo}/issues/{index}/times": { "get": { "produces": [ @@ -16973,6 +17028,130 @@ "format": "int64", "x-go-package": "code.gitea.io/gitea/modules/timeutil" }, + "TimelineComment": { + "description": "Comment represents a comment on a commit or issue", + "type": "object", + "properties": { + "assignee": { + "$ref": "#/definitions/User" + }, + "assignee_team": { + "$ref": "#/definitions/Team" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "dependent_issue": { + "$ref": "#/definitions/Issue" + }, + "html_url": { + "type": "string", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "issue_url": { + "type": "string", + "x-go-name": "IssueURL" + }, + "label": { + "$ref": "#/definitions/Label" + }, + "milestone": { + "$ref": "#/definitions/Milestone" + }, + "new_ref": { + "type": "string", + "x-go-name": "NewRef" + }, + "new_title": { + "type": "string", + "x-go-name": "NewTitle" + }, + "old_milestone": { + "$ref": "#/definitions/Milestone" + }, + "old_project_id": { + "type": "integer", + "format": "int64", + "x-go-name": "OldProjectID" + }, + "old_ref": { + "type": "string", + "x-go-name": "OldRef" + }, + "old_title": { + "type": "string", + "x-go-name": "OldTitle" + }, + "project_id": { + "type": "integer", + "format": "int64", + "x-go-name": "ProjectID" + }, + "pull_request_url": { + "type": "string", + "x-go-name": "PRURL" + }, + "ref_action": { + "description": "action that was used to refernce issue/PR\n0 means the cross-reference is simply a comment\n1 means the cross-reference should close an issue if it is resolved\n2 means the cross-reference should reopen an issue if it is resolved\n3 means the cross-reference will no longer affect the source", + "type": "integer", + "format": "int64", + "x-go-name": "RefAction" + }, + "ref_comment": { + "$ref": "#/definitions/Comment" + }, + "ref_commit_sha": { + "description": "commit SHA where issue/PR was referenced", + "type": "string", + "x-go-name": "RefCommitSHA" + }, + "ref_issue": { + "$ref": "#/definitions/Issue" + }, + "removed_assignee": { + "description": "whether the assignees were removed or added", + "type": "boolean", + "x-go-name": "RemovedAssignee" + }, + "resolve_doer": { + "$ref": "#/definitions/User" + }, + "review_id": { + "type": "integer", + "format": "int64", + "x-go-name": "ReviewID" + }, + "time": { + "$ref": "#/definitions/TrackedTime" + }, + "type": { + "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Comment a line of code\n22 Reviews a pull request by giving general feedback\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review", + "type": "integer", + "format": "int64", + "x-go-name": "Type" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "TopicName": { "description": "TopicName a list of repo topic names", "type": "object", @@ -18000,6 +18179,15 @@ } } }, + "TimelineList": { + "description": "TimelineList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TimelineComment" + } + } + }, "TopicListResponse": { "description": "TopicListResponse", "schema": { From 330ea4d9fd3da6b5b21885411b8d8a73f16b2987 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 14:36:36 +0200 Subject: [PATCH 02/22] Fix swagger --- templates/swagger/v1_json.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index aaa9636f8c50a..70ac7717507c6 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -17029,7 +17029,7 @@ "x-go-package": "code.gitea.io/gitea/modules/timeutil" }, "TimelineComment": { - "description": "Comment represents a comment on a commit or issue", + "description": "TimelineComment represents a timeline comment (comment of any type) on a commit or issue", "type": "object", "properties": { "assignee": { @@ -17103,7 +17103,7 @@ "x-go-name": "PRURL" }, "ref_action": { - "description": "action that was used to refernce issue/PR\n0 means the cross-reference is simply a comment\n1 means the cross-reference should close an issue if it is resolved\n2 means the cross-reference should reopen an issue if it is resolved\n3 means the cross-reference will no longer affect the source", + "description": "action that was used to reference issue/PR\n0 means the cross-reference is simply a comment\n1 means the cross-reference should close an issue if it is resolved\n2 means the cross-reference should reopen an issue if it is resolved\n3 means the cross-reference will no longer affect the source", "type": "integer", "format": "int64", "x-go-name": "RefAction" From a96bcc72364f45c5dbd808af24496daa706438e0 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 15:30:42 +0200 Subject: [PATCH 03/22] Don't show code comments (use review api instead) --- modules/structs/issue_comment.go | 4 ++-- routers/api/v1/repo/issue_comment.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index e8de160d0fd91..eb68a93b11c63 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -62,7 +62,7 @@ type TimelineComment struct { // 18 Removed a due date // 19 Dependency added // 20 Dependency removed - // 21 Comment a line of code + // 21 Comment a line of code, use review API to get more information // 22 Reviews a pull request by giving general feedback // 23 Lock an issue, giving only collaborators access // 24 Unlocks a previously locked issue @@ -107,7 +107,7 @@ type TimelineComment struct { // commit SHA where issue/PR was referenced RefCommitSHA string `json:"ref_commit_sha"` - ReviewID int64 `json:"review_id"` + ReviewID int64 `json:"review_id"` Label *Label `json:"label"` diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 547cb0cd719cb..47b27cec17600 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -172,7 +172,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { var apiComments []*api.TimelineComment for i, comment := range comments { - if isXRefCommentAccessible(ctx.User, comment, issue.RepoID) { + if comment.Type != models.CommentTypeCode && isXRefCommentAccessible(ctx.User, comment, issue.RepoID) { comment.Issue = issue apiComments = append(apiComments, convert.ToTimelineComment(comments[i], ctx.User)) } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 70ac7717507c6..82508b48fac5d 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -17136,7 +17136,7 @@ "$ref": "#/definitions/TrackedTime" }, "type": { - "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Comment a line of code\n22 Reviews a pull request by giving general feedback\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review", + "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Comment a line of code, use review API to get more information\n22 Reviews a pull request by giving general feedback\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review", "type": "integer", "format": "int64", "x-go-name": "Type" From 2df41c1c06e47b3fe96f4183c0feb4e1d7089425 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 15:33:39 +0200 Subject: [PATCH 04/22] fmt --- modules/structs/issue_comment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index eb68a93b11c63..44d829ef8d9c5 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -107,7 +107,7 @@ type TimelineComment struct { // commit SHA where issue/PR was referenced RefCommitSHA string `json:"ref_commit_sha"` - ReviewID int64 `json:"review_id"` + ReviewID int64 `json:"review_id"` Label *Label `json:"label"` From 6811c3a5758d0c4aa9db28787f7410e1378a6a32 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 16:11:31 +0200 Subject: [PATCH 05/22] Fix comment --- modules/structs/issue_comment.go | 4 ++-- templates/swagger/v1_json.tmpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index 44d829ef8d9c5..f04597d68bd5a 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -62,8 +62,8 @@ type TimelineComment struct { // 18 Removed a due date // 19 Dependency added // 20 Dependency removed - // 21 Comment a line of code, use review API to get more information - // 22 Reviews a pull request by giving general feedback + // 21 Not returned; use review API to get more information + // 22 Reviews a pull request by giving general feedback; use review API to get more information // 23 Lock an issue, giving only collaborators access // 24 Unlocks a previously locked issue // 25 Change pull request's target branch diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 82508b48fac5d..c77d066e39da6 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -17136,7 +17136,7 @@ "$ref": "#/definitions/TrackedTime" }, "type": { - "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Comment a line of code, use review API to get more information\n22 Reviews a pull request by giving general feedback\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review", + "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Not returned; use review API to get more information\n22 Reviews a pull request by giving general feedback; use review API to get more information\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review", "type": "integer", "format": "int64", "x-go-name": "Type" From ea097a6ba76c380f590ccdc1584f0a04b16b0c76 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 16:43:10 +0200 Subject: [PATCH 06/22] Time -> TrackedTime --- modules/convert/issue_comment.go | 2 +- modules/structs/issue_comment.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index 30e3d18231f73..84a49314c2eca 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -91,7 +91,7 @@ func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineCommen } if c.Time != nil { - comment.Time = ToTrackedTime(c.Time) + comment.TrackedTime = ToTrackedTime(c.Time) } if c.RefIssueID != 0 { diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index f04597d68bd5a..f264736a063da 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -90,7 +90,7 @@ type TimelineComment struct { ProjectID int64 `json:"project_id"` OldMilestone *Milestone `json:"old_milestone"` Milestone *Milestone `json:"milestone"` - Time *TrackedTime `json:"time"` + TrackedTime *TrackedTime `json:"tracked_time"` OldTitle string `json:"old_title"` NewTitle string `json:"new_title"` OldRef string `json:"old_ref"` diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index c77d066e39da6..57f7b77b9f3dc 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -17132,7 +17132,7 @@ "format": "int64", "x-go-name": "ReviewID" }, - "time": { + "tracked_time": { "$ref": "#/definitions/TrackedTime" }, "type": { From 7fec3c74288b0d3f22cc01332190f3e24202fe05 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 16:43:50 +0200 Subject: [PATCH 07/22] Use var directly --- routers/api/v1/repo/issue_comment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 47b27cec17600..09e8303a7c7d9 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -174,7 +174,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { for i, comment := range comments { if comment.Type != models.CommentTypeCode && isXRefCommentAccessible(ctx.User, comment, issue.RepoID) { comment.Issue = issue - apiComments = append(apiComments, convert.ToTimelineComment(comments[i], ctx.User)) + apiComments = append(apiComments, convert.ToTimelineComment(comment, ctx.User)) } } From 8a443f0fdb7fd53499adc9e11388deb8f9300629 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 16:49:47 +0200 Subject: [PATCH 08/22] Add logger --- modules/convert/issue_comment.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index 84a49314c2eca..2570272a70d15 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -6,6 +6,7 @@ package convert import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" ) @@ -27,31 +28,37 @@ func ToComment(c *models.Comment) *api.Comment { func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineComment { err := c.LoadMilestone() if err != nil { + log.Error("LoadMilestone: %v", err) return nil } err = c.LoadAssigneeUserAndTeam() if err != nil { + log.Error("LoadAssigneeUserAndTeam: %v", err) return nil } err = c.LoadResolveDoer() if err != nil { + log.Error("LoadResolveDoer: %v", err) return nil } err = c.LoadDepIssueDetails() if err != nil { + log.Error("LoadDepIssueDetails: %v", err) return nil } err = c.LoadTime() if err != nil { + log.Error("LoadTime: %v", err) return nil } err = c.LoadLabel() if err != nil { + log.Error("LoadLabel: %v", err) return nil } @@ -97,6 +104,7 @@ func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineCommen if c.RefIssueID != 0 { issue, err := models.GetIssueByID(c.RefIssueID) if err != nil { + log.Error("GetIssueByID(%d): %v", c.RefIssueID, err) return nil } comment.RefIssue = ToAPIIssue(issue) @@ -105,10 +113,12 @@ func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineCommen if c.RefCommentID != 0 { com, err := models.GetCommentByID(c.RefCommentID) if err != nil { + log.Error("GetCommentByID(%d): %v", c.RefCommentID, err) return nil } err = com.LoadPoster() if err != nil { + log.Error("LoadPoster: %v", err) return nil } comment.RefComment = ToComment(com) @@ -121,6 +131,7 @@ func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineCommen var err error org, err = models.GetUserByID(c.Label.OrgID) if err != nil { + log.Error("GetCommentByID(%d): %v", c.Label.OrgID, err) return nil } } @@ -128,6 +139,7 @@ func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineCommen var err error repo, err = models.GetRepositoryByID(c.Label.RepoID) if err != nil { + log.Error("GetRepositoryByID(%d): %v", c.Label.RepoID, err) return nil } } From b4bcf1f1094229bb2c01de3dedc3f4ffd07cf0e6 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 22 Oct 2021 16:55:49 +0200 Subject: [PATCH 09/22] Fix lint --- routers/api/v1/repo/issue_comment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 09e8303a7c7d9..38245280dbe7c 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -171,7 +171,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { } var apiComments []*api.TimelineComment - for i, comment := range comments { + for _, comment := range comments { if comment.Type != models.CommentTypeCode && isXRefCommentAccessible(ctx.User, comment, issue.RepoID) { comment.Issue = issue apiComments = append(apiComments, convert.ToTimelineComment(comment, ctx.User)) From f6df41ee0bf518321b7b01009a0afe143b99aee7 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sat, 23 Oct 2021 13:17:56 +0200 Subject: [PATCH 10/22] Fix test --- integrations/api_comment_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 70a5d2b5929e6..e0989baaae547 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -182,7 +182,7 @@ func TestAPIDeleteComment(t *testing.T) { func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() - comment := db.AssertExistsAndLoadBean(t, &models.Comment{}).(*models.Comment) + comment := db.AssertExistsAndLoadBean(t, &models.Comment{}, db.Cond("NOT type = ?", models.CommentTypeCode)).(*models.Comment) issue := db.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) repo := db.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) repoOwner := db.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) From ffcfe38731eda4d2de6e0566b1aec8848d56af96 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 29 Oct 2021 18:07:03 +0200 Subject: [PATCH 11/22] Add comments --- integrations/api_comment_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index e0989baaae547..5dbb2609a2b5a 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -182,16 +182,20 @@ func TestAPIDeleteComment(t *testing.T) { func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() + // load comments that are not code comments comment := db.AssertExistsAndLoadBean(t, &models.Comment{}, db.Cond("NOT type = ?", models.CommentTypeCode)).(*models.Comment) issue := db.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) repo := db.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) repoOwner := db.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + // make request session := loginUser(t, repoOwner.Name) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/timeline", repoOwner.Name, repo.Name, issue.Index) resp := session.MakeRequest(t, req, http.StatusOK) + // check if lens of list returned by API and + // lists extracted directly from DB are the same var comments []*api.TimelineComment DecodeJSON(t, resp, &comments) expectedCount := db.GetCount(t, &models.Comment{IssueID: issue.ID}) From efdb22432db46bbea4320d56783c1176ade43d59 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 29 Oct 2021 18:19:18 +0200 Subject: [PATCH 12/22] fmt --- integrations/api_comment_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 5dbb2609a2b5a..0a1f335a940de 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -195,7 +195,7 @@ func TestAPIListIssueTimeline(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) // check if lens of list returned by API and - // lists extracted directly from DB are the same + // lists extracted directly from DB are the same var comments []*api.TimelineComment DecodeJSON(t, resp, &comments) expectedCount := db.GetCount(t, &models.Comment{IssueID: issue.ID}) From fabe8ebd2fd3e35a44398b3c0d6387696f5ac76d Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sat, 30 Oct 2021 18:05:37 +0200 Subject: [PATCH 13/22] [test] get issue directly by ID --- integrations/api_comment_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 0a1f335a940de..ffe11be92dc55 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -183,8 +183,7 @@ func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() // load comments that are not code comments - comment := db.AssertExistsAndLoadBean(t, &models.Comment{}, db.Cond("NOT type = ?", models.CommentTypeCode)).(*models.Comment) - issue := db.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + issue := db.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) repo := db.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) repoOwner := db.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) From c2017dcd900f33c56ff02bc31e5c5613a4e07a95 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 16 Nov 2021 19:29:38 +0100 Subject: [PATCH 14/22] Update test --- integrations/api_comment_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 0385481d01de0..8748ac835f895 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -183,9 +183,9 @@ func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() // load comments that are not code comments - issue := db.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) - repo := db.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) - repoOwner := db.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) + repoOwner := unittest.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) // make request session := loginUser(t, repoOwner.Name) @@ -197,6 +197,6 @@ func TestAPIListIssueTimeline(t *testing.T) { // lists extracted directly from DB are the same var comments []*api.TimelineComment DecodeJSON(t, resp, &comments) - expectedCount := db.GetCount(t, &models.Comment{IssueID: issue.ID}) + expectedCount := unittest.GetCount(t, &models.Comment{IssueID: issue.ID}) assert.EqualValues(t, expectedCount, len(comments)) } From f8356856edf0e4850f0a1bf9682b66787c65486b Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 22 Nov 2021 19:15:05 +0100 Subject: [PATCH 15/22] Add description for changed refs --- modules/structs/issue_comment.go | 1 + templates/swagger/v1_json.tmpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index f264736a063da..a03d6b6b32fef 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -74,6 +74,7 @@ type TimelineComment struct { // 30 Project changed // 31 Project board changed // 32 Dismiss Review + // 33 Change issue ref Type int64 `json:"type"` HTMLURL string `json:"html_url"` diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index fbd927a2ce54e..1a9fcf25a412d 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -17436,7 +17436,7 @@ "$ref": "#/definitions/TrackedTime" }, "type": { - "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Not returned; use review API to get more information\n22 Reviews a pull request by giving general feedback; use review API to get more information\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review", + "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Not returned; use review API to get more information\n22 Reviews a pull request by giving general feedback; use review API to get more information\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review\n33 Change issue ref", "type": "integer", "format": "int64", "x-go-name": "Type" From 7a8b1f11c92a95656d2a12b300680240436f1132 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sat, 27 Nov 2021 14:37:15 +0100 Subject: [PATCH 16/22] Fix build issues + lint --- integrations/api_comment_test.go | 4 ++-- modules/convert/issue_comment.go | 7 ++++--- routers/api/v1/repo/issue_comment.go | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 125c7efe7e26e..d05a3b0aac619 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -183,10 +183,10 @@ func TestAPIDeleteComment(t *testing.T) { func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() - // load comments that are not code comments + // load comment issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) // make request session := loginUser(t, repoOwner.Name) diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index 2570272a70d15..1004461e9cacf 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -6,6 +6,7 @@ package convert import ( "code.gitea.io/gitea/models" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" ) @@ -25,7 +26,7 @@ func ToComment(c *models.Comment) *api.Comment { } // ToTimelineComment converts a models.Comment to the api.TimelineComment format -func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineComment { +func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineComment { err := c.LoadMilestone() if err != nil { log.Error("LoadMilestone: %v", err) @@ -125,11 +126,11 @@ func ToTimelineComment(c *models.Comment, doer *models.User) *api.TimelineCommen } if c.Label != nil { - var org *models.User + var org *user_model.User var repo *models.Repository if c.Label.BelongsToOrg() { var err error - org, err = models.GetUserByID(c.Label.OrgID) + org, err = user_model.GetUserByID(c.Label.OrgID) if err != nil { log.Error("GetCommentByID(%d): %v", c.Label.OrgID, err) return nil diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 38245280dbe7c..378f0cf1208b4 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -10,6 +10,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -182,7 +183,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { ctx.JSON(http.StatusOK, &apiComments) } -func isXRefCommentAccessible(user *models.User, c *models.Comment, issueRepoID int64) bool { +func isXRefCommentAccessible(user *user_model.User, c *models.Comment, issueRepoID int64) bool { // Remove comments that the user has no permissions to see if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { var err error From df62eedd67ea60face033dfaac082e6fb45e7cb7 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sun, 12 Dec 2021 18:13:50 +0100 Subject: [PATCH 17/22] Fix build --- integrations/api_comment_test.go | 2 +- modules/convert/issue_comment.go | 7 ++++--- routers/api/v1/repo/issue_comment.go | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 90fe94f87eadf..4c4c6308eeabc 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -186,7 +186,7 @@ func TestAPIListIssueTimeline(t *testing.T) { // load comment issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: issue.RepoID}).(*models.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) // make request diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index 1004461e9cacf..e4177d4873862 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -6,6 +6,7 @@ package convert import ( "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" @@ -127,18 +128,18 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo if c.Label != nil { var org *user_model.User - var repo *models.Repository + var repo *repo_model.Repository if c.Label.BelongsToOrg() { var err error org, err = user_model.GetUserByID(c.Label.OrgID) if err != nil { - log.Error("GetCommentByID(%d): %v", c.Label.OrgID, err) + log.Error("GetUserByID(%d): %v", c.Label.OrgID, err) return nil } } if c.Label.BelongsToRepo() { var err error - repo, err = models.GetRepositoryByID(c.Label.RepoID) + repo, err = repo_model.GetRepositoryByID(c.Label.RepoID) if err != nil { log.Error("GetRepositoryByID(%d): %v", c.Label.RepoID, err) return nil diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 378f0cf1208b4..5729094336733 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -10,6 +10,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -188,7 +189,7 @@ func isXRefCommentAccessible(user *user_model.User, c *models.Comment, issueRepo if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { var err error // Set RefRepo for description in template - c.RefRepo, err = models.GetRepositoryByID(c.RefRepoID) + c.RefRepo, err = repo_model.GetRepositoryByID(c.RefRepoID) if err != nil { return false } From 4dd46ef30f38b20bb123899ae3fd77be4879bf2b Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Wed, 22 Dec 2021 12:46:14 +0100 Subject: [PATCH 18/22] Use string enums --- models/issue_comment.go | 39 ++++++++++++++++++++++++++ modules/convert/issue_comment.go | 4 +-- modules/references/references.go | 9 ++++++ modules/structs/issue_comment.go | 47 ++------------------------------ 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/models/issue_comment.go b/models/issue_comment.go index e54d41bf0d8b8..e8066f606d63e 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -110,6 +110,45 @@ const ( CommentTypeChangeIssueRef ) +func (t CommentType) String() string { + return []string{ + "comment", + "reopen", + "close", + "issue_ref", + "commit_ref", + "comment_ref", + "pull_ref", + "label", + "milestone", + "assignees", + "change_title", + "delete_branch", + "start_tracking", + "stop_tracking", + "add_time_manual", + "cancel_tracking", + "added_deadline", + "modified_deadline", + "removed_deadline", + "add_dependency", + "remove_dependency", + "code", + "review", + "lock", + "unlock", + "change_target_branch", + "delete_time_manual", + "review_request", + "merge_pull", + "pull_push", + "project", + "project_board", + "dismiss_review", + "change_issue_ref", + }[t] +} + // RoleDescriptor defines comment tag type type RoleDescriptor int diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index e4177d4873862..caba2b506e435 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -66,7 +66,7 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo comment := &api.TimelineComment{ ID: c.ID, - Type: int64(c.Type), + Type: c.Type.String(), Poster: ToUser(c.Poster, nil), HTMLURL: c.HTMLURL(), IssueURL: c.IssueURL(), @@ -84,7 +84,7 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo OldRef: c.OldRef, NewRef: c.NewRef, - RefAction: int64(c.RefAction), + RefAction: c.RefAction.String(), RefCommitSHA: c.CommitSHA, ReviewID: c.ReviewID, diff --git a/modules/references/references.go b/modules/references/references.go index cfc01cd4c0132..b6fc8d352a460 100644 --- a/modules/references/references.go +++ b/modules/references/references.go @@ -65,6 +65,15 @@ const ( XRefActionNeutered // 3 ) +func (a XRefAction) String() string { + return []string{ + "none", + "closes", + "reopens", + "neutered", + }[a] +} + // IssueReference contains an unverified cross-reference to a local issue or pull request type IssueReference struct { Index int64 diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index a03d6b6b32fef..e13ec05d01856 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -38,44 +38,8 @@ type EditIssueCommentOption struct { // TimelineComment represents a timeline comment (comment of any type) on a commit or issue type TimelineComment struct { - ID int64 `json:"id"` - - // Type specifies the type of an event. - // 0 Plain comment, can be associated with a commit (CommitID > 0) and a line (LineNum > 0) - // 1 Reopen issue/pull request - // 2 Close issue/pull request - // 3 References. - // 4 Reference from a commit (not part of a pull request) - // 5 Reference from a comment - // 6 Reference from a pull request - // 7 Labels changed (if Body is "1", label was added, if not it was removed) - // 8 Milestone changed - // 9 Assignees changed - // 10 Change Title - // 11 Delete Branch - // 12 Start a stopwatch for time tracking - // 13 Stop a stopwatch for time tracking - // 14 Add time manual for time tracking - // 15 Cancel a stopwatch for time tracking - // 16 Added a due date - // 17 Modified the due date - // 18 Removed a due date - // 19 Dependency added - // 20 Dependency removed - // 21 Not returned; use review API to get more information - // 22 Reviews a pull request by giving general feedback; use review API to get more information - // 23 Lock an issue, giving only collaborators access - // 24 Unlocks a previously locked issue - // 25 Change pull request's target branch - // 26 Delete time manual for time tracking - // 27 add or remove Request from one - // 28 merge pull request - // 29 push to PR head branch (information about the push is included in Body) - // 30 Project changed - // 31 Project board changed - // 32 Dismiss Review - // 33 Change issue ref - Type int64 `json:"type"` + ID int64 `json:"id"` + Type string `json:"type"` HTMLURL string `json:"html_url"` PRURL string `json:"pull_request_url"` @@ -99,12 +63,7 @@ type TimelineComment struct { RefIssue *Issue `json:"ref_issue"` RefComment *Comment `json:"ref_comment"` - // action that was used to reference issue/PR - // 0 means the cross-reference is simply a comment - // 1 means the cross-reference should close an issue if it is resolved - // 2 means the cross-reference should reopen an issue if it is resolved - // 3 means the cross-reference will no longer affect the source - RefAction int64 `json:"ref_action"` + RefAction string `json:"ref_action"` // commit SHA where issue/PR was referenced RefCommitSHA string `json:"ref_commit_sha"` From dd3e9c488233e8a31fd08f241c8f1fb5aac8944e Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Wed, 22 Dec 2021 12:49:29 +0100 Subject: [PATCH 19/22] Update swagger --- templates/swagger/v1_json.tmpl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 138fcfdf54ce3..4d797840b8662 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -17411,9 +17411,7 @@ "x-go-name": "PRURL" }, "ref_action": { - "description": "action that was used to reference issue/PR\n0 means the cross-reference is simply a comment\n1 means the cross-reference should close an issue if it is resolved\n2 means the cross-reference should reopen an issue if it is resolved\n3 means the cross-reference will no longer affect the source", - "type": "integer", - "format": "int64", + "type": "string", "x-go-name": "RefAction" }, "ref_comment": { @@ -17444,9 +17442,7 @@ "$ref": "#/definitions/TrackedTime" }, "type": { - "description": "Type specifies the type of an event.\n0 Plain comment, can be associated with a commit (CommitID \u003e 0) and a line (LineNum \u003e 0)\n1 Reopen issue/pull request\n2 Close issue/pull request\n3 References.\n4 Reference from a commit (not part of a pull request)\n5 Reference from a comment\n6 Reference from a pull request\n7 Labels changed (if Body is \"1\", label was added, if not it was removed)\n8 Milestone changed\n9 Assignees changed\n10 Change Title\n11 Delete Branch\n12 Start a stopwatch for time tracking\n13 Stop a stopwatch for time tracking\n14 Add time manual for time tracking\n15 Cancel a stopwatch for time tracking\n16 Added a due date\n17 Modified the due date\n18 Removed a due date\n19 Dependency added\n20 Dependency removed\n21 Not returned; use review API to get more information\n22 Reviews a pull request by giving general feedback; use review API to get more information\n23 Lock an issue, giving only collaborators access\n24 Unlocks a previously locked issue\n25 Change pull request's target branch\n26 Delete time manual for time tracking\n27 add or remove Request from one\n28 merge pull request\n29 push to PR head branch (information about the push is included in Body)\n30 Project changed\n31 Project board changed\n32 Dismiss Review\n33 Change issue ref", - "type": "integer", - "format": "int64", + "type": "string", "x-go-name": "Type" }, "updated_at": { From 06db66a61549c111c68dea50c1352ae0bd320f29 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Thu, 30 Dec 2021 18:04:25 +0100 Subject: [PATCH 20/22] Support `page` and `limit` params --- routers/api/v1/repo/issue_comment.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 5729094336733..16f220c82e77a 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -133,6 +133,14 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { // description: if provided, only comments updated since the specified time are returned. // type: string // format: date-time + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // - name: limit + // in: query + // description: page size of results + // type: integer // - name: before // in: query // description: if provided, only comments updated before the provided time are returned. @@ -155,6 +163,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { issue.Repo = ctx.Repo.Repository opts := &models.FindCommentsOptions{ + ListOptions: utils.GetListOptions(ctx), IssueID: issue.ID, Since: since, Before: before, From a6ac7bd7f91288f85297d67821dcf9687e92d002 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sat, 1 Jan 2022 14:44:27 +0100 Subject: [PATCH 21/22] fmt + swagger --- routers/api/v1/repo/issue_comment.go | 8 ++++---- templates/swagger/v1_json.tmpl | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 16f220c82e77a..b929cec3737c4 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -164,10 +164,10 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { opts := &models.FindCommentsOptions{ ListOptions: utils.GetListOptions(ctx), - IssueID: issue.ID, - Since: since, - Before: before, - Type: models.CommentTypeUnknown, + IssueID: issue.ID, + Since: since, + Before: before, + Type: models.CommentTypeUnknown, } comments, err := models.FindComments(opts) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 4d797840b8662..f634a88c9ae19 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -6088,6 +6088,18 @@ "name": "since", "in": "query" }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + }, { "type": "string", "format": "date-time", From dfd0e65b782051c16c6a036414a965a40832546c Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sat, 1 Jan 2022 14:48:25 +0100 Subject: [PATCH 22/22] Use global slices --- models/issue_comment.go | 74 ++++++++++++++++---------------- modules/references/references.go | 14 +++--- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/models/issue_comment.go b/models/issue_comment.go index e8066f606d63e..d4b54be26b0ac 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -110,43 +110,45 @@ const ( CommentTypeChangeIssueRef ) +var commentStrings = []string{ + "comment", + "reopen", + "close", + "issue_ref", + "commit_ref", + "comment_ref", + "pull_ref", + "label", + "milestone", + "assignees", + "change_title", + "delete_branch", + "start_tracking", + "stop_tracking", + "add_time_manual", + "cancel_tracking", + "added_deadline", + "modified_deadline", + "removed_deadline", + "add_dependency", + "remove_dependency", + "code", + "review", + "lock", + "unlock", + "change_target_branch", + "delete_time_manual", + "review_request", + "merge_pull", + "pull_push", + "project", + "project_board", + "dismiss_review", + "change_issue_ref", +} + func (t CommentType) String() string { - return []string{ - "comment", - "reopen", - "close", - "issue_ref", - "commit_ref", - "comment_ref", - "pull_ref", - "label", - "milestone", - "assignees", - "change_title", - "delete_branch", - "start_tracking", - "stop_tracking", - "add_time_manual", - "cancel_tracking", - "added_deadline", - "modified_deadline", - "removed_deadline", - "add_dependency", - "remove_dependency", - "code", - "review", - "lock", - "unlock", - "change_target_branch", - "delete_time_manual", - "review_request", - "merge_pull", - "pull_push", - "project", - "project_board", - "dismiss_review", - "change_issue_ref", - }[t] + return commentStrings[t] } // RoleDescriptor defines comment tag type diff --git a/modules/references/references.go b/modules/references/references.go index b6fc8d352a460..74837b8553f60 100644 --- a/modules/references/references.go +++ b/modules/references/references.go @@ -49,6 +49,13 @@ var ( giteaHostInit sync.Once giteaHost string giteaIssuePullPattern *regexp.Regexp + + actionStrings = []string{ + "none", + "closes", + "reopens", + "neutered", + } ) // XRefAction represents the kind of effect a cross reference has once is resolved @@ -66,12 +73,7 @@ const ( ) func (a XRefAction) String() string { - return []string{ - "none", - "closes", - "reopens", - "neutered", - }[a] + return actionStrings[a] } // IssueReference contains an unverified cross-reference to a local issue or pull request