Skip to content

Commit bc3a467

Browse files
committed
remove duplicate workflow run trigger + add test for cancel
* missing test for approve
1 parent c3a7f15 commit bc3a467

File tree

2 files changed

+128
-2
lines changed

2 files changed

+128
-2
lines changed

routers/web/repo/actions/view.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,6 @@ func Cancel(ctx *context_module.Context) {
560560
if len(updatedjobs) > 0 {
561561
job := updatedjobs[0]
562562
actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job)
563-
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
564563
}
565564
ctx.JSON(http.StatusOK, struct{}{})
566565
}
@@ -606,7 +605,6 @@ func Approve(ctx *context_module.Context) {
606605
if len(updatedjobs) > 0 {
607606
job := updatedjobs[0]
608607
actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job)
609-
notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run)
610608
}
611609

612610
for _, job := range updatedjobs {

tests/integration/repo_webhook_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path"
1313
"strings"
1414
"testing"
15+
"time"
1516

1617
auth_model "code.gitea.io/gitea/models/auth"
1718
"code.gitea.io/gitea/models/repo"
@@ -1058,6 +1059,10 @@ func Test_WebhookWorkflowRun(t *testing.T) {
10581059
name: "WorkflowRunDepthLimit",
10591060
callback: testWebhookWorkflowRunDepthLimit,
10601061
},
1062+
{
1063+
name: "WorkflowRunDuplicateEvents",
1064+
callback: testWorkflowRunDuplicateEvents,
1065+
},
10611066
}
10621067
for _, test := range tests {
10631068
t.Run(test.name, func(t *testing.T) {
@@ -1070,6 +1075,129 @@ func Test_WebhookWorkflowRun(t *testing.T) {
10701075
}
10711076
}
10721077

1078+
func testWorkflowRunDuplicateEvents(t *testing.T, webhookData *workflowRunWebhook) {
1079+
// 1. create a new webhook with special webhook for repo1
1080+
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
1081+
session := loginUser(t, "user2")
1082+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
1083+
1084+
testAPICreateWebhookForRepo(t, session, "user2", "repo1", webhookData.URL, "workflow_run")
1085+
1086+
repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
1087+
1088+
gitRepo1, err := gitrepo.OpenRepository(t.Context(), repo1)
1089+
assert.NoError(t, err)
1090+
1091+
// 2.2 trigger the webhooks
1092+
1093+
// add workflow file to the repo
1094+
// init the workflow
1095+
wfTreePath := ".gitea/workflows/push.yml"
1096+
wfFileContent := `on:
1097+
push:
1098+
workflow_dispatch:
1099+
1100+
jobs:
1101+
test:
1102+
runs-on: ubuntu-latest
1103+
steps:
1104+
- run: exit 0
1105+
1106+
test2:
1107+
needs: [test]
1108+
runs-on: ubuntu-latest
1109+
steps:
1110+
- run: exit 0
1111+
1112+
test3:
1113+
needs: [test, test2]
1114+
runs-on: ubuntu-latest
1115+
steps:
1116+
- run: exit 0
1117+
1118+
test4:
1119+
needs: [test, test2, test3]
1120+
runs-on: ubuntu-latest
1121+
steps:
1122+
- run: exit 0
1123+
1124+
test5:
1125+
needs: [test, test2, test4]
1126+
runs-on: ubuntu-latest
1127+
steps:
1128+
- run: exit 0
1129+
1130+
test6:
1131+
strategy:
1132+
matrix:
1133+
os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
1134+
needs: [test, test2, test3]
1135+
runs-on: ${{ matrix.os }}
1136+
steps:
1137+
- run: exit 0
1138+
1139+
test7:
1140+
needs: test6
1141+
runs-on: ubuntu-latest
1142+
steps:
1143+
- run: exit 0
1144+
1145+
test8:
1146+
runs-on: ubuntu-latest
1147+
steps:
1148+
- run: exit 0
1149+
1150+
test9:
1151+
strategy:
1152+
matrix:
1153+
os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, ubuntu-25.04, windows-2022, windows-2025, macos-13, macos-14, macos-15]
1154+
runs-on: ${{ matrix.os }}
1155+
steps:
1156+
- run: exit 0
1157+
1158+
test10:
1159+
runs-on: ubuntu-latest
1160+
steps:
1161+
- run: exit 0`
1162+
opts := getWorkflowCreateFileOptions(user2, repo1.DefaultBranch, "create "+wfTreePath, wfFileContent)
1163+
createWorkflowFile(t, token, "user2", "repo1", wfTreePath, opts)
1164+
1165+
commitID, err := gitRepo1.GetBranchCommitID(repo1.DefaultBranch)
1166+
assert.NoError(t, err)
1167+
1168+
// 3. validate the webhook is triggered
1169+
assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
1170+
assert.Len(t, webhookData.payloads, 1)
1171+
assert.Equal(t, "requested", webhookData.payloads[0].Action)
1172+
assert.Equal(t, "queued", webhookData.payloads[0].WorkflowRun.Status)
1173+
assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[0].WorkflowRun.HeadBranch)
1174+
assert.Equal(t, commitID, webhookData.payloads[0].WorkflowRun.HeadSha)
1175+
assert.Equal(t, "repo1", webhookData.payloads[0].Repo.Name)
1176+
assert.Equal(t, "user2/repo1", webhookData.payloads[0].Repo.FullName)
1177+
1178+
time.Sleep(15 * time.Second) // wait for the workflow to be processed
1179+
1180+
// Call cancel ui api
1181+
// Only a web UI API exists for cancelling workflow runs, so use the UI endpoint.
1182+
cancelURL := fmt.Sprintf("/user2/repo1/actions/runs/%d/cancel", webhookData.payloads[0].WorkflowRun.RunNumber)
1183+
req := NewRequestWithValues(t, "POST", cancelURL, map[string]string{
1184+
"_csrf": GetUserCSRFToken(t, session),
1185+
})
1186+
session.MakeRequest(t, req, http.StatusOK)
1187+
1188+
assert.Len(t, webhookData.payloads, 2)
1189+
1190+
// 4. Validate the second webhook payload
1191+
assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
1192+
assert.Equal(t, "completed", webhookData.payloads[1].Action)
1193+
assert.Equal(t, "push", webhookData.payloads[1].WorkflowRun.Event)
1194+
assert.Equal(t, "completed", webhookData.payloads[1].WorkflowRun.Status)
1195+
assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[1].WorkflowRun.HeadBranch)
1196+
assert.Equal(t, commitID, webhookData.payloads[1].WorkflowRun.HeadSha)
1197+
assert.Equal(t, "repo1", webhookData.payloads[1].Repo.Name)
1198+
assert.Equal(t, "user2/repo1", webhookData.payloads[1].Repo.FullName)
1199+
}
1200+
10731201
func testWebhookWorkflowRun(t *testing.T, webhookData *workflowRunWebhook) {
10741202
// 1. create a new webhook with special webhook for repo1
10751203
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})

0 commit comments

Comments
 (0)