Skip to content

Commit a31e6c5

Browse files
committed
Merge branch 'main' into rb/submodule-diff
2 parents ae53bc7 + 34dfc25 commit a31e6c5

Some content is hidden

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

85 files changed

+979
-784
lines changed

custom/conf/app.example.ini

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ RUN_USER = ; git
7878
;; Set the domain for the server
7979
;DOMAIN = localhost
8080
;;
81-
;; Overwrite the automatically generated public URL. Necessary for proxies and docker.
82-
;ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
81+
;; The AppURL used by Gitea to generate absolute links, defaults to "{PROTOCOL}://{DOMAIN}:{HTTP_PORT}/".
82+
;; Most users should set it to the real website URL of their Gitea instance.
83+
;ROOT_URL =
8384
;;
8485
;; For development purpose only. It makes Gitea handle sub-path ("/sub-path/owner/repo/...") directly when debugging without a reverse proxy.
8586
;; DO NOT USE IT IN PRODUCTION!!!
@@ -103,8 +104,8 @@ RUN_USER = ; git
103104
;REDIRECT_OTHER_PORT = false
104105
;PORT_TO_REDIRECT = 80
105106
;;
106-
;; expect PROXY protocol header on connections to https redirector.
107-
;REDIRECTOR_USE_PROXY_PROTOCOL = %(USE_PROXY_PROTOCOL)s
107+
;; expect PROXY protocol header on connections to https redirector, defaults to USE_PROXY_PROTOCOL
108+
;REDIRECTOR_USE_PROXY_PROTOCOL =
108109
;; Minimum and maximum supported TLS versions
109110
;SSL_MIN_VERSION=TLSv1.2
110111
;SSL_MAX_VERSION=
@@ -128,13 +129,14 @@ RUN_USER = ; git
128129
;; most cases you do not need to change the default value. Alter it only if
129130
;; your SSH server node is not the same as HTTP node. For different protocol, the default
130131
;; values are different. If `PROTOCOL` is `http+unix`, the default value is `http://unix/`.
131-
;; If `PROTOCOL` is `fcgi` or `fcgi+unix`, the default value is `%(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/`.
132-
;; If listen on `0.0.0.0`, the default value is `%(PROTOCOL)s://localhost:%(HTTP_PORT)s/`, Otherwise the default
133-
;; value is `%(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/`.
134-
;LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
132+
;; If `PROTOCOL` is `fcgi` or `fcgi+unix`, the default value is `{PROTOCOL}://{HTTP_ADDR}:{HTTP_PORT}/`.
133+
;; If listen on `0.0.0.0`, the default value is `{PROTOCOL}://localhost:{HTTP_PORT}/`.
134+
;; Otherwise the default value is `{PROTOCOL}://{HTTP_ADDR}:{HTTP_PORT}/`.
135+
;; Most users don't need (and shouldn't) set this value.
136+
;LOCAL_ROOT_URL =
135137
;;
136-
;; When making local connections pass the PROXY protocol header.
137-
;LOCAL_USE_PROXY_PROTOCOL = %(USE_PROXY_PROTOCOL)s
138+
;; When making local connections pass the PROXY protocol header, defaults to USE_PROXY_PROTOCOL
139+
;LOCAL_USE_PROXY_PROTOCOL =
138140
;;
139141
;; Disable SSH feature when not available
140142
;DISABLE_SSH = false
@@ -146,22 +148,26 @@ RUN_USER = ; git
146148
;SSH_SERVER_USE_PROXY_PROTOCOL = false
147149
;;
148150
;; Username to use for the builtin SSH server. If blank, then it is the value of RUN_USER.
149-
;BUILTIN_SSH_SERVER_USER = %(RUN_USER)s
151+
;BUILTIN_SSH_SERVER_USER =
150152
;;
151-
;; Domain name to be exposed in clone URL
152-
;SSH_DOMAIN = %(DOMAIN)s
153+
;; Domain name to be exposed in clone URL, defaults to DOMAIN or the domain part of ROOT_URL
154+
;SSH_DOMAIN =
153155
;;
154-
;; SSH username displayed in clone URLs.
155-
;SSH_USER = %(BUILTIN_SSH_SERVER_USER)s
156+
;; SSH username displayed in clone URLs. It defaults to BUILTIN_SSH_SERVER_USER or RUN_USER.
157+
;; If it is set to "(DOER_USERNAME)", it will use current signed-in user's username.
158+
;; This option is only for some advanced users who have configured their SSH reverse-proxy
159+
;; and need to use different usernames for git SSH clone.
160+
;; Most users should just leave it blank.
161+
;SSH_USER =
156162
;;
157163
;; The network interface the builtin SSH server should listen on
158164
;SSH_LISTEN_HOST =
159165
;;
160166
;; Port number to be exposed in clone URL
161167
;SSH_PORT = 22
162168
;;
163-
;; The port number the builtin SSH server should listen on
164-
;SSH_LISTEN_PORT = %(SSH_PORT)s
169+
;; The port number the builtin SSH server should listen on, defaults to SSH_PORT
170+
;SSH_LISTEN_PORT =
165171
;;
166172
;; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
167173
;SSH_ROOT_PATH =
@@ -188,7 +194,7 @@ RUN_USER = ; git
188194
;;
189195
;; For the built-in SSH server, choose the keypair to offer as the host key
190196
;; The private key should be at SSH_SERVER_HOST_KEY and the public SSH_SERVER_HOST_KEY.pub
191-
;; relative paths are made absolute relative to the %(APP_DATA_PATH)s
197+
;; relative paths are made absolute relative to the APP_DATA_PATH
192198
;SSH_SERVER_HOST_KEYS=ssh/gitea.rsa, ssh/gogs.rsa
193199
;;
194200
;; Directory to create temporary files in when testing public keys using ssh-keygen,
@@ -582,7 +588,7 @@ ENABLED = true
582588
[log]
583589
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
584590
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
585-
;; Root path for the log files - defaults to %(GITEA_WORK_DIR)/log
591+
;; Root path for the log files - defaults to "{AppWorkPath}/log"
586592
;ROOT_PATH =
587593
;;
588594
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -682,8 +688,8 @@ LEVEL = Info
682688
;; The path of git executable. If empty, Gitea searches through the PATH environment.
683689
;PATH =
684690
;;
685-
;; The HOME directory for Git
686-
;HOME_PATH = %(APP_DATA_PATH)s/home
691+
;; The HOME directory for Git, defaults to "{APP_DATA_PATH}/home"
692+
;HOME_PATH =
687693
;;
688694
;; Disables highlight of added and removed changes
689695
;DISABLE_DIFF_HIGHLIGHT = false
@@ -946,8 +952,8 @@ LEVEL = Info
946952
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
947953
;[repository]
948954
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
949-
;; Root path for storing all repository data. By default, it is set to %(APP_DATA_PATH)s/gitea-repositories.
950-
;; A relative path is interpreted as _`AppWorkPath`_/%(ROOT)s
955+
;; Root path for storing all repository data. By default, it is set to "{APP_DATA_PATH}/gitea-repositories".
956+
;; A relative path is interpreted as "{AppWorkPath}/{ROOT}" (use AppWorkPath as base path).
951957
;ROOT =
952958
;;
953959
;; The script type this server supports. Usually this is `bash`, but some users report that only `sh` is available.
@@ -1506,7 +1512,8 @@ LEVEL = Info
15061512
;TYPE = persistable-channel
15071513
;;
15081514
;; data-dir for storing persistable queues and level queues, individual queues will default to `queues/common` meaning the queue is shared.
1509-
;DATADIR = queues/ ; Relative paths will be made absolute against `%(APP_DATA_PATH)s`.
1515+
;; Relative paths will be made absolute against "APP_DATA_PATH"
1516+
;DATADIR = queues/
15101517
;;
15111518
;; Default queue length before a channel queue will block
15121519
;LENGTH = 100000

go.mod

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ require (
7171
github.com/google/uuid v1.6.0
7272
github.com/gorilla/feeds v1.2.0
7373
github.com/gorilla/sessions v1.4.0
74-
github.com/h2non/gock v1.2.0
7574
github.com/hashicorp/go-version v1.7.0
7675
github.com/hashicorp/golang-lru/v2 v2.0.7
7776
github.com/huandu/xstrings v1.5.0
@@ -230,7 +229,6 @@ require (
230229
github.com/gorilla/handlers v1.5.2 // indirect
231230
github.com/gorilla/mux v1.8.1 // indirect
232231
github.com/gorilla/securecookie v1.1.2 // indirect
233-
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
234232
github.com/hashicorp/errwrap v1.1.0 // indirect
235233
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
236234
github.com/hashicorp/go-multierror v1.1.1 // indirect

go.sum

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,6 @@ github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z
452452
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
453453
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
454454
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
455-
github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
456-
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
457-
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
458-
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
459455
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
460456
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
461457
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -599,8 +595,6 @@ github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
599595
github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0=
600596
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
601597
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
602-
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
603-
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
604598
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
605599
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
606600
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=

models/issues/pull.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func (pr *PullRequest) LoadRequestedReviewers(ctx context.Context) error {
301301
return nil
302302
}
303303

304-
reviews, err := GetReviewsByIssueID(ctx, pr.Issue.ID)
304+
reviews, _, err := GetReviewsByIssueID(ctx, pr.Issue.ID)
305305
if err != nil {
306306
return err
307307
}
@@ -320,7 +320,7 @@ func (pr *PullRequest) LoadRequestedReviewers(ctx context.Context) error {
320320

321321
// LoadRequestedReviewersTeams loads the requested reviewers teams.
322322
func (pr *PullRequest) LoadRequestedReviewersTeams(ctx context.Context) error {
323-
reviews, err := GetReviewsByIssueID(ctx, pr.Issue.ID)
323+
reviews, _, err := GetReviewsByIssueID(ctx, pr.Issue.ID)
324324
if err != nil {
325325
return err
326326
}

models/issues/review_list.go

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package issues
55

66
import (
77
"context"
8+
"slices"
9+
"sort"
810

911
"code.gitea.io/gitea/models/db"
1012
organization_model "code.gitea.io/gitea/models/organization"
@@ -153,43 +155,60 @@ func CountReviews(ctx context.Context, opts FindReviewOptions) (int64, error) {
153155
return db.GetEngine(ctx).Where(opts.toCond()).Count(&Review{})
154156
}
155157

156-
// GetReviewersFromOriginalAuthorsByIssueID gets the latest review of each original authors for a pull request
157-
func GetReviewersFromOriginalAuthorsByIssueID(ctx context.Context, issueID int64) (ReviewList, error) {
158+
// GetReviewsByIssueID gets the latest review of each reviewer for a pull request
159+
// The first returned parameter is the latest review of each individual reviewer or team
160+
// The second returned parameter is the latest review of each original author which is migrated from other systems
161+
// The reviews are sorted by updated time
162+
func GetReviewsByIssueID(ctx context.Context, issueID int64) (latestReviews, migratedOriginalReviews ReviewList, err error) {
158163
reviews := make([]*Review, 0, 10)
159164

160-
// Get latest review of each reviewer, sorted in order they were made
161-
if err := db.GetEngine(ctx).SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND original_author_id <> 0 GROUP BY issue_id, original_author_id) ORDER BY review.updated_unix ASC",
162-
issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
163-
Find(&reviews); err != nil {
164-
return nil, err
165+
// Get all reviews for the issue id
166+
if err := db.GetEngine(ctx).Where("issue_id=?", issueID).OrderBy("updated_unix ASC").Find(&reviews); err != nil {
167+
return nil, nil, err
165168
}
166169

167-
return reviews, nil
168-
}
169-
170-
// GetReviewsByIssueID gets the latest review of each reviewer for a pull request
171-
func GetReviewsByIssueID(ctx context.Context, issueID int64) (ReviewList, error) {
172-
reviews := make([]*Review, 0, 10)
173-
174-
sess := db.GetEngine(ctx)
170+
// filter them in memory to get the latest review of each reviewer
171+
// Since the reviews should not be too many for one issue, less than 100 commonly, it's acceptable to do this in memory
172+
// And since there are too less indexes in review table, it will be very slow to filter in the database
173+
reviewersMap := make(map[int64][]*Review) // key is reviewer id
174+
originalReviewersMap := make(map[int64][]*Review) // key is original author id
175+
reviewTeamsMap := make(map[int64][]*Review) // key is reviewer team id
176+
countedReivewTypes := []ReviewType{ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest}
177+
for _, review := range reviews {
178+
if review.ReviewerTeamID == 0 && slices.Contains(countedReivewTypes, review.Type) && !review.Dismissed {
179+
if review.OriginalAuthorID != 0 {
180+
originalReviewersMap[review.OriginalAuthorID] = append(originalReviewersMap[review.OriginalAuthorID], review)
181+
} else {
182+
reviewersMap[review.ReviewerID] = append(reviewersMap[review.ReviewerID], review)
183+
}
184+
} else if review.ReviewerTeamID != 0 && review.OriginalAuthorID == 0 {
185+
reviewTeamsMap[review.ReviewerTeamID] = append(reviewTeamsMap[review.ReviewerTeamID], review)
186+
}
187+
}
175188

176-
// Get latest review of each reviewer, sorted in order they were made
177-
if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND dismissed = ? AND original_author_id = 0 GROUP BY issue_id, reviewer_id) ORDER BY review.updated_unix ASC",
178-
issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, false).
179-
Find(&reviews); err != nil {
180-
return nil, err
189+
individualReviews := make([]*Review, 0, 10)
190+
for _, reviews := range reviewersMap {
191+
individualReviews = append(individualReviews, reviews[len(reviews)-1])
181192
}
193+
sort.Slice(individualReviews, func(i, j int) bool {
194+
return individualReviews[i].UpdatedUnix < individualReviews[j].UpdatedUnix
195+
})
182196

183-
teamReviewRequests := make([]*Review, 0, 5)
184-
if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id <> 0 AND original_author_id = 0 GROUP BY issue_id, reviewer_team_id) ORDER BY review.updated_unix ASC",
185-
issueID).
186-
Find(&teamReviewRequests); err != nil {
187-
return nil, err
197+
originalReviews := make([]*Review, 0, 10)
198+
for _, reviews := range originalReviewersMap {
199+
originalReviews = append(originalReviews, reviews[len(reviews)-1])
188200
}
201+
sort.Slice(originalReviews, func(i, j int) bool {
202+
return originalReviews[i].UpdatedUnix < originalReviews[j].UpdatedUnix
203+
})
189204

190-
if len(teamReviewRequests) > 0 {
191-
reviews = append(reviews, teamReviewRequests...)
205+
teamReviewRequests := make([]*Review, 0, 5)
206+
for _, reviews := range reviewTeamsMap {
207+
teamReviewRequests = append(teamReviewRequests, reviews[len(reviews)-1])
192208
}
209+
sort.Slice(teamReviewRequests, func(i, j int) bool {
210+
return teamReviewRequests[i].UpdatedUnix < teamReviewRequests[j].UpdatedUnix
211+
})
193212

194-
return reviews, nil
213+
return append(individualReviews, teamReviewRequests...), originalReviews, nil
195214
}

models/issues/review_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ func TestGetReviewersByIssueID(t *testing.T) {
162162
},
163163
)
164164

165-
allReviews, err := issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID)
165+
allReviews, migratedReviews, err := issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID)
166166
assert.NoError(t, err)
167+
assert.Empty(t, migratedReviews)
167168
for _, review := range allReviews {
168169
assert.NoError(t, review.LoadReviewer(db.DefaultContext))
169170
}

models/migrations/v1_21/v276.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func getRemoteAddress(ownerName, repoName, remoteName string) (string, error) {
172172
return "", fmt.Errorf("get remote %s's address of %s/%s failed: %v", remoteName, ownerName, repoName, err)
173173
}
174174

175-
u, err := giturl.Parse(remoteURL)
175+
u, err := giturl.ParseGitURL(remoteURL)
176176
if err != nil {
177177
return "", err
178178
}

0 commit comments

Comments
 (0)