Files
gitea/modules/actions/scoped_workflows.go

89 lines
2.7 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"gitea.dev/modules/actions/jobparser"
"gitea.dev/modules/git"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
api "gitea.dev/modules/structs"
webhook_module "gitea.dev/modules/webhook"
)
// ListScopedWorkflows lists scoped workflow files (under SCOPED_WORKFLOW_DIRS) at the given commit.
func ListScopedWorkflows(commit *git.Commit) (string, git.Entries, error) {
return listWorkflowsInDirs(commit, setting.Actions.ScopedWorkflowDirs)
}
// ParsedScopedWorkflow is one scoped workflow's source-side parse result
type ParsedScopedWorkflow struct {
EntryName string
DisplayName string // the workflow `name:` or base file name
Content []byte // raw content of the workflow file
Events []*jobparser.Event // decoded `on:` events
}
// ParseScopedWorkflows lists and parses the scoped workflow files at sourceCommit (under SCOPED_WORKFLOW_DIRS).
func ParseScopedWorkflows(sourceCommit *git.Commit) ([]*ParsedScopedWorkflow, error) {
_, entries, err := ListScopedWorkflows(sourceCommit)
if err != nil {
return nil, err
}
parsed := make([]*ParsedScopedWorkflow, 0, len(entries))
for _, entry := range entries {
content, err := GetContentFromEntry(entry)
if err != nil {
return nil, err
}
// one workflow may have multiple events
events, err := GetEventsFromContent(content)
if err != nil {
log.Warn("ignore invalid scoped workflow %q: %v", entry.Name(), err)
continue
}
parsed = append(parsed, &ParsedScopedWorkflow{
EntryName: entry.Name(),
DisplayName: WorkflowDisplayName(entry.Name(), content),
Content: content,
Events: events,
})
}
return parsed, nil
}
// MatchScopedWorkflows evaluates already-parsed scoped workflows against one consuming event.
// It returns the workflows whose `on:` matches, and those that matched the event but were excluded by a branch/paths filter (filtered).
func MatchScopedWorkflows(
parsed []*ParsedScopedWorkflow,
consumerGitRepo *git.Repository,
consumerCommit *git.Commit,
triggedEvent webhook_module.HookEventType,
payload api.Payloader,
) (matched, filtered []*DetectedWorkflow) {
for _, p := range parsed {
for _, evt := range p.Events {
if evt.IsSchedule() {
// schedule is a non-target for scoped workflows
continue
}
dwf := &DetectedWorkflow{
EntryName: p.EntryName,
TriggerEvent: evt,
Content: p.Content,
}
switch detectWorkflowMatch(consumerGitRepo, consumerCommit, triggedEvent, payload, evt) {
case detectMatched:
matched = append(matched, dwf)
case detectFilteredOut:
filtered = append(filtered, dwf)
case detectNotApplicable:
}
}
}
return matched, filtered
}