diff --git a/options/locale/locale_cs-CZ.json b/options/locale/locale_cs-CZ.json index 1b563c085a0..73c5f2221c6 100644 --- a/options/locale/locale_cs-CZ.json +++ b/options/locale/locale_cs-CZ.json @@ -1950,7 +1950,6 @@ "repo.settings.webhook_deletion": "Odstranit webový háček", "repo.settings.webhook_deletion_desc": "Odstranění webového háčku smaže jeho nastavení a historii doručení. Pokračovat?", "repo.settings.webhook_deletion_success": "Webový háček byl smazán.", - "repo.settings.webhook.test_delivery_desc_disabled": "Chcete-li tento webový háček otestovat s falešnou událostí, aktivujte ho.", "repo.settings.webhook.request": "Požadavek", "repo.settings.webhook.response": "Odpověď", "repo.settings.webhook.headers": "Hlavičky", diff --git a/options/locale/locale_de-DE.json b/options/locale/locale_de-DE.json index 569e0fcc4cc..44f42c58311 100644 --- a/options/locale/locale_de-DE.json +++ b/options/locale/locale_de-DE.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "Webhook wurde entfernt.", "repo.settings.webhook.test_delivery": "Test Push Ereignis", "repo.settings.webhook.test_delivery_desc": "Teste diesen Webhook mit einem Fake-Push-Event.", - "repo.settings.webhook.test_delivery_desc_disabled": "Um diesen Webhook mit einem Fake-Event zu testen, aktiviere ihn.", "repo.settings.webhook.request": "Anfrage", "repo.settings.webhook.response": "Antwort", "repo.settings.webhook.headers": "Kopfzeilen", diff --git a/options/locale/locale_el-GR.json b/options/locale/locale_el-GR.json index ad0012c7a48..ab251040286 100644 --- a/options/locale/locale_el-GR.json +++ b/options/locale/locale_el-GR.json @@ -1781,7 +1781,6 @@ "repo.settings.webhook_deletion": "Αφαίρεση Webhook", "repo.settings.webhook_deletion_desc": "Η αφαίρεση ενός webhook διαγράφει τις ρυθμίσεις και το ιστορικό παραδόσεων. Συνέχεια;", "repo.settings.webhook_deletion_success": "Το webhook έχει αφαιρεθεί.", - "repo.settings.webhook.test_delivery_desc_disabled": "Για να δοκιμάσετε αυτό το webhook με μια ψεύτικη κλήση, ενεργοποιήστε το.", "repo.settings.webhook.request": "Αίτημα", "repo.settings.webhook.response": "Απάντηση", "repo.settings.webhook.headers": "Κεφαλίδες", diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index 9373aa83a90..91e66940765 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "The webhook has been removed.", "repo.settings.webhook.test_delivery": "Test Push Event", "repo.settings.webhook.test_delivery_desc": "Test this webhook with a fake push event.", - "repo.settings.webhook.test_delivery_desc_disabled": "To test this webhook with a fake event, activate it.", "repo.settings.webhook.request": "Request", "repo.settings.webhook.response": "Response", "repo.settings.webhook.headers": "Headers", diff --git a/options/locale/locale_es-ES.json b/options/locale/locale_es-ES.json index 6dc1065cdbf..bc5ea04d6a9 100644 --- a/options/locale/locale_es-ES.json +++ b/options/locale/locale_es-ES.json @@ -1753,7 +1753,6 @@ "repo.settings.webhook_deletion": "Eliminar Webhook", "repo.settings.webhook_deletion_desc": "Eliminar un webhook borra sus ajustes e historial de entrega. ¿Continuar?", "repo.settings.webhook_deletion_success": "El webhook ha sido eliminado.", - "repo.settings.webhook.test_delivery_desc_disabled": "Para probar este webhook con un evento falso, actívalo.", "repo.settings.webhook.request": "Petición", "repo.settings.webhook.response": "Respuesta", "repo.settings.webhook.headers": "Encabezado", diff --git a/options/locale/locale_fr-FR.json b/options/locale/locale_fr-FR.json index 047d8420cb3..739acec24d6 100644 --- a/options/locale/locale_fr-FR.json +++ b/options/locale/locale_fr-FR.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "Le webhook a été supprimé.", "repo.settings.webhook.test_delivery": "Tester l’envoi", "repo.settings.webhook.test_delivery_desc": "Testez ce webhook avec un faux événement.", - "repo.settings.webhook.test_delivery_desc_disabled": "Pour tester ce webhook avec un faux événement, activez-le.", "repo.settings.webhook.request": "Requête", "repo.settings.webhook.response": "Réponse", "repo.settings.webhook.headers": "Entêtes", diff --git a/options/locale/locale_ga-IE.json b/options/locale/locale_ga-IE.json index ef4c368d2b5..132c9d325d8 100644 --- a/options/locale/locale_ga-IE.json +++ b/options/locale/locale_ga-IE.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "Tá an Crúca Gréasán bainte amach.", "repo.settings.webhook.test_delivery": "Imeacht Brúigh Tástála", "repo.settings.webhook.test_delivery_desc": "Déan tástáil ar an webhook seo le teagmhas brú bréige.", - "repo.settings.webhook.test_delivery_desc_disabled": "Chun an Crúca Gréasán seo a thástáil le himeacht bhréige, gníomhachtaigh é.", "repo.settings.webhook.request": "Iarratas", "repo.settings.webhook.response": "Freagra", "repo.settings.webhook.headers": "Ceanntásca", diff --git a/options/locale/locale_ja-JP.json b/options/locale/locale_ja-JP.json index 7486bf5473e..a9dabf1772d 100644 --- a/options/locale/locale_ja-JP.json +++ b/options/locale/locale_ja-JP.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "Webhookを削除しました。", "repo.settings.webhook.test_delivery": "プッシュ・イベントによるテスト", "repo.settings.webhook.test_delivery_desc": "ダミーのプッシュ・イベントでこのWebhookをテストします。", - "repo.settings.webhook.test_delivery_desc_disabled": "このWebhookをダミーのイベントでテストするには、有効にしてください。", "repo.settings.webhook.request": "リクエスト", "repo.settings.webhook.response": "レスポンス", "repo.settings.webhook.headers": "ヘッダー", diff --git a/options/locale/locale_ko-KR.json b/options/locale/locale_ko-KR.json index 20497594251..41e5771ee3a 100644 --- a/options/locale/locale_ko-KR.json +++ b/options/locale/locale_ko-KR.json @@ -2248,7 +2248,6 @@ "repo.settings.webhook_deletion_success": "Webhook을 삭제했습니다.", "repo.settings.webhook.test_delivery": "푸시 이벤트 테스트", "repo.settings.webhook.test_delivery_desc": "가짜 푸시 이벤트로 웹훅을 테스트합니다.", - "repo.settings.webhook.test_delivery_desc_disabled": "가짜 이벤트로 이 웹훅을 테스트하려면 활성화하십시오.", "repo.settings.webhook.request": "요청", "repo.settings.webhook.response": "응답", "repo.settings.webhook.headers": "제목", diff --git a/options/locale/locale_lv-LV.json b/options/locale/locale_lv-LV.json index bfc3efc8edf..fedce5f0f39 100644 --- a/options/locale/locale_lv-LV.json +++ b/options/locale/locale_lv-LV.json @@ -1812,7 +1812,6 @@ "repo.settings.webhook_deletion": "Noņemt tīmekļa āķi", "repo.settings.webhook_deletion_desc": "Noņemot tīmekļa āķi, tiks dzēsti visi tā iestatījumi un piegādes vēsture. Vai turpināt?", "repo.settings.webhook_deletion_success": "Tīmekļa āķis tika noņemts.", - "repo.settings.webhook.test_delivery_desc_disabled": "Lai pārbaudītu šo tīmekļa āķi ar neīstu notikumu, tas ir jāiespējo.", "repo.settings.webhook.request": "Pieprasījums", "repo.settings.webhook.response": "Atbilde", "repo.settings.webhook.headers": "Galvenes", diff --git a/options/locale/locale_pt-BR.json b/options/locale/locale_pt-BR.json index 8d42a84e5c6..4d3633f8b02 100644 --- a/options/locale/locale_pt-BR.json +++ b/options/locale/locale_pt-BR.json @@ -2019,7 +2019,6 @@ "repo.settings.webhook_deletion_success": "O webhook foi removido.", "repo.settings.webhook.test_delivery": "Testar Evento de Push", "repo.settings.webhook.test_delivery_desc": "Teste este webhook com um evento falso.", - "repo.settings.webhook.test_delivery_desc_disabled": "Para testar este webhook com um evento falso, ative-o.", "repo.settings.webhook.request": "Solicitação", "repo.settings.webhook.response": "Resposta", "repo.settings.webhook.headers": "Cabeçalhos", diff --git a/options/locale/locale_pt-PT.json b/options/locale/locale_pt-PT.json index b02ac313810..23cb9425231 100644 --- a/options/locale/locale_pt-PT.json +++ b/options/locale/locale_pt-PT.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "O automatismo web foi removido.", "repo.settings.webhook.test_delivery": "Testar o envio", "repo.settings.webhook.test_delivery_desc": "Testar este automatismo web com um evento de envio falso.", - "repo.settings.webhook.test_delivery_desc_disabled": "Para testar este automatismo web com um evento falso, habilite-o.", "repo.settings.webhook.request": "Pedido", "repo.settings.webhook.response": "Resposta", "repo.settings.webhook.headers": "Cabeçalhos", diff --git a/options/locale/locale_tr-TR.json b/options/locale/locale_tr-TR.json index d1aeed537b8..5ef8d890e2a 100644 --- a/options/locale/locale_tr-TR.json +++ b/options/locale/locale_tr-TR.json @@ -2204,7 +2204,6 @@ "repo.settings.webhook_deletion_success": "Web isteği silindi.", "repo.settings.webhook.test_delivery": "İtme Olayını Sına", "repo.settings.webhook.test_delivery_desc": "Bu web istemcisini sahte bir itme olayıyla sınayın.", - "repo.settings.webhook.test_delivery_desc_disabled": "Bu web istemcisini sahte bir olayla denemek için etkinleştirin.", "repo.settings.webhook.request": "İstekler", "repo.settings.webhook.response": "Cevaplar", "repo.settings.webhook.headers": "Başlıklar", diff --git a/options/locale/locale_zh-CN.json b/options/locale/locale_zh-CN.json index a81cd20d796..6759b09b579 100644 --- a/options/locale/locale_zh-CN.json +++ b/options/locale/locale_zh-CN.json @@ -2251,7 +2251,6 @@ "repo.settings.webhook_deletion_success": "Web 钩子删除成功!", "repo.settings.webhook.test_delivery": "测试推送事件", "repo.settings.webhook.test_delivery_desc": "用假推送事件测试这个 Web 钩子。", - "repo.settings.webhook.test_delivery_desc_disabled": "要用假事件测试这个 Web钩子,请激活它。", "repo.settings.webhook.request": "请求内容", "repo.settings.webhook.response": "响应内容", "repo.settings.webhook.headers": "头信息", diff --git a/options/locale/locale_zh-TW.json b/options/locale/locale_zh-TW.json index ef25bbe25d8..41e4cb5f224 100644 --- a/options/locale/locale_zh-TW.json +++ b/options/locale/locale_zh-TW.json @@ -1952,7 +1952,6 @@ "repo.settings.webhook_deletion": "移除 Webhook", "repo.settings.webhook_deletion_desc": "移除 Webhook 將刪除它的設定及傳送記錄,是否繼續?", "repo.settings.webhook_deletion_success": "Webhook 已移除。", - "repo.settings.webhook.test_delivery_desc_disabled": "要使用假事件測試此 Webhook,請啟用它。", "repo.settings.webhook.request": "請求", "repo.settings.webhook.response": "回應", "repo.settings.webhook.headers": "標頭", diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index c247fc00390..b3154696b76 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -177,7 +177,7 @@ func TestHook(ctx *context.APIContext) { commit := convert.ToPayloadCommit(ctx, ctx.Repo.Repository, ctx.Repo.Commit) commitID := ctx.Repo.Commit.ID.String() - if err := webhook_service.PrepareWebhook(ctx, hook, webhook_module.HookEventPush, &api.PushPayload{ + if err := webhook_service.PrepareTestWebhook(ctx, hook, webhook_module.HookEventPush, &api.PushPayload{ Ref: ref, Before: commitID, After: commitID, diff --git a/routers/web/admin/queue_tester.go b/routers/web/admin/queue_tester.go index be7cb687e4a..e3f04ac705e 100644 --- a/routers/web/admin/queue_tester.go +++ b/routers/web/admin/queue_tester.go @@ -56,6 +56,7 @@ func initTestQueueOnce() { for { select { case <-ctx.Done(): + return case <-time.After(500 * time.Millisecond): if adding { if testQueue.GetQueueItemNumber() == qs.Length { diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 4d3120618f4..f128209f1be 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -664,19 +664,14 @@ func TestWebhook(ctx *context.Context) { return } - // Grab latest commit or fake one if it's empty repository. - // Note: in old code, the "ctx.Repo.Commit" is the last commit of the default branch. - // New code doesn't set that commit, so it always uses the fake commit to test webhook. - commit := ctx.Repo.Commit - if commit == nil { - ghost := user_model.NewGhostUser() - objectFormat := git.ObjectFormatFromName(ctx.Repo.Repository.ObjectFormatName) - commit = &git.Commit{ - ID: objectFormat.EmptyObjectID(), - Author: ghost.NewGitSig(), - Committer: ghost.NewGitSig(), - CommitMessage: git.CommitMessage{MessageRaw: "This is a fake commit"}, - } + // use a fake commit to test webhook + ghostUser := user_model.NewGhostUser() + objectFormat := git.ObjectFormatFromName(ctx.Repo.Repository.ObjectFormatName) + commit := &git.Commit{ + ID: objectFormat.EmptyObjectID(), + Author: ghostUser.NewGitSig(), + Committer: ghostUser.NewGitSig(), + CommitMessage: git.CommitMessage{MessageRaw: "This is a fake commit for webhook push test"}, } apiUser := convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone) @@ -697,7 +692,7 @@ func TestWebhook(ctx *context.Context) { commitID := commit.ID.String() p := &api.PushPayload{ - Ref: git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, + Ref: git.RefNameFromBranch(ctx.Repo.Repository.DefaultBranch).String(), Before: commitID, After: commitID, CompareURL: setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID), @@ -708,8 +703,8 @@ func TestWebhook(ctx *context.Context) { Pusher: apiUser, Sender: apiUser, } - if err := webhook_service.PrepareWebhook(ctx, w, webhook_module.HookEventPush, p); err != nil { - ctx.Flash.Error("PrepareWebhook: " + err.Error()) + if err := webhook_service.PrepareTestWebhook(ctx, w, webhook_module.HookEventPush, p); err != nil { + ctx.Flash.Error("PrepareTestWebhook: " + err.Error()) ctx.Status(http.StatusInternalServerError) } else { ctx.Flash.Info(ctx.Tr("repo.settings.webhook.delivery.success")) diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index f174bfb1cd4..21a2bb8fc1d 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -373,16 +373,18 @@ func RunnerBulkActionPost(ctx *context.Context) { return } - var runnerIDs []int64 - if rCtx.IsAdmin { - // ATTENTION: it completely depends on the assumption that the doer is "site admin" - // So it doesn't do extra permission check to the runner IDs - // In the future, if you need to support such operation on non-admin pages, be careful! - runnerIDs = ctx.FormStringInt64s("ids") - } else { + if !rCtx.IsAdmin { ctx.HTTPError(http.StatusForbidden, "bulk actions are admin-only") return } + // ATTENTION: it completely depends on the assumption that the doer is "site admin" + // So it doesn't do extra permission check to the runner IDs + // In the future, if you need to support such operation on non-admin pages, be careful! + runnerIDs := ctx.FormStringInt64s("ids") + if len(runnerIDs) == 0 { + ctx.HTTPError(http.StatusBadRequest, "missing runner IDs") + return + } action := ctx.FormString("action") var successKey, failedKey string diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go index 5e8107772ac..0a53f289aa9 100644 --- a/services/webhook/webhook.go +++ b/services/webhook/webhook.go @@ -129,6 +129,33 @@ func checkBranchFilter(branchFilter string, ref git.RefName) bool { return g.Match(ref.String()) } +// PrepareTestWebhook always creates and enqueues a hook task for manual testing. +// Unlike PrepareWebhook, it ignores event subscriptions and branch filters so the +// Test Push Event control can verify delivery even when those gates would suppress +// a real event. +func PrepareTestWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook_module.HookEventType, p api.Payloader) error { + if setting.DisableWebhooks { + return nil + } + + payload, err := p.JSONPayload() + if err != nil { + return fmt.Errorf("JSONPayload for %s: %w", event, err) + } + + task, err := webhook_model.CreateHookTask(ctx, &webhook_model.HookTask{ + HookID: w.ID, + PayloadContent: string(payload), + EventType: event, + PayloadVersion: 2, + }) + if err != nil { + return fmt.Errorf("CreateHookTask for %s: %w", event, err) + } + + return enqueueHookTask(task.ID) +} + // PrepareWebhook creates a hook task and enqueues it for processing. // The payload is saved as-is. The adjustments depending on the webhook type happen // right before delivery, in the [Deliver] method. diff --git a/services/webhook/webhook_test.go b/services/webhook/webhook_test.go index f20510c9a61..6ecf24337c7 100644 --- a/services/webhook/webhook_test.go +++ b/services/webhook/webhook_test.go @@ -30,6 +30,7 @@ func TestWebhookService(t *testing.T) { t.Run("PrepareBranchFilterNoMatch", testWebhookPrepareBranchFilterNoMatch) t.Run("WebhookUserMail", testWebhookUserMail) t.Run("CheckBranchFilter", testWebhookCheckBranchFilter) + t.Run("PrepareTestWebhookIgnoresGates", testPrepareTestWebhookIgnoresGates) } func testWebhookGetSlackHook(t *testing.T) { @@ -132,3 +133,37 @@ func testWebhookCheckBranchFilter(t *testing.T) { assert.Equal(t, v.match, checkBranchFilter(v.filter, v.ref), "filter: %q ref: %q", v.filter, v.ref) } } + +func testPrepareTestWebhookIgnoresGates(t *testing.T) { + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + hook := &webhook_model.Webhook{ + RepoID: repo.ID, + URL: "http://localhost/gitea-webhook-test-prepare_test_webhook", + ContentType: webhook_model.ContentTypeJSON, + IsActive: true, + HookEvent: &webhook_module.HookEvent{ + ChooseEvents: true, + BranchFilter: "dev", + HookEvents: webhook_module.HookEvents{ + webhook_module.HookEventWorkflowRun: true, + }, + }, + } + require.NoError(t, hook.UpdateEvent()) + require.NoError(t, db.Insert(t.Context(), hook)) + + payload := &api.PushPayload{ + Ref: "refs/heads/master", + Commits: []*api.PayloadCommit{{}}, + } + hookTask := &webhook_model.HookTask{HookID: hook.ID, EventType: webhook_module.HookEventPush} + + // Real deliveries stay gated: no push event + branch filter mismatch => nothing queued. + unittest.AssertNotExistsBean(t, hookTask) + require.NoError(t, PrepareWebhook(t.Context(), hook, webhook_module.HookEventPush, payload)) + unittest.AssertNotExistsBean(t, hookTask) + + // Manual test delivery always queues so the endpoint can be verified. + require.NoError(t, PrepareTestWebhook(t.Context(), hook, webhook_module.HookEventPush, payload)) + unittest.AssertExistsAndLoadBean(t, hookTask) +} diff --git a/templates/devtest/flex-list.tmpl b/templates/devtest/flex-list.tmpl index 26df0920c5d..2551941f7ff 100644 --- a/templates/devtest/flex-list.tmpl +++ b/templates/devtest/flex-list.tmpl @@ -1,7 +1,17 @@ {{template "devtest/devtest-header"}}
-

Flex List (standalone)

+

Flex Relaxed List

+
+
+
+ left looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong + right +
+
+
+ +

Flex Divided List (standalone)

@@ -87,7 +97,7 @@
-

Flex List (with "ui segment")

+

Flex Divided List (with "ui segment")

item 1
@@ -101,7 +111,7 @@
item 2
-

Flex List (with "ui segment fitted", items have their own padding)

+

Flex Divided List (with "ui segment fitted", items have their own padding)

item 1
diff --git a/templates/org/header.tmpl b/templates/org/header.tmpl index 4f9e54b6109..58300edc5b6 100644 --- a/templates/org/header.tmpl +++ b/templates/org/header.tmpl @@ -1,6 +1,6 @@ -
+
{{ctx.AvatarUtils.Avatar .Org 100}}
-
+
{{.Org.DisplayName}} diff --git a/templates/repo/settings/webhook/history.tmpl b/templates/repo/settings/webhook/history.tmpl index d57913042be..7762fca85f2 100644 --- a/templates/repo/settings/webhook/history.tmpl +++ b/templates/repo/settings/webhook/history.tmpl @@ -1,16 +1,12 @@ -{{$isNew:=or .PageIsSettingsHooksNew .PageIsAdminDefaultHooksNew .PageIsAdminSystemHooksNew}} {{if .PageIsSettingsHooksEdit}} -

- {{ctx.Locale.Tr "repo.settings.recent_deliveries"}} +

+ {{ctx.Locale.Tr "repo.settings.recent_deliveries"}} {{if .Permission.IsAdmin}} -
- - - - -
+ {{end}}

diff --git a/templates/shared/actions/runner_list.tmpl b/templates/shared/actions/runner_list.tmpl index 1b287cdabc2..03400fa3a79 100644 --- a/templates/shared/actions/runner_list.tmpl +++ b/templates/shared/actions/runner_list.tmpl @@ -44,9 +44,9 @@
- - - + +