Skip to content

Commit 0ee8e03

Browse files
committed
Merge branch 'main' into add_option_bot
2 parents 07e6c68 + 943cc4f commit 0ee8e03

File tree

116 files changed

+1585
-539
lines changed

Some content is hidden

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

116 files changed

+1585
-539
lines changed

.changelog.yml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,25 @@ groups:
2222
name: FEATURES
2323
labels:
2424
- type/feature
25-
-
26-
name: API
27-
labels:
28-
- modifies/api
2925
-
3026
name: ENHANCEMENTS
3127
labels:
3228
- type/enhancement
33-
- type/refactoring
34-
- topic/ui
29+
-
30+
name: PERFORMANCE
31+
labels:
32+
- performance/memory
33+
- performance/speed
34+
- performance/bigrepo
35+
- performance/cpu
3536
-
3637
name: BUGFIXES
3738
labels:
3839
- type/bug
40+
-
41+
name: API
42+
labels:
43+
- modifies/api
3944
-
4045
name: TESTING
4146
labels:

.github/workflows/cron-licenses.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: cron-licenses
22

33
on:
4-
schedule:
5-
- cron: "7 0 * * 1" # every Monday at 00:07 UTC
4+
#schedule:
5+
# - cron: "7 0 * * 1" # every Monday at 00:07 UTC
66
workflow_dispatch:
77

88
jobs:

main_timezones.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
//go:build windows
5+
6+
package main
7+
8+
// Golang has the ability to load OS's timezone data from most UNIX systems (https://github.com/golang/go/blob/master/src/time/zoneinfo_unix.go)
9+
// Even if the timezone data is missing, users could install the related packages to get it.
10+
// But on Windows, although `zoneinfo_windows.go` tries to load the timezone data from Windows registry,
11+
// some users still suffer from the issue that the timezone data is missing: https://github.com/go-gitea/gitea/issues/33235
12+
// So we import the tzdata package to make sure the timezone data is included in the binary.
13+
//
14+
// For non-Windows package builders, they could still use the "TAGS=timetzdata" to include the tzdata package in the binary.
15+
// If we decided to add the tzdata for other platforms, modify the "go:build" directive above.
16+
import _ "time/tzdata"

models/issues/issue_project.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ func (issue *Issue) projectID(ctx context.Context) int64 {
3838
}
3939

4040
// ProjectColumnID return project column id if issue was assigned to one
41-
func (issue *Issue) ProjectColumnID(ctx context.Context) int64 {
41+
func (issue *Issue) ProjectColumnID(ctx context.Context) (int64, error) {
4242
var ip project_model.ProjectIssue
4343
has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
44-
if err != nil || !has {
45-
return 0
44+
if err != nil {
45+
return 0, err
46+
} else if !has {
47+
return 0, nil
4648
}
47-
return ip.ProjectColumnID
49+
return ip.ProjectColumnID, nil
4850
}
4951

5052
// LoadIssuesFromColumn load issues assigned to this column

models/issues/issue_stats.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func GetIssueStats(ctx context.Context, opts *IssuesOptions) (*IssueStats, error
107107
accum.YourRepositoriesCount += stats.YourRepositoriesCount
108108
accum.AssignCount += stats.AssignCount
109109
accum.CreateCount += stats.CreateCount
110-
accum.OpenCount += stats.MentionCount
110+
accum.MentionCount += stats.MentionCount
111111
accum.ReviewRequestedCount += stats.ReviewRequestedCount
112112
accum.ReviewedCount += stats.ReviewedCount
113113
i = chunk
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package organization
5+
6+
import (
7+
"sort"
8+
9+
"code.gitea.io/gitea/models/db"
10+
11+
"xorm.io/builder"
12+
)
13+
14+
type WorktimeSumByRepos struct {
15+
RepoName string
16+
SumTime int64
17+
}
18+
19+
func GetWorktimeByRepos(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByRepos, err error) {
20+
err = db.GetEngine(db.DefaultContext).
21+
Select("repository.name AS repo_name, SUM(tracked_time.time) AS sum_time").
22+
Table("tracked_time").
23+
Join("INNER", "issue", "tracked_time.issue_id = issue.id").
24+
Join("INNER", "repository", "issue.repo_id = repository.id").
25+
Where(builder.Eq{"repository.owner_id": org.ID}).
26+
And(builder.Eq{"tracked_time.deleted": false}).
27+
And(builder.Gte{"tracked_time.created_unix": unitFrom}).
28+
And(builder.Lte{"tracked_time.created_unix": unixTo}).
29+
GroupBy("repository.name").
30+
OrderBy("repository.name").
31+
Find(&results)
32+
return results, err
33+
}
34+
35+
type WorktimeSumByMilestones struct {
36+
RepoName string
37+
MilestoneName string
38+
MilestoneID int64
39+
MilestoneDeadline int64
40+
SumTime int64
41+
HideRepoName bool
42+
}
43+
44+
func GetWorktimeByMilestones(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMilestones, err error) {
45+
err = db.GetEngine(db.DefaultContext).
46+
Select("repository.name AS repo_name, milestone.name AS milestone_name, milestone.id AS milestone_id, milestone.deadline_unix as milestone_deadline, SUM(tracked_time.time) AS sum_time").
47+
Table("tracked_time").
48+
Join("INNER", "issue", "tracked_time.issue_id = issue.id").
49+
Join("INNER", "repository", "issue.repo_id = repository.id").
50+
Join("LEFT", "milestone", "issue.milestone_id = milestone.id").
51+
Where(builder.Eq{"repository.owner_id": org.ID}).
52+
And(builder.Eq{"tracked_time.deleted": false}).
53+
And(builder.Gte{"tracked_time.created_unix": unitFrom}).
54+
And(builder.Lte{"tracked_time.created_unix": unixTo}).
55+
GroupBy("repository.name, milestone.name, milestone.deadline_unix, milestone.id").
56+
OrderBy("repository.name, milestone.deadline_unix, milestone.id").
57+
Find(&results)
58+
59+
// TODO: pgsql: NULL values are sorted last in default ascending order, so we need to sort them manually again.
60+
sort.Slice(results, func(i, j int) bool {
61+
if results[i].RepoName != results[j].RepoName {
62+
return results[i].RepoName < results[j].RepoName
63+
}
64+
if results[i].MilestoneDeadline != results[j].MilestoneDeadline {
65+
return results[i].MilestoneDeadline < results[j].MilestoneDeadline
66+
}
67+
return results[i].MilestoneID < results[j].MilestoneID
68+
})
69+
70+
// Show only the first RepoName, for nicer output.
71+
prevRepoName := ""
72+
for i := 0; i < len(results); i++ {
73+
res := &results[i]
74+
res.MilestoneDeadline = 0 // clear the deadline because we do not really need it
75+
if prevRepoName == res.RepoName {
76+
res.HideRepoName = true
77+
}
78+
prevRepoName = res.RepoName
79+
}
80+
return results, err
81+
}
82+
83+
type WorktimeSumByMembers struct {
84+
UserName string
85+
SumTime int64
86+
}
87+
88+
func GetWorktimeByMembers(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMembers, err error) {
89+
err = db.GetEngine(db.DefaultContext).
90+
Select("`user`.name AS user_name, SUM(tracked_time.time) AS sum_time").
91+
Table("tracked_time").
92+
Join("INNER", "issue", "tracked_time.issue_id = issue.id").
93+
Join("INNER", "repository", "issue.repo_id = repository.id").
94+
Join("INNER", "`user`", "tracked_time.user_id = `user`.id").
95+
Where(builder.Eq{"repository.owner_id": org.ID}).
96+
And(builder.Eq{"tracked_time.deleted": false}).
97+
And(builder.Gte{"tracked_time.created_unix": unitFrom}).
98+
And(builder.Lte{"tracked_time.created_unix": unixTo}).
99+
GroupBy("`user`.name").
100+
OrderBy("sum_time DESC").
101+
Find(&results)
102+
return results, err
103+
}

models/project/project.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ func GetSearchOrderByBySortType(sortType string) db.SearchOrderBy {
244244
return db.SearchOrderByRecentUpdated
245245
case "leastupdate":
246246
return db.SearchOrderByLeastUpdated
247+
case "alphabetically":
248+
return "title ASC"
249+
case "reversealphabetically":
250+
return "title DESC"
247251
default:
248252
return db.SearchOrderByNewest
249253
}

models/system/notice_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ func TestCreateRepositoryNotice(t *testing.T) {
4545
unittest.AssertExistsAndLoadBean(t, noticeBean)
4646
}
4747

48-
// TODO TestRemoveAllWithNotice
49-
5048
func TestCountNotices(t *testing.T) {
5149
assert.NoError(t, unittest.PrepareTestDatabase())
5250
assert.Equal(t, int64(3), system.CountNotices(db.DefaultContext))

modules/base/tool.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"time"
1919

2020
"code.gitea.io/gitea/modules/git"
21-
"code.gitea.io/gitea/modules/log"
2221
"code.gitea.io/gitea/modules/setting"
2322
"code.gitea.io/gitea/modules/util"
2423

@@ -64,10 +63,7 @@ func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) b
6463
// check code
6564
retCode := CreateTimeLimitCode(data, aliveTime, startTimeStr, nil)
6665
if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 {
67-
retCode = CreateTimeLimitCode(data, aliveTime, startTimeStr, sha1.New()) // TODO: this is only for the support of legacy codes, remove this in/after 1.23
68-
if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 {
69-
return false
70-
}
66+
return false
7167
}
7268

7369
// check time is expired or not: startTime <= now && now < startTime + minutes
@@ -144,13 +140,12 @@ func Int64sToStrings(ints []int64) []string {
144140
return strs
145141
}
146142

147-
// EntryIcon returns the octicon class for displaying files/directories
143+
// EntryIcon returns the octicon name for displaying files/directories
148144
func EntryIcon(entry *git.TreeEntry) string {
149145
switch {
150146
case entry.IsLink():
151147
te, err := entry.FollowLink()
152148
if err != nil {
153-
log.Debug(err.Error())
154149
return "file-symlink-file"
155150
}
156151
if te.IsDir() {

modules/base/tool_test.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,10 @@ JWT_SECRET = %s
8686
verifyDataCode := func(c string) bool {
8787
return VerifyTimeLimitCode(now, "data", 2, c)
8888
}
89-
code1 := CreateTimeLimitCode("data", 2, now, sha1.New())
90-
code2 := CreateTimeLimitCode("data", 2, now, nil)
91-
assert.True(t, verifyDataCode(code1))
92-
assert.True(t, verifyDataCode(code2))
89+
code := CreateTimeLimitCode("data", 2, now, nil)
90+
assert.True(t, verifyDataCode(code))
9391
initGeneralSecret("000_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko")
94-
assert.False(t, verifyDataCode(code1))
95-
assert.False(t, verifyDataCode(code2))
92+
assert.False(t, verifyDataCode(code))
9693
})
9794
}
9895

@@ -137,5 +134,3 @@ func TestInt64sToStrings(t *testing.T) {
137134
Int64sToStrings([]int64{1, 4, 16, 64, 256}),
138135
)
139136
}
140-
141-
// TODO: Test EntryIcon

0 commit comments

Comments
 (0)