Skip to content

Commit ab50a4d

Browse files
authored
Merge branch 'main' into navrework
2 parents 02ce207 + feda506 commit ab50a4d

File tree

16 files changed

+120
-60
lines changed

16 files changed

+120
-60
lines changed

.github/workflows/release-nightly.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ jobs:
5555
runs-on: ubuntu-latest
5656
steps:
5757
- uses: actions/checkout@v3
58+
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
59+
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
60+
- run: git fetch --unshallow --quiet --tags --force
5861
- uses: docker/setup-qemu-action@v2
5962
- uses: docker/setup-buildx-action@v2
6063
- name: Get cleaned branch name
@@ -75,12 +78,14 @@ jobs:
7578
- name: build rootful docker image
7679
uses: docker/build-push-action@v4
7780
with:
81+
context: .
7882
platforms: linux/amd64,linux/arm64
7983
push: true
8084
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}
8185
- name: build rootless docker image
8286
uses: docker/build-push-action@v4
8387
with:
88+
context: .
8489
platforms: linux/amd64,linux/arm64
8590
push: true
8691
file: Dockerfile.rootless

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ endif
7979
STORED_VERSION_FILE := VERSION
8080
HUGO_VERSION ?= 0.111.3
8181

82+
GITHUB_REF_TYPE ?= branch
83+
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
84+
8285
ifneq ($(GITHUB_REF_TYPE),branch)
8386
VERSION ?= $(subst v,,$(GITHUB_REF_NAME))
8487
GITEA_VERSION ?= $(GITHUB_REF_NAME)
@@ -1011,9 +1014,5 @@ docker:
10111014
docker build --disable-content-trust=false -t $(DOCKER_REF) .
10121015
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
10131016

1014-
.PHONY: docker-build
1015-
docker-build:
1016-
docker run -ti --rm -v "$(CURDIR):/srv/app/src/code.gitea.io/gitea" -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" CGO_EXTRA_CFLAGS="$(CGO_EXTRA_CFLAGS)" webhippie/golang:edge make clean build
1017-
10181017
# This endif closes the if at the top of the file
10191018
endif

models/issues/tracked_time.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ func addTime(ctx context.Context, user *user_model.User, issue *Issue, amount in
199199
return tt, db.Insert(ctx, tt)
200200
}
201201

202-
// TotalTimes returns the spent time for each user by an issue
203-
func TotalTimes(options *FindTrackedTimesOptions) (map[*user_model.User]string, error) {
202+
// TotalTimes returns the spent time in seconds for each user by an issue
203+
func TotalTimes(options *FindTrackedTimesOptions) (map[*user_model.User]int64, error) {
204204
trackedTimes, err := GetTrackedTimes(db.DefaultContext, options)
205205
if err != nil {
206206
return nil, err
@@ -211,7 +211,7 @@ func TotalTimes(options *FindTrackedTimesOptions) (map[*user_model.User]string,
211211
totalTimesByUser[t.UserID] += t.Time
212212
}
213213

214-
totalTimes := make(map[*user_model.User]string)
214+
totalTimes := make(map[*user_model.User]int64)
215215
// Fetching User and making time human readable
216216
for userID, total := range totalTimesByUser {
217217
user, err := user_model.GetUserByID(db.DefaultContext, userID)
@@ -221,7 +221,7 @@ func TotalTimes(options *FindTrackedTimesOptions) (map[*user_model.User]string,
221221
}
222222
return nil, err
223223
}
224-
totalTimes[user] = util.SecToTime(total)
224+
totalTimes[user] = total
225225
}
226226
return totalTimes, nil
227227
}

models/issues/tracked_time_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,18 @@ func TestTotalTimes(t *testing.T) {
8686
assert.NoError(t, err)
8787
assert.Len(t, total, 1)
8888
for user, time := range total {
89-
assert.Equal(t, int64(1), user.ID)
90-
assert.Equal(t, "6 minutes 40 seconds", time)
89+
assert.EqualValues(t, 1, user.ID)
90+
assert.EqualValues(t, 400, time)
9191
}
9292

9393
total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 2})
9494
assert.NoError(t, err)
9595
assert.Len(t, total, 2)
9696
for user, time := range total {
9797
if user.ID == 2 {
98-
assert.Equal(t, "1 hour 1 minute", time)
98+
assert.EqualValues(t, 3662, time)
9999
} else if user.ID == 1 {
100-
assert.Equal(t, "20 seconds", time)
100+
assert.EqualValues(t, 20, time)
101101
} else {
102102
assert.Error(t, assert.AnError)
103103
}
@@ -107,8 +107,8 @@ func TestTotalTimes(t *testing.T) {
107107
assert.NoError(t, err)
108108
assert.Len(t, total, 1)
109109
for user, time := range total {
110-
assert.Equal(t, int64(2), user.ID)
111-
assert.Equal(t, "1 second", time)
110+
assert.EqualValues(t, 2, user.ID)
111+
assert.EqualValues(t, 1, time)
112112
}
113113

114114
total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 4})

routers/api/actions/runner/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct {
119119
"head_ref": headRef, // string, The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target.
120120
"job": fmt.Sprint(t.JobID), // string, The job_id of the current job.
121121
"ref": t.Job.Run.Ref, // string, The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/<branch_name>, for pull requests it is refs/pull/<pr_number>/merge, and for tags it is refs/tags/<tag_name>. For example, refs/heads/feature-branch-1.
122-
"ref_name": refName.String(), // string, The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature-branch-1.
122+
"ref_name": refName.ShortName(), // string, The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature-branch-1.
123123
"ref_protected": false, // boolean, true if branch protections are configured for the ref that triggered the workflow run.
124124
"ref_type": refName.RefType(), // string, The type of ref that triggered the workflow run. Valid values are branch or tag.
125125
"path": "", // string, Path on the runner to the file that sets system PATH variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions."

services/auth/source/ldap/source_sync.go

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package ldap
66
import (
77
"context"
88
"fmt"
9-
"sort"
109
"strings"
1110

1211
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -24,7 +23,6 @@ import (
2423
func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
2524
log.Trace("Doing: SyncExternalUsers[%s]", source.authSource.Name)
2625

27-
var existingUsers []int
2826
isAttributeSSHPublicKeySet := len(strings.TrimSpace(source.AttributeSSHPublicKey)) > 0
2927
var sshKeysNeedUpdate bool
3028

@@ -41,9 +39,14 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
4139
default:
4240
}
4341

44-
sort.Slice(users, func(i, j int) bool {
45-
return users[i].LowerName < users[j].LowerName
46-
})
42+
usernameUsers := make(map[string]*user_model.User, len(users))
43+
mailUsers := make(map[string]*user_model.User, len(users))
44+
keepActiveUsers := make(map[int64]struct{})
45+
46+
for _, u := range users {
47+
usernameUsers[u.LowerName] = u
48+
mailUsers[strings.ToLower(u.Email)] = u
49+
}
4750

4851
sr, err := source.SearchEntries()
4952
if err != nil {
@@ -59,11 +62,6 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
5962
log.Warn("LDAP search found no entries but did not report an error. All users will be deactivated as per settings")
6063
}
6164

62-
sort.Slice(sr, func(i, j int) bool {
63-
return sr[i].LowerName < sr[j].LowerName
64-
})
65-
66-
userPos := 0
6765
orgCache := make(map[string]*organization.Organization)
6866
teamCache := make(map[string]*organization.Team)
6967

@@ -86,21 +84,27 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
8684
return db.ErrCancelledf("During update of %s before completed update of users", source.authSource.Name)
8785
default:
8886
}
89-
if len(su.Username) == 0 {
87+
if len(su.Username) == 0 && len(su.Mail) == 0 {
9088
continue
9189
}
9290

93-
if len(su.Mail) == 0 {
94-
su.Mail = fmt.Sprintf("%s@localhost", su.Username)
91+
var usr *user_model.User
92+
if len(su.Username) > 0 {
93+
usr = usernameUsers[su.LowerName]
94+
}
95+
if usr == nil && len(su.Mail) > 0 {
96+
usr = mailUsers[strings.ToLower(su.Mail)]
9597
}
9698

97-
var usr *user_model.User
98-
for userPos < len(users) && users[userPos].LowerName < su.LowerName {
99-
userPos++
99+
if usr != nil {
100+
keepActiveUsers[usr.ID] = struct{}{}
101+
} else if len(su.Username) == 0 {
102+
// we cannot create the user if su.Username is empty
103+
continue
100104
}
101-
if userPos < len(users) && users[userPos].LowerName == su.LowerName {
102-
usr = users[userPos]
103-
existingUsers = append(existingUsers, userPos)
105+
106+
if len(su.Mail) == 0 {
107+
su.Mail = fmt.Sprintf("%s@localhost", su.Username)
104108
}
105109

106110
fullName := composeFullName(su.Name, su.Surname, su.Username)
@@ -203,19 +207,17 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
203207

204208
// Deactivate users not present in LDAP
205209
if updateExisting {
206-
existPos := 0
207-
for i, usr := range users {
208-
for existPos < len(existingUsers) && i > existingUsers[existPos] {
209-
existPos++
210+
for _, usr := range users {
211+
if _, ok := keepActiveUsers[usr.ID]; ok {
212+
continue
210213
}
211-
if usr.IsActive && (existPos >= len(existingUsers) || i < existingUsers[existPos]) {
212-
log.Trace("SyncExternalUsers[%s]: Deactivating user %s", source.authSource.Name, usr.Name)
213214

214-
usr.IsActive = false
215-
err = user_model.UpdateUserCols(ctx, usr, "is_active")
216-
if err != nil {
217-
log.Error("SyncExternalUsers[%s]: Error deactivating user %s: %v", source.authSource.Name, usr.Name, err)
218-
}
215+
log.Trace("SyncExternalUsers[%s]: Deactivating user %s", source.authSource.Name, usr.Name)
216+
217+
usr.IsActive = false
218+
err = user_model.UpdateUserCols(ctx, usr, "is_active")
219+
if err != nil {
220+
log.Error("SyncExternalUsers[%s]: Error deactivating user %s: %v", source.authSource.Name, usr.Name, err)
219221
}
220222
}
221223
}

templates/base/head_script.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
1717
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
1818
enableTimeTracking: {{EnableTimetracking}},
1919
{{if or .Participants .Assignees .MentionableTeams}}
20-
tributeValues: Array.from(new Map([
20+
mentionValues: Array.from(new Map([
2121
{{- range .Participants -}}
2222
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}],
2323
{{- end -}}

templates/repo/issue/list.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
{{template "repo/issue/openclose" .}}
9090
</div>
9191
<div class="issue-list-toolbar-right">
92-
<div class="ui secondary filter stackable menu labels">
92+
<div class="ui secondary filter menu labels">
9393
<!-- Label -->
9494
<div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item label-filter">
9595
<span class="text">
@@ -278,7 +278,7 @@
278278
{{template "repo/issue/openclose" .}}
279279
</div>
280280
<div class="issue-list-toolbar-right">
281-
<div class="ui secondary filter stackable menu">
281+
<div class="ui secondary filter menu">
282282
{{if not .Repository.IsArchived}}
283283
<!-- Action Button -->
284284
{{if .IsShowClosed}}

templates/repo/issue/view_content/sidebar.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@
340340
<div class="content">
341341
{{template "shared/user/authorlink" $user}}
342342
<div class="text">
343-
{{$trackedtime}}
343+
{{$trackedtime|Sec2Time}}
344344
</div>
345345
</div>
346346
</div>

tests/integration/auth_ldap_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,57 @@ func TestLDAPUserSync(t *testing.T) {
268268
}
269269
}
270270

271+
func TestLDAPUserSyncWithEmptyUsernameAttribute(t *testing.T) {
272+
if skipLDAPTests() {
273+
t.Skip()
274+
return
275+
}
276+
defer tests.PrepareTestEnv(t)()
277+
278+
session := loginUser(t, "user1")
279+
csrf := GetCSRF(t, session, "/admin/auths/new")
280+
payload := buildAuthSourceLDAPPayload(csrf, "", "", "", "")
281+
payload["attribute_username"] = ""
282+
req := NewRequestWithValues(t, "POST", "/admin/auths/new", payload)
283+
session.MakeRequest(t, req, http.StatusSeeOther)
284+
285+
for _, u := range gitLDAPUsers {
286+
req := NewRequest(t, "GET", "/admin/users?q="+u.UserName)
287+
resp := session.MakeRequest(t, req, http.StatusOK)
288+
289+
htmlDoc := NewHTMLParser(t, resp.Body)
290+
291+
tr := htmlDoc.doc.Find("table.table tbody tr")
292+
assert.True(t, tr.Length() == 0)
293+
}
294+
295+
for _, u := range gitLDAPUsers {
296+
req := NewRequestWithValues(t, "POST", "/user/login", map[string]string{
297+
"_csrf": csrf,
298+
"user_name": u.UserName,
299+
"password": u.Password,
300+
})
301+
MakeRequest(t, req, http.StatusSeeOther)
302+
}
303+
304+
auth.SyncExternalUsers(context.Background(), true)
305+
306+
authSource := unittest.AssertExistsAndLoadBean(t, &auth_model.Source{
307+
Name: payload["name"],
308+
})
309+
unittest.AssertCount(t, &user_model.User{
310+
LoginType: auth_model.LDAP,
311+
LoginSource: authSource.ID,
312+
}, len(gitLDAPUsers))
313+
314+
for _, u := range gitLDAPUsers {
315+
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{
316+
Name: u.UserName,
317+
})
318+
assert.True(t, user.IsActive)
319+
}
320+
}
321+
271322
func TestLDAPUserSyncWithGroupFilter(t *testing.T) {
272323
if skipLDAPTests() {
273324
t.Skip()

web_src/css/repo/issue-list.css

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.issue-list-toolbar {
22
display: flex;
33
flex-wrap: wrap;
4+
justify-content: space-between;
45
align-items: flex-start;
56
gap: 1rem;
67
margin-top: 1rem;
@@ -10,17 +11,19 @@
1011
display: flex;
1112
}
1213

13-
.issue-list-toolbar-right {
14-
margin-left: auto;
14+
.issue-list-toolbar-right .filter.menu {
15+
flex-direction: row;
16+
flex-wrap: wrap;
17+
gap: 8px;
1518
}
1619

1720
@media (max-width: 767.98px) {
1821
.issue-list-toolbar {
1922
flex-direction: column-reverse;
2023
}
21-
.issue-list-toolbar-right {
22-
margin-right: auto;
23-
width: 100%;
24+
.issue-list-toolbar-right .dropdown .menu {
25+
left: auto !important;
26+
right: auto !important;
2427
}
2528
.issue-list-navbar {
2629
order: 0;

web_src/js/features/repo-issue.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export function initRepoIssueSidebarList() {
149149
}
150150
}
151151
});
152-
$('.ui.dropdown.label-filter').dropdown('setting', {'hideDividers': 'empty'}).dropdown('refreshItems');
152+
$('.ui.dropdown.label-filter, .ui.dropdown.select-label').dropdown('setting', {'hideDividers': 'empty'}).dropdown('refreshItems');
153153
}
154154

155155
export function initRepoIssueCommentDelete() {

web_src/js/features/tribute.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function makeCollections({mentions, emoji}) {
3131

3232
if (mentions) {
3333
collections.push({
34-
values: window.config.tributeValues,
34+
values: window.config.mentionValues,
3535
requireLeadingSpace: true,
3636
menuItemTemplate: (item) => {
3737
return `

web_src/js/test/setup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ window.config = {
33
pageData: {},
44
i18n: {},
55
appSubUrl: '',
6-
tributeValues: [
6+
mentionValues: [
77
{key: 'user1 User 1', value: 'user1', name: 'user1', fullname: 'User 1', avatar: 'https://avatar1.com'},
88
{key: 'user2 User 2', value: 'user2', name: 'user2', fullname: 'User 2', avatar: 'https://avatar2.com'},
99
{key: 'user3 User 3', value: 'user3', name: 'user3', fullname: 'User 3', avatar: 'https://avatar3.com'},

web_src/js/utils/match.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function matchMention(queryText) {
3232

3333
// results is a map of weights, lower is better
3434
const results = new Map();
35-
for (const obj of window.config.tributeValues) {
35+
for (const obj of window.config.mentionValues) {
3636
const index = obj.key.toLowerCase().indexOf(query);
3737
if (index === -1) continue;
3838
const existing = results.get(obj);

0 commit comments

Comments
 (0)