0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-02-21 11:28:12 +01:00

Merge 9f4a01f53f0640c77efa12e30c38c01f836ddb9d into 87f729190918e957b1d80c5e94c4e3ff440a387c

This commit is contained in:
Davide Tacchini 2026-02-20 16:40:41 +01:00 committed by GitHub
commit a8151862b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 186 additions and 9 deletions

View File

@ -34,9 +34,9 @@ func CreateCommitStatusForRunJobs(ctx context.Context, run *actions_model.Action
return
}
event, commitID, err := getCommitStatusEventNameAndCommitID(run)
event, commitID, err := getCommitStatusEventNameAndCommitID(ctx, run)
if err != nil {
log.Error("GetCommitStatusEventNameAndSHA: %v", err)
log.Error("getCommitStatusEventNameAndCommitID: %v", err)
}
if event == "" || commitID == "" {
return // unsupported event, or no commit id, or error occurs, do nothing
@ -81,7 +81,7 @@ func GetRunsFromCommitStatuses(ctx context.Context, statuses []*git_model.Commit
return runs, nil
}
func getCommitStatusEventNameAndCommitID(run *actions_model.ActionRun) (event, commitID string, _ error) {
func getCommitStatusEventNameAndCommitID(ctx context.Context, run *actions_model.ActionRun) (event, commitID string, _ error) {
switch run.Event {
case webhook_module.HookEventPush:
event = "push"
@ -118,6 +118,31 @@ func getCommitStatusEventNameAndCommitID(run *actions_model.ActionRun) (event, c
case webhook_module.HookEventRelease:
event = string(run.Event)
commitID = run.CommitSHA
case webhook_module.HookEventWorkflowRun:
event = "workflow_run"
currentRun := run
for range MaxWorkflowRunDepth {
payload, err := currentRun.GetWorkflowRunEventPayload()
if err != nil {
return "", "", fmt.Errorf("GetWorkflowRunEventPayload: %w", err)
}
if payload.WorkflowRun == nil {
return "", "", nil
}
parentRun, err := actions_model.GetRunByRepoAndID(ctx, currentRun.RepoID, payload.WorkflowRun.ID)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
return "", "", nil
}
return "", "", fmt.Errorf("GetRunByRepoAndID: %w", err)
}
if parentRun.Event != webhook_module.HookEventWorkflowRun {
_, commitID, err = getCommitStatusEventNameAndCommitID(ctx, parentRun)
return event, commitID, err
}
currentRun = parentRun
}
return "", "", nil
default: // do nothing, return empty
}
return event, commitID, nil

View File

@ -0,0 +1,149 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetCommitStatusEventNameAndCommitID(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
ctx := t.Context()
repoID := int64(1)
pushCommitSHA := "abc123def456abc123def456abc123def456abc1"
pushPayload, err := json.Marshal(&api.PushPayload{
HeadCommit: &api.PayloadCommit{ID: pushCommitSHA},
})
require.NoError(t, err)
nextIndex := func() int64 {
idx, err := db.GetNextResourceIndex(ctx, "action_run_index", repoID)
require.NoError(t, err)
return idx
}
pushRun := &actions_model.ActionRun{
Index: nextIndex(),
RepoID: repoID,
Event: webhook_module.HookEventPush,
EventPayload: string(pushPayload),
TriggerUserID: 1,
CommitSHA: pushCommitSHA,
Ref: "refs/heads/main",
WorkflowID: "push.yml",
Title: "push run",
}
require.NoError(t, db.Insert(ctx, pushRun))
t.Run("WorkflowRunWithPushParent", func(t *testing.T) {
wrPayload, err := json.Marshal(&api.WorkflowRunPayload{
WorkflowRun: &api.ActionWorkflowRun{
ID: pushRun.ID,
},
})
require.NoError(t, err)
wrRun := &actions_model.ActionRun{
Index: nextIndex(),
RepoID: repoID,
Event: webhook_module.HookEventWorkflowRun,
EventPayload: string(wrPayload),
TriggerUserID: 1,
CommitSHA: "default-branch-head-000000000000000000000",
Ref: "refs/heads/main",
WorkflowID: "wr.yml",
Title: "workflow_run run",
}
require.NoError(t, db.Insert(ctx, wrRun))
event, commitID, err := getCommitStatusEventNameAndCommitID(ctx, wrRun)
require.NoError(t, err)
assert.Equal(t, "workflow_run", event)
assert.Equal(t, pushCommitSHA, commitID)
})
t.Run("WorkflowRunChainedTwoLevels", func(t *testing.T) {
midPayload, err := json.Marshal(&api.WorkflowRunPayload{
WorkflowRun: &api.ActionWorkflowRun{
ID: pushRun.ID,
},
})
require.NoError(t, err)
midRun := &actions_model.ActionRun{
Index: nextIndex(),
RepoID: repoID,
Event: webhook_module.HookEventWorkflowRun,
EventPayload: string(midPayload),
TriggerUserID: 1,
CommitSHA: "default-branch-head-000000000000000000000",
Ref: "refs/heads/main",
WorkflowID: "mid.yml",
Title: "mid workflow_run",
}
require.NoError(t, db.Insert(ctx, midRun))
leafPayload, err := json.Marshal(&api.WorkflowRunPayload{
WorkflowRun: &api.ActionWorkflowRun{
ID: midRun.ID,
},
})
require.NoError(t, err)
leafRun := &actions_model.ActionRun{
Index: nextIndex(),
RepoID: repoID,
Event: webhook_module.HookEventWorkflowRun,
EventPayload: string(leafPayload),
TriggerUserID: 1,
CommitSHA: "default-branch-head-200000000000000000000",
Ref: "refs/heads/main",
WorkflowID: "leaf.yml",
Title: "leaf workflow_run",
}
require.NoError(t, db.Insert(ctx, leafRun))
event, commitID, err := getCommitStatusEventNameAndCommitID(ctx, leafRun)
require.NoError(t, err)
assert.Equal(t, "workflow_run", event)
assert.Equal(t, pushCommitSHA, commitID)
})
t.Run("WorkflowRunNilWorkflowRun", func(t *testing.T) {
payload, err := json.Marshal(&api.WorkflowRunPayload{
WorkflowRun: nil,
})
require.NoError(t, err)
run := &actions_model.ActionRun{
Index: nextIndex(),
RepoID: repoID,
Event: webhook_module.HookEventWorkflowRun,
EventPayload: string(payload),
TriggerUserID: 1,
CommitSHA: "some-sha-0000000000000000000000000000000",
Ref: "refs/heads/main",
WorkflowID: "nil.yml",
Title: "nil workflow_run",
}
require.NoError(t, db.Insert(ctx, run))
event, commitID, err := getCommitStatusEventNameAndCommitID(ctx, run)
require.NoError(t, err)
assert.Empty(t, event)
assert.Empty(t, commitID)
})
}

View File

@ -31,6 +31,9 @@ import (
"github.com/nektos/act/pkg/model"
)
// MaxWorkflowRunDepth is the maximum depth of recursive workflow_run event chains
const MaxWorkflowRunDepth = 5
type methodCtxKeyType struct{}
var methodCtxKey methodCtxKeyType
@ -264,7 +267,7 @@ func skipWorkflows(ctx context.Context, input *notifyInput, commit *git.Commit)
}
if input.Event == webhook_module.HookEventWorkflowRun {
wrun, ok := input.Payload.(*api.WorkflowRunPayload)
for i := 0; i < 5 && ok && wrun.WorkflowRun != nil; i++ {
for i := 0; i < MaxWorkflowRunDepth && ok && wrun.WorkflowRun != nil; i++ {
if wrun.WorkflowRun.Event != "workflow_run" {
return false
}
@ -279,8 +282,8 @@ func skipWorkflows(ctx context.Context, input *notifyInput, commit *git.Commit)
return true
}
}
// skip workflow runs events exceeding the maximum of 5 recursive events
log.Debug("repo %s: skipped workflow_run because of recursive event of 5", input.Repo.RelativePath())
// skip workflow_run events exceeding the maximum depth of recursive events
log.Debug("repo %s: skipped workflow_run because of recursive event of %d", input.Repo.RelativePath(), MaxWorkflowRunDepth)
return true
}
return false

View File

@ -1712,9 +1712,9 @@ jobs:
// 3. validate the webhook is triggered
assert.Equal(t, "workflow_run", webhookData.triggeredEvent)
// 1x push + 5x workflow_run requested chain
assert.Len(t, webhookData.payloads, 6)
for i := range 6 {
// 1x push + MaxWorkflowRunDepth workflow_run requested chain
assert.Len(t, webhookData.payloads, actions.MaxWorkflowRunDepth+1)
for i := range actions.MaxWorkflowRunDepth + 1 {
assert.Equal(t, "requested", webhookData.payloads[i].Action)
assert.Equal(t, "queued", webhookData.payloads[i].WorkflowRun.Status)
assert.Equal(t, repo1.DefaultBranch, webhookData.payloads[i].WorkflowRun.HeadBranch)