Skip to content

Commit 4bab1d4

Browse files
Merge branch 'main' into fix-artifact-v4-upload-above-8MB
2 parents f036ed8 + 08adbc4 commit 4bab1d4

Some content is hidden

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

68 files changed

+754
-507
lines changed

.github/workflows/pull-db-tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ jobs:
201201
runs-on: ubuntu-latest
202202
services:
203203
mssql:
204-
image: mcr.microsoft.com/mssql/server:2017-latest
204+
# some images before 2024-04 can't run on new kernels
205+
image: mcr.microsoft.com/mssql/server:2019-latest
205206
env:
206207
ACCEPT_EULA: Y
207208
MSSQL_PID: Standard

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ module code.gitea.io/gitea
22

33
go 1.23
44

5+
// rfc5280 said: "The serial number is an integer assigned by the CA to each certificate."
6+
// But some CAs use negative serial number, just relax the check. related:
7+
// Default TLS cert uses negative serial number #895 https://github.com/microsoft/mssql-docker/issues/895
8+
godebug x509negativeserial=1
9+
510
require (
611
code.gitea.io/actions-proto-go v0.4.0
712
code.gitea.io/gitea-vet v0.2.3

models/issues/issue_project.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ func (issue *Issue) ProjectColumnID(ctx context.Context) int64 {
4848
}
4949

5050
// LoadIssuesFromColumn load issues assigned to this column
51-
func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column) (IssueList, error) {
52-
issueList, err := Issues(ctx, &IssuesOptions{
53-
ProjectColumnID: b.ID,
54-
ProjectID: b.ProjectID,
55-
SortType: "project-column-sorting",
56-
})
51+
func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *IssuesOptions) (IssueList, error) {
52+
issueList, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) {
53+
o.ProjectColumnID = b.ID
54+
o.ProjectID = b.ProjectID
55+
o.SortType = "project-column-sorting"
56+
}))
5757
if err != nil {
5858
return nil, err
5959
}
@@ -78,10 +78,10 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column) (IssueLi
7878
}
7979

8080
// LoadIssuesFromColumnList load issues assigned to the columns
81-
func LoadIssuesFromColumnList(ctx context.Context, bs project_model.ColumnList) (map[int64]IssueList, error) {
81+
func LoadIssuesFromColumnList(ctx context.Context, bs project_model.ColumnList, opts *IssuesOptions) (map[int64]IssueList, error) {
8282
issuesMap := make(map[int64]IssueList, len(bs))
8383
for i := range bs {
84-
il, err := LoadIssuesFromColumn(ctx, bs[i])
84+
il, err := LoadIssuesFromColumn(ctx, bs[i], opts)
8585
if err != nil {
8686
return nil, err
8787
}

models/issues/issue_search.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ type IssuesOptions struct { //nolint
5454
User *user_model.User // issues permission scope
5555
}
5656

57+
// Copy returns a copy of the options.
58+
// Be careful, it's not a deep copy, so `IssuesOptions.RepoIDs = {...}` is OK while `IssuesOptions.RepoIDs[0] = ...` is not.
59+
func (o *IssuesOptions) Copy(edit ...func(options *IssuesOptions)) *IssuesOptions {
60+
if o == nil {
61+
return nil
62+
}
63+
v := *o
64+
for _, e := range edit {
65+
e(&v)
66+
}
67+
return &v
68+
}
69+
5770
// applySorts sort an issues-related session based on the provided
5871
// sortType string
5972
func applySorts(sess *xorm.Session, sortType string, priorityRepoID int64) {

models/issues/review.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func (r *Review) TooltipContent() string {
247247
}
248248
return "repo.issues.review.official"
249249
case ReviewTypeComment:
250-
return "repo.issues.review.comment"
250+
return "repo.issues.review.commented"
251251
case ReviewTypeReject:
252252
return "repo.issues.review.rejected"
253253
case ReviewTypeRequest:

models/organization/org_user.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99

1010
"code.gitea.io/gitea/models/db"
1111
"code.gitea.io/gitea/models/perm"
12+
"code.gitea.io/gitea/models/unit"
1213
user_model "code.gitea.io/gitea/models/user"
14+
"code.gitea.io/gitea/modules/container"
1315
"code.gitea.io/gitea/modules/log"
1416

1517
"xorm.io/builder"
@@ -112,6 +114,49 @@ func IsUserOrgOwner(ctx context.Context, users user_model.UserList, orgID int64)
112114
return results
113115
}
114116

117+
// GetOrgAssignees returns all users that have write access and can be assigned to issues
118+
// of the any repository in the organization.
119+
func GetOrgAssignees(ctx context.Context, orgID int64) (_ []*user_model.User, err error) {
120+
e := db.GetEngine(ctx)
121+
userIDs := make([]int64, 0, 10)
122+
if err = e.Table("access").
123+
Join("INNER", "repository", "`repository`.id = `access`.repo_id").
124+
Where("`repository`.owner_id = ? AND `access`.mode >= ?", orgID, perm.AccessModeWrite).
125+
Select("user_id").
126+
Find(&userIDs); err != nil {
127+
return nil, err
128+
}
129+
130+
additionalUserIDs := make([]int64, 0, 10)
131+
if err = e.Table("team_user").
132+
Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
133+
Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
134+
Join("INNER", "repository", "`repository`.id = `team_repo`.repo_id").
135+
Where("`repository`.owner_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
136+
orgID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
137+
Distinct("`team_user`.uid").
138+
Select("`team_user`.uid").
139+
Find(&additionalUserIDs); err != nil {
140+
return nil, err
141+
}
142+
143+
uniqueUserIDs := make(container.Set[int64])
144+
uniqueUserIDs.AddMultiple(userIDs...)
145+
uniqueUserIDs.AddMultiple(additionalUserIDs...)
146+
147+
users := make([]*user_model.User, 0, len(uniqueUserIDs))
148+
if len(userIDs) > 0 {
149+
if err = e.In("id", uniqueUserIDs.Values()).
150+
Where(builder.Eq{"`user`.is_active": true}).
151+
OrderBy(user_model.GetOrderByName()).
152+
Find(&users); err != nil {
153+
return nil, err
154+
}
155+
}
156+
157+
return users, nil
158+
}
159+
115160
func loadOrganizationOwners(ctx context.Context, users user_model.UserList, orgID int64) (map[int64]*TeamUser, error) {
116161
if len(users) == 0 {
117162
return nil, nil

models/repo/release.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ type FindReleasesOptions struct {
234234
IsDraft optional.Option[bool]
235235
TagNames []string
236236
HasSha1 optional.Option[bool] // useful to find draft releases which are created with existing tags
237+
NamePattern optional.Option[string]
237238
}
238239

239240
func (opts FindReleasesOptions) ToConds() builder.Cond {
@@ -261,6 +262,11 @@ func (opts FindReleasesOptions) ToConds() builder.Cond {
261262
cond = cond.And(builder.Eq{"sha1": ""})
262263
}
263264
}
265+
266+
if opts.NamePattern.Has() && opts.NamePattern.Value() != "" {
267+
cond = cond.And(builder.Like{"lower_tag_name", strings.ToLower(opts.NamePattern.Value())})
268+
}
269+
264270
return cond
265271
}
266272

modules/httplib/url.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ func getRequestScheme(req *http.Request) string {
5252
return ""
5353
}
5454

55-
func getForwardedHost(req *http.Request) string {
56-
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
57-
return req.Header.Get("X-Forwarded-Host")
58-
}
59-
6055
// GuessCurrentAppURL tries to guess the current full app URL (with sub-path) by http headers. It always has a '/' suffix, exactly the same as setting.AppURL
6156
func GuessCurrentAppURL(ctx context.Context) string {
6257
return GuessCurrentHostURL(ctx) + setting.AppSubURL + "/"
@@ -81,11 +76,9 @@ func GuessCurrentHostURL(ctx context.Context) string {
8176
if reqScheme == "" {
8277
return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
8378
}
84-
reqHost := getForwardedHost(req)
85-
if reqHost == "" {
86-
reqHost = req.Host
87-
}
88-
return reqScheme + "://" + reqHost
79+
// X-Forwarded-Host has many problems: non-standard, not well-defined (X-Forwarded-Port or not), conflicts with Host header.
80+
// So do not use X-Forwarded-Host, just use Host header directly.
81+
return reqScheme + "://" + req.Host
8982
}
9083

9184
// MakeAbsoluteURL tries to make a link to an absolute URL:

modules/httplib/url_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func TestMakeAbsoluteURL(t *testing.T) {
7070
"X-Forwarded-Proto": {"https"},
7171
},
7272
})
73-
assert.Equal(t, "https://forwarded-host/foo", MakeAbsoluteURL(ctx, "/foo"))
73+
assert.Equal(t, "https://user-host/foo", MakeAbsoluteURL(ctx, "/foo"))
7474
}
7575

7676
func TestIsCurrentGiteaSiteURL(t *testing.T) {
@@ -119,5 +119,6 @@ func TestIsCurrentGiteaSiteURL(t *testing.T) {
119119
},
120120
})
121121
assert.True(t, IsCurrentGiteaSiteURL(ctx, "http://localhost:3000"))
122-
assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host"))
122+
assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://user-host"))
123+
assert.False(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host"))
123124
}

modules/templates/util_avatar.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func AvatarHTML(src string, size int, class, name string) template.HTML {
3434
name = "avatar"
3535
}
3636

37-
return template.HTML(`<img class="` + class + `" src="` + src + `" title="` + html.EscapeString(name) + `" width="` + sizeStr + `" height="` + sizeStr + `"/>`)
37+
return template.HTML(`<img loading="lazy" class="` + class + `" src="` + src + `" title="` + html.EscapeString(name) + `" width="` + sizeStr + `" height="` + sizeStr + `"/>`)
3838
}
3939

4040
// Avatar renders user avatars. args: user, size (int), class (string)

0 commit comments

Comments
 (0)