Skip to content

Commit 8af63b6

Browse files
committed
Merge branch 'develop' of ssh://github.com/rossigee/gitea into develop
2 parents 65d732c + 9fe483c commit 8af63b6

File tree

15 files changed

+645
-114
lines changed

15 files changed

+645
-114
lines changed

.github/workflows/release-nightly.yml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,6 @@ jobs:
7575
- name: Get cleaned branch name
7676
id: clean_name
7777
run: |
78-
# if main then say nightly otherwise cleanup name
79-
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
80-
echo "branch=nightly" >> "$GITHUB_OUTPUT"
81-
exit 0
82-
fi
8378
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
8479
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
8580
- name: Login to Docker Hub
@@ -122,11 +117,6 @@ jobs:
122117
- name: Get cleaned branch name
123118
id: clean_name
124119
run: |
125-
# if main then say nightly otherwise cleanup name
126-
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
127-
echo "branch=nightly" >> "$GITHUB_OUTPUT"
128-
exit 0
129-
fi
130120
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
131121
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
132122
- name: Login to Docker Hub

routers/api/v1/repo/issue_comment.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ func deleteIssueComment(ctx *context.APIContext) {
721721
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
722722
ctx.Status(http.StatusForbidden)
723723
return
724-
} else if comment.Type != issues_model.CommentTypeComment {
725-
ctx.Status(http.StatusNoContent)
724+
} else if !comment.Type.HasContentSupport() {
725+
ctx.Status(http.StatusBadRequest)
726726
return
727727
}
728728

routers/api/v1/repo/status.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
271271
}
272272
ctx.SetTotalCountHeader(count)
273273

274-
if len(statuses) == 0 {
275-
ctx.JSON(http.StatusOK, &api.CombinedStatus{})
276-
return
277-
}
278-
279-
combiStatus := convert.ToCombinedStatus(ctx, statuses, convert.ToRepo(ctx, repo, ctx.Repo.Permission))
274+
combiStatus := convert.ToCombinedStatus(ctx, refCommit.Commit.ID.String(), statuses,
275+
convert.ToRepo(ctx, repo, ctx.Repo.Permission))
280276
ctx.JSON(http.StatusOK, combiStatus)
281277
}

routers/web/admin/auths.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func NewAuthSource(ctx *context.Context) {
9797
ctx.Data["AuthSources"] = authSources
9898
ctx.Data["SecurityProtocols"] = securityProtocols
9999
ctx.Data["SMTPAuths"] = smtp.Authenticators
100-
oauth2providers := oauth2.GetSupportedOAuth2Providers()
100+
oauth2providers := oauth2.GetSupportedOAuth2ProvidersWithContext(ctx)
101101
ctx.Data["OAuth2Providers"] = oauth2providers
102102

103103
ctx.Data["SSPIAutoCreateUsers"] = true
@@ -107,7 +107,9 @@ func NewAuthSource(ctx *context.Context) {
107107
ctx.Data["SSPIDefaultLanguage"] = ""
108108

109109
// only the first as default
110-
ctx.Data["oauth2_provider"] = oauth2providers[0].Name()
110+
if len(oauth2providers) > 0 {
111+
ctx.Data["oauth2_provider"] = oauth2providers[0].Name()
112+
}
111113

112114
ctx.HTML(http.StatusOK, tplAuthNew)
113115
}
@@ -240,7 +242,7 @@ func NewAuthSourcePost(ctx *context.Context) {
240242
ctx.Data["AuthSources"] = authSources
241243
ctx.Data["SecurityProtocols"] = securityProtocols
242244
ctx.Data["SMTPAuths"] = smtp.Authenticators
243-
oauth2providers := oauth2.GetSupportedOAuth2Providers()
245+
oauth2providers := oauth2.GetSupportedOAuth2ProvidersWithContext(ctx)
244246
ctx.Data["OAuth2Providers"] = oauth2providers
245247

246248
ctx.Data["SSPIAutoCreateUsers"] = true

routers/web/feed/render.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@ import (
88
)
99

1010
// RenderBranchFeed render format for branch or file
11-
func RenderBranchFeed(ctx *context.Context) {
12-
_, showFeedType := GetFeedType(ctx.PathParam("reponame"), ctx.Req)
11+
func RenderBranchFeed(ctx *context.Context, feedType string) {
1312
if ctx.Repo.TreePath == "" {
14-
ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType)
13+
ShowBranchFeed(ctx, ctx.Repo.Repository, feedType)
1514
} else {
16-
ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType)
15+
ShowFileFeed(ctx, ctx.Repo.Repository, feedType)
1716
}
1817
}
18+
19+
func RenderBranchFeedRSS(ctx *context.Context) {
20+
RenderBranchFeed(ctx, "rss")
21+
}
22+
23+
func RenderBranchFeedAtom(ctx *context.Context) {
24+
RenderBranchFeed(ctx, "atom")
25+
}

routers/web/repo/actions/view.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,12 @@ func Rerun(ctx *context_module.Context) {
429429
ctx.ServerError("UpdateRun", err)
430430
return
431431
}
432+
433+
if err := run.LoadAttributes(ctx); err != nil {
434+
ctx.ServerError("run.LoadAttributes", err)
435+
return
436+
}
437+
notify_service.WorkflowRunStatusUpdate(ctx, run.Repo, run.TriggerUser, run)
432438
}
433439

434440
job, jobs := getRunJobs(ctx, runIndex, jobIndex)
@@ -485,7 +491,6 @@ func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shou
485491
}
486492

487493
actions_service.CreateCommitStatus(ctx, job)
488-
actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job)
489494
notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil)
490495

491496
return nil
@@ -560,9 +565,8 @@ func Cancel(ctx *context_module.Context) {
560565
if len(updatedjobs) > 0 {
561566
job := updatedjobs[0]
562567
actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job)
563-
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
564568
}
565-
ctx.JSON(http.StatusOK, struct{}{})
569+
ctx.JSONOK()
566570
}
567571

568572
func Approve(ctx *context_module.Context) {
@@ -606,15 +610,14 @@ func Approve(ctx *context_module.Context) {
606610
if len(updatedjobs) > 0 {
607611
job := updatedjobs[0]
608612
actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job)
609-
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
610613
}
611614

612615
for _, job := range updatedjobs {
613616
_ = job.LoadAttributes(ctx)
614617
notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil)
615618
}
616619

617-
ctx.JSON(http.StatusOK, struct{}{})
620+
ctx.JSONOK()
618621
}
619622

620623
func Delete(ctx *context_module.Context) {

routers/web/web.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,8 +1615,8 @@ func registerWebRoutes(m *web.Router) {
16151615
m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, context.RepoRefByDefaultBranch(), repo.CherryPick)
16161616
}, repo.MustBeNotEmpty)
16171617

1618-
m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed)
1619-
m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed)
1618+
m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeedRSS)
1619+
m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeedAtom)
16201620

16211621
m.Group("/src", func() {
16221622
m.Get("", func(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink) }) // there is no "{owner}/{repo}/src" page, so redirect to "{owner}/{repo}" to avoid 404

services/actions/clear_tasks.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ func notifyWorkflowJobStatusUpdate(ctx context.Context, jobs []*actions_model.Ac
4242
_ = job.LoadAttributes(ctx)
4343
notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil)
4444
}
45-
if len(jobs) > 0 {
46-
job := jobs[0]
47-
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
48-
}
45+
job := jobs[0]
46+
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
4947
}
5048
}
5149

@@ -101,7 +99,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
10199
return nil
102100
}
103101

104-
// CancelAbandonedJobs cancels the jobs which have waiting status, but haven't been picked by a runner for a long time
102+
// CancelAbandonedJobs cancels jobs that have not been picked by any runner for a long time
105103
func CancelAbandonedJobs(ctx context.Context) error {
106104
jobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{
107105
Statuses: []actions_model.Status{actions_model.StatusWaiting, actions_model.StatusBlocked},
@@ -113,24 +111,40 @@ func CancelAbandonedJobs(ctx context.Context) error {
113111
}
114112

115113
now := timeutil.TimeStampNow()
114+
115+
// Collect one job per run to send workflow run status update
116+
updatedRuns := map[int64]*actions_model.ActionRunJob{}
117+
116118
for _, job := range jobs {
117119
job.Status = actions_model.StatusCancelled
118120
job.Stopped = now
119121
updated := false
120122
if err := db.WithTx(ctx, func(ctx context.Context) error {
121123
n, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped")
122-
updated = err == nil && n > 0
123-
return err
124+
if err != nil {
125+
return err
126+
}
127+
if err := job.LoadAttributes(ctx); err != nil {
128+
return err
129+
}
130+
updated = n > 0
131+
if updated && job.Run.Status.IsDone() {
132+
updatedRuns[job.RunID] = job
133+
}
134+
return nil
124135
}); err != nil {
125136
log.Warn("cancel abandoned job %v: %v", job.ID, err)
126137
// go on
127138
}
128139
CreateCommitStatus(ctx, job)
129140
if updated {
130-
NotifyWorkflowRunStatusUpdateWithReload(ctx, job)
131141
notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil)
132142
}
133143
}
134144

145+
for _, job := range updatedRuns {
146+
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
147+
}
148+
135149
return nil
136150
}

services/asymkey/sign.go

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ func signingModeFromStrings(modeStrings []string) []signingMode {
6969
return returnable
7070
}
7171

72+
func userHasPubkeysGPG(ctx context.Context, userID int64) (bool, error) {
73+
return db.Exist[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
74+
OwnerID: userID,
75+
IncludeSubKeys: true,
76+
}.ToConds())
77+
}
78+
79+
func userHasPubkeysSSH(ctx context.Context, userID int64) (bool, error) {
80+
return db.Exist[asymkey_model.PublicKey](ctx, asymkey_model.FindPublicKeyOptions{
81+
OwnerID: userID,
82+
NotKeytype: asymkey_model.KeyTypePrincipal,
83+
}.ToConds())
84+
}
85+
86+
// userHasPubkeys checks if a user has any public keys (GPG or SSH)
87+
func userHasPubkeys(ctx context.Context, userID int64) (bool, error) {
88+
has, err := userHasPubkeysGPG(ctx, userID)
89+
if has || err != nil {
90+
return has, err
91+
}
92+
return userHasPubkeysSSH(ctx, userID)
93+
}
94+
7295
// ErrWontSign explains the first reason why a commit would not be signed
7396
// There may be other reasons - this is just the first reason found
7497
type ErrWontSign struct {
@@ -170,14 +193,11 @@ Loop:
170193
case always:
171194
break Loop
172195
case pubkey:
173-
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
174-
OwnerID: u.ID,
175-
IncludeSubKeys: true,
176-
})
196+
hasKeys, err := userHasPubkeys(ctx, u.ID)
177197
if err != nil {
178198
return false, nil, nil, err
179199
}
180-
if len(keys) == 0 {
200+
if !hasKeys {
181201
return false, nil, nil, &ErrWontSign{pubkey}
182202
}
183203
case twofa:
@@ -210,14 +230,11 @@ Loop:
210230
case always:
211231
break Loop
212232
case pubkey:
213-
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
214-
OwnerID: u.ID,
215-
IncludeSubKeys: true,
216-
})
233+
hasKeys, err := userHasPubkeys(ctx, u.ID)
217234
if err != nil {
218235
return false, nil, nil, err
219236
}
220-
if len(keys) == 0 {
237+
if !hasKeys {
221238
return false, nil, nil, &ErrWontSign{pubkey}
222239
}
223240
case twofa:
@@ -266,14 +283,11 @@ Loop:
266283
case always:
267284
break Loop
268285
case pubkey:
269-
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
270-
OwnerID: u.ID,
271-
IncludeSubKeys: true,
272-
})
286+
hasKeys, err := userHasPubkeys(ctx, u.ID)
273287
if err != nil {
274288
return false, nil, nil, err
275289
}
276-
if len(keys) == 0 {
290+
if !hasKeys {
277291
return false, nil, nil, &ErrWontSign{pubkey}
278292
}
279293
case twofa:
@@ -337,14 +351,11 @@ Loop:
337351
case always:
338352
break Loop
339353
case pubkey:
340-
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
341-
OwnerID: u.ID,
342-
IncludeSubKeys: true,
343-
})
354+
hasKeys, err := userHasPubkeys(ctx, u.ID)
344355
if err != nil {
345356
return false, nil, nil, err
346357
}
347-
if len(keys) == 0 {
358+
if !hasKeys {
348359
return false, nil, nil, &ErrWontSign{pubkey}
349360
}
350361
case twofa:

services/asymkey/sign_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package asymkey
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/unittest"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestUserHasPubkeys(t *testing.T) {
16+
assert.NoError(t, unittest.PrepareTestDatabase())
17+
test := func(t *testing.T, userID int64, expectedHasGPG, expectedHasSSH bool) {
18+
ctx := t.Context()
19+
hasGPG, err := userHasPubkeysGPG(ctx, userID)
20+
require.NoError(t, err)
21+
hasSSH, err := userHasPubkeysSSH(ctx, userID)
22+
require.NoError(t, err)
23+
hasPubkeys, err := userHasPubkeys(ctx, userID)
24+
require.NoError(t, err)
25+
assert.Equal(t, expectedHasGPG, hasGPG)
26+
assert.Equal(t, expectedHasSSH, hasSSH)
27+
assert.Equal(t, expectedHasGPG || expectedHasSSH, hasPubkeys)
28+
}
29+
30+
t.Run("AllowUserWithGPGKey", func(t *testing.T) {
31+
test(t, 36, true, false) // has gpg
32+
})
33+
t.Run("AllowUserWithSSHKey", func(t *testing.T) {
34+
test(t, 2, false, true) // has ssh
35+
})
36+
t.Run("DenyUserWithNoKeys", func(t *testing.T) {
37+
test(t, 1, false, false) // no pubkey
38+
})
39+
}

0 commit comments

Comments
 (0)