mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Add API to get issue/pull comments and events (timeline) (#17403)
* 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 * Fix swagger * Don't show code comments (use review api instead) * fmt * Fix comment * Time -> TrackedTime * Use var directly * Add logger * Fix lint * Fix test * Add comments * fmt * [test] get issue directly by ID * Update test * Add description for changed refs * Fix build issues + lint * Fix build * Use string enums * Update swagger * Support `page` and `limit` params * fmt + swagger * Use global slices Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
@@ -6,6 +6,9 @@ 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"
|
||||
)
|
||||
|
||||
@@ -22,3 +25,143 @@ 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 *user_model.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
|
||||
}
|
||||
|
||||
comment := &api.TimelineComment{
|
||||
ID: c.ID,
|
||||
Type: c.Type.String(),
|
||||
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: c.RefAction.String(),
|
||||
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.TrackedTime = ToTrackedTime(c.Time)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
if c.Label != nil {
|
||||
var org *user_model.User
|
||||
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("GetUserByID(%d): %v", c.Label.OrgID, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if c.Label.BelongsToRepo() {
|
||||
var err error
|
||||
repo, err = repo_model.GetRepositoryByID(c.Label.RepoID)
|
||||
if err != nil {
|
||||
log.Error("GetRepositoryByID(%d): %v", c.Label.RepoID, err)
|
||||
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
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -65,6 +72,10 @@ const (
|
||||
XRefActionNeutered // 3
|
||||
)
|
||||
|
||||
func (a XRefAction) String() string {
|
||||
return actionStrings[a]
|
||||
}
|
||||
|
||||
// IssueReference contains an unverified cross-reference to a local issue or pull request
|
||||
type IssueReference struct {
|
||||
Index int64
|
||||
|
@@ -35,3 +35,48 @@ 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 string `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"`
|
||||
TrackedTime *TrackedTime `json:"tracked_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"`
|
||||
RefAction string `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"`
|
||||
}
|
||||
|
Reference in New Issue
Block a user