Skip to content

Commit d0022eb

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: [skip ci] Updated licenses and gitignores Fix overflow in issue card (go-gitea#31203) Fix agit checkout command line hint & fix ShowMergeInstructions checking (go-gitea#31219) Fix the possible migration failure on 286 with postgres 16 (go-gitea#31209) Only update poster in issue/comment list if it has been loaded (go-gitea#31216) Return an empty string when a repo has no avatar in the repo API (go-gitea#31187) Split sanitizer functions and fine-tune some tests (go-gitea#31192) Performance improvements for pull request list API (go-gitea#30490) Fix URL In Gitea Actions Badge Docs (go-gitea#31191)
2 parents 12e3fc3 + c685420 commit d0022eb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+654
-434
lines changed

docs/content/usage/actions/badge.en-us.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ It is designed to be compatible with [GitHub Actions workflow badge](https://doc
2525
You can use the following URL to get the badge:
2626

2727
```
28-
https://your-gitea-instance.com/{owner}/{repo}/actions/workflows/{workflow_file}?branch={branch}&event={event}
28+
https://your-gitea-instance.com/{owner}/{repo}/actions/workflows/{workflow_file}/badge.svg?branch={branch}&event={event}
2929
```
3030

3131
- `{owner}`: The owner of the repository.

models/issues/assignees.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,27 @@ func init() {
2727

2828
// LoadAssignees load assignees of this issue.
2929
func (issue *Issue) LoadAssignees(ctx context.Context) (err error) {
30+
if issue.isAssigneeLoaded || len(issue.Assignees) > 0 {
31+
return nil
32+
}
33+
3034
// Reset maybe preexisting assignees
3135
issue.Assignees = []*user_model.User{}
3236
issue.Assignee = nil
3337

34-
err = db.GetEngine(ctx).Table("`user`").
38+
if err = db.GetEngine(ctx).Table("`user`").
3539
Join("INNER", "issue_assignees", "assignee_id = `user`.id").
3640
Where("issue_assignees.issue_id = ?", issue.ID).
37-
Find(&issue.Assignees)
38-
if err != nil {
41+
Find(&issue.Assignees); err != nil {
3942
return err
4043
}
4144

45+
issue.isAssigneeLoaded = true
4246
// Check if we have at least one assignee and if yes put it in as `Assignee`
4347
if len(issue.Assignees) > 0 {
4448
issue.Assignee = issue.Assignees[0]
4549
}
46-
return err
50+
return nil
4751
}
4852

4953
// GetAssigneeIDsByIssue returns the IDs of users assigned to an issue

models/issues/comment_list.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,25 @@ import (
1616
// CommentList defines a list of comments
1717
type CommentList []*Comment
1818

19-
func (comments CommentList) getPosterIDs() []int64 {
20-
return container.FilterSlice(comments, func(c *Comment) (int64, bool) {
21-
return c.PosterID, c.PosterID > 0
22-
})
23-
}
24-
2519
// LoadPosters loads posters
2620
func (comments CommentList) LoadPosters(ctx context.Context) error {
2721
if len(comments) == 0 {
2822
return nil
2923
}
3024

31-
posterMaps, err := getPosters(ctx, comments.getPosterIDs())
25+
posterIDs := container.FilterSlice(comments, func(c *Comment) (int64, bool) {
26+
return c.PosterID, c.Poster == nil && c.PosterID > 0
27+
})
28+
29+
posterMaps, err := getPostersByIDs(ctx, posterIDs)
3230
if err != nil {
3331
return err
3432
}
3533

3634
for _, comment := range comments {
37-
comment.Poster = getPoster(comment.PosterID, posterMaps)
35+
if comment.Poster == nil {
36+
comment.Poster = getPoster(comment.PosterID, posterMaps)
37+
}
3838
}
3939
return nil
4040
}

models/issues/issue.go

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -98,44 +98,48 @@ var ErrIssueAlreadyChanged = util.NewInvalidArgumentErrorf("the issue is already
9898

9999
// Issue represents an issue or pull request of repository.
100100
type Issue struct {
101-
ID int64 `xorm:"pk autoincr"`
102-
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"`
103-
Repo *repo_model.Repository `xorm:"-"`
104-
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
105-
PosterID int64 `xorm:"INDEX"`
106-
Poster *user_model.User `xorm:"-"`
107-
OriginalAuthor string
108-
OriginalAuthorID int64 `xorm:"index"`
109-
Title string `xorm:"name"`
110-
Content string `xorm:"LONGTEXT"`
111-
RenderedContent template.HTML `xorm:"-"`
112-
ContentVersion int `xorm:"NOT NULL DEFAULT 0"`
113-
Labels []*Label `xorm:"-"`
114-
MilestoneID int64 `xorm:"INDEX"`
115-
Milestone *Milestone `xorm:"-"`
116-
Project *project_model.Project `xorm:"-"`
117-
Priority int
118-
AssigneeID int64 `xorm:"-"`
119-
Assignee *user_model.User `xorm:"-"`
120-
IsClosed bool `xorm:"INDEX"`
121-
IsRead bool `xorm:"-"`
122-
IsPull bool `xorm:"INDEX"` // Indicates whether is a pull request or not.
123-
PullRequest *PullRequest `xorm:"-"`
124-
NumComments int
125-
Ref string
126-
PinOrder int `xorm:"DEFAULT 0"`
101+
ID int64 `xorm:"pk autoincr"`
102+
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"`
103+
Repo *repo_model.Repository `xorm:"-"`
104+
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
105+
PosterID int64 `xorm:"INDEX"`
106+
Poster *user_model.User `xorm:"-"`
107+
OriginalAuthor string
108+
OriginalAuthorID int64 `xorm:"index"`
109+
Title string `xorm:"name"`
110+
Content string `xorm:"LONGTEXT"`
111+
RenderedContent template.HTML `xorm:"-"`
112+
ContentVersion int `xorm:"NOT NULL DEFAULT 0"`
113+
Labels []*Label `xorm:"-"`
114+
isLabelsLoaded bool `xorm:"-"`
115+
MilestoneID int64 `xorm:"INDEX"`
116+
Milestone *Milestone `xorm:"-"`
117+
isMilestoneLoaded bool `xorm:"-"`
118+
Project *project_model.Project `xorm:"-"`
119+
Priority int
120+
AssigneeID int64 `xorm:"-"`
121+
Assignee *user_model.User `xorm:"-"`
122+
isAssigneeLoaded bool `xorm:"-"`
123+
IsClosed bool `xorm:"INDEX"`
124+
IsRead bool `xorm:"-"`
125+
IsPull bool `xorm:"INDEX"` // Indicates whether is a pull request or not.
126+
PullRequest *PullRequest `xorm:"-"`
127+
NumComments int
128+
Ref string
129+
PinOrder int `xorm:"DEFAULT 0"`
127130

128131
DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
129132

130133
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
131134
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
132135
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
133136

134-
Attachments []*repo_model.Attachment `xorm:"-"`
135-
Comments CommentList `xorm:"-"`
136-
Reactions ReactionList `xorm:"-"`
137-
TotalTrackedTime int64 `xorm:"-"`
138-
Assignees []*user_model.User `xorm:"-"`
137+
Attachments []*repo_model.Attachment `xorm:"-"`
138+
isAttachmentsLoaded bool `xorm:"-"`
139+
Comments CommentList `xorm:"-"`
140+
Reactions ReactionList `xorm:"-"`
141+
TotalTrackedTime int64 `xorm:"-"`
142+
Assignees []*user_model.User `xorm:"-"`
139143

140144
// IsLocked limits commenting abilities to users on an issue
141145
// with write access
@@ -187,6 +191,19 @@ func (issue *Issue) LoadRepo(ctx context.Context) (err error) {
187191
return nil
188192
}
189193

194+
func (issue *Issue) LoadAttachments(ctx context.Context) (err error) {
195+
if issue.isAttachmentsLoaded || issue.Attachments != nil {
196+
return nil
197+
}
198+
199+
issue.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, issue.ID)
200+
if err != nil {
201+
return fmt.Errorf("getAttachmentsByIssueID [%d]: %w", issue.ID, err)
202+
}
203+
issue.isAttachmentsLoaded = true
204+
return nil
205+
}
206+
190207
// IsTimetrackerEnabled returns true if the repo enables timetracking
191208
func (issue *Issue) IsTimetrackerEnabled(ctx context.Context) bool {
192209
if err := issue.LoadRepo(ctx); err != nil {
@@ -287,11 +304,12 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) {
287304

288305
// LoadMilestone load milestone of this issue.
289306
func (issue *Issue) LoadMilestone(ctx context.Context) (err error) {
290-
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
307+
if !issue.isMilestoneLoaded && (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
291308
issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID)
292309
if err != nil && !IsErrMilestoneNotExist(err) {
293310
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %w", issue.RepoID, issue.MilestoneID, err)
294311
}
312+
issue.isMilestoneLoaded = true
295313
}
296314
return nil
297315
}
@@ -327,11 +345,8 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
327345
return err
328346
}
329347

330-
if issue.Attachments == nil {
331-
issue.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, issue.ID)
332-
if err != nil {
333-
return fmt.Errorf("getAttachmentsByIssueID [%d]: %w", issue.ID, err)
334-
}
348+
if err = issue.LoadAttachments(ctx); err != nil {
349+
return err
335350
}
336351

337352
if err = issue.loadComments(ctx); err != nil {
@@ -350,6 +365,13 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
350365
return issue.loadReactions(ctx)
351366
}
352367

368+
func (issue *Issue) ResetAttributesLoaded() {
369+
issue.isLabelsLoaded = false
370+
issue.isMilestoneLoaded = false
371+
issue.isAttachmentsLoaded = false
372+
issue.isAssigneeLoaded = false
373+
}
374+
353375
// GetIsRead load the `IsRead` field of the issue
354376
func (issue *Issue) GetIsRead(ctx context.Context, userID int64) error {
355377
issueUser := &IssueUser{IssueID: issue.ID, UID: userID}

models/issues/issue_label.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ func NewIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m
111111
return err
112112
}
113113

114+
issue.isLabelsLoaded = false
114115
issue.Labels = nil
115116
if err = issue.LoadLabels(ctx); err != nil {
116117
return err
@@ -160,6 +161,8 @@ func NewIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *us
160161
return err
161162
}
162163

164+
// reload all labels
165+
issue.isLabelsLoaded = false
163166
issue.Labels = nil
164167
if err = issue.LoadLabels(ctx); err != nil {
165168
return err
@@ -325,11 +328,12 @@ func FixIssueLabelWithOutsideLabels(ctx context.Context) (int64, error) {
325328

326329
// LoadLabels loads labels
327330
func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
328-
if issue.Labels == nil && issue.ID != 0 {
331+
if !issue.isLabelsLoaded && issue.Labels == nil && issue.ID != 0 {
329332
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
330333
if err != nil {
331334
return fmt.Errorf("getLabelsByIssueID [%d]: %w", issue.ID, err)
332335
}
336+
issue.isLabelsLoaded = true
333337
}
334338
return nil
335339
}

models/issues/issue_list.go

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,29 +72,29 @@ func (issues IssueList) LoadRepositories(ctx context.Context) (repo_model.Reposi
7272
return repo_model.ValuesRepository(repoMaps), nil
7373
}
7474

75-
func (issues IssueList) getPosterIDs() []int64 {
76-
return container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
77-
return issue.PosterID, true
78-
})
79-
}
80-
81-
func (issues IssueList) loadPosters(ctx context.Context) error {
75+
func (issues IssueList) LoadPosters(ctx context.Context) error {
8276
if len(issues) == 0 {
8377
return nil
8478
}
8579

86-
posterMaps, err := getPosters(ctx, issues.getPosterIDs())
80+
posterIDs := container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
81+
return issue.PosterID, issue.Poster == nil && issue.PosterID > 0
82+
})
83+
84+
posterMaps, err := getPostersByIDs(ctx, posterIDs)
8785
if err != nil {
8886
return err
8987
}
9088

9189
for _, issue := range issues {
92-
issue.Poster = getPoster(issue.PosterID, posterMaps)
90+
if issue.Poster == nil {
91+
issue.Poster = getPoster(issue.PosterID, posterMaps)
92+
}
9393
}
9494
return nil
9595
}
9696

97-
func getPosters(ctx context.Context, posterIDs []int64) (map[int64]*user_model.User, error) {
97+
func getPostersByIDs(ctx context.Context, posterIDs []int64) (map[int64]*user_model.User, error) {
9898
posterMaps := make(map[int64]*user_model.User, len(posterIDs))
9999
left := len(posterIDs)
100100
for left > 0 {
@@ -136,7 +136,7 @@ func (issues IssueList) getIssueIDs() []int64 {
136136
return ids
137137
}
138138

139-
func (issues IssueList) loadLabels(ctx context.Context) error {
139+
func (issues IssueList) LoadLabels(ctx context.Context) error {
140140
if len(issues) == 0 {
141141
return nil
142142
}
@@ -168,7 +168,7 @@ func (issues IssueList) loadLabels(ctx context.Context) error {
168168
err = rows.Scan(&labelIssue)
169169
if err != nil {
170170
if err1 := rows.Close(); err1 != nil {
171-
return fmt.Errorf("IssueList.loadLabels: Close: %w", err1)
171+
return fmt.Errorf("IssueList.LoadLabels: Close: %w", err1)
172172
}
173173
return err
174174
}
@@ -177,14 +177,15 @@ func (issues IssueList) loadLabels(ctx context.Context) error {
177177
// When there are no rows left and we try to close it.
178178
// Since that is not relevant for us, we can safely ignore it.
179179
if err1 := rows.Close(); err1 != nil {
180-
return fmt.Errorf("IssueList.loadLabels: Close: %w", err1)
180+
return fmt.Errorf("IssueList.LoadLabels: Close: %w", err1)
181181
}
182182
left -= limit
183183
issueIDs = issueIDs[limit:]
184184
}
185185

186186
for _, issue := range issues {
187187
issue.Labels = issueLabels[issue.ID]
188+
issue.isLabelsLoaded = true
188189
}
189190
return nil
190191
}
@@ -195,7 +196,7 @@ func (issues IssueList) getMilestoneIDs() []int64 {
195196
})
196197
}
197198

198-
func (issues IssueList) loadMilestones(ctx context.Context) error {
199+
func (issues IssueList) LoadMilestones(ctx context.Context) error {
199200
milestoneIDs := issues.getMilestoneIDs()
200201
if len(milestoneIDs) == 0 {
201202
return nil
@@ -220,6 +221,7 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
220221

221222
for _, issue := range issues {
222223
issue.Milestone = milestoneMaps[issue.MilestoneID]
224+
issue.isMilestoneLoaded = true
223225
}
224226
return nil
225227
}
@@ -263,7 +265,7 @@ func (issues IssueList) LoadProjects(ctx context.Context) error {
263265
return nil
264266
}
265267

266-
func (issues IssueList) loadAssignees(ctx context.Context) error {
268+
func (issues IssueList) LoadAssignees(ctx context.Context) error {
267269
if len(issues) == 0 {
268270
return nil
269271
}
@@ -310,6 +312,10 @@ func (issues IssueList) loadAssignees(ctx context.Context) error {
310312

311313
for _, issue := range issues {
312314
issue.Assignees = assignees[issue.ID]
315+
if len(issue.Assignees) > 0 {
316+
issue.Assignee = issue.Assignees[0]
317+
}
318+
issue.isAssigneeLoaded = true
313319
}
314320
return nil
315321
}
@@ -413,6 +419,7 @@ func (issues IssueList) LoadAttachments(ctx context.Context) (err error) {
413419

414420
for _, issue := range issues {
415421
issue.Attachments = attachments[issue.ID]
422+
issue.isAttachmentsLoaded = true
416423
}
417424
return nil
418425
}
@@ -538,23 +545,23 @@ func (issues IssueList) LoadAttributes(ctx context.Context) error {
538545
return fmt.Errorf("issue.loadAttributes: LoadRepositories: %w", err)
539546
}
540547

541-
if err := issues.loadPosters(ctx); err != nil {
542-
return fmt.Errorf("issue.loadAttributes: loadPosters: %w", err)
548+
if err := issues.LoadPosters(ctx); err != nil {
549+
return fmt.Errorf("issue.loadAttributes: LoadPosters: %w", err)
543550
}
544551

545-
if err := issues.loadLabels(ctx); err != nil {
546-
return fmt.Errorf("issue.loadAttributes: loadLabels: %w", err)
552+
if err := issues.LoadLabels(ctx); err != nil {
553+
return fmt.Errorf("issue.loadAttributes: LoadLabels: %w", err)
547554
}
548555

549-
if err := issues.loadMilestones(ctx); err != nil {
550-
return fmt.Errorf("issue.loadAttributes: loadMilestones: %w", err)
556+
if err := issues.LoadMilestones(ctx); err != nil {
557+
return fmt.Errorf("issue.loadAttributes: LoadMilestones: %w", err)
551558
}
552559

553560
if err := issues.LoadProjects(ctx); err != nil {
554561
return fmt.Errorf("issue.loadAttributes: loadProjects: %w", err)
555562
}
556563

557-
if err := issues.loadAssignees(ctx); err != nil {
564+
if err := issues.LoadAssignees(ctx); err != nil {
558565
return fmt.Errorf("issue.loadAttributes: loadAssignees: %w", err)
559566
}
560567

0 commit comments

Comments
 (0)