Files
c30ddc3e14 refactor(actions): small cleanups across models, services and routers (#39722)
Collection of small, behaviour-preserving cleanups in the Actions code.

- Fix log and error prefixes that named non-existent or wrong functions,
and wrap errors with `%w` so `errors.Is` keeps working.
- Remove unused code.
- Rely on `ctx.ServerError` / `ctx.APIErrorAuto`, which already map
`util.ErrNotExist` and friends, instead of equivalent hand-written
switches.
- Load runs referenced by commit statuses with one query instead of one
per run (used on every PR view); the result order is now stable.
- Encode an event's payload once instead of up to three times.
- Share the duplicated runner-token "get or create" logic and the
"notify and emit" call pair.
- Simplify `ToActionArtifact` / `ToActionRunner` signatures.

---------

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-10 12:55:28 +00:00

77 lines
3.0 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"context"
"fmt"
actions_model "gitea.dev/models/actions"
"gitea.dev/models/db"
"gitea.dev/models/unit"
"gitea.dev/modules/commitstatus"
"gitea.dev/modules/git"
"gitea.dev/modules/log"
"gitea.dev/modules/timeutil"
"gitea.dev/modules/util"
)
func handleInvalidWorkflows(ctx context.Context, input *notifyInput, ref git.RefName, commit *git.Commit, invalid map[string]error) {
if len(invalid) == 0 {
return
}
payload, err := input.EncodedPayload()
if err != nil {
log.Error("marshal event payload: %v", err)
return
}
actionsConfig := input.Repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig()
for entryName, parseErr := range invalid {
if actionsConfig.IsWorkflowDisabled(entryName) {
continue
}
insertInvalidWorkflowRun(ctx, &actions_model.ActionRun{
Title: commit.MessageTitle(), RepoID: input.Repo.ID, Repo: input.Repo, OwnerID: input.Repo.OwnerID,
WorkflowID: entryName, TriggerUserID: input.Doer.ID, TriggerUser: input.Doer, Ref: ref.String(),
CommitSHA: commit.ID.String(), Event: input.Event, TriggerEvent: string(input.Event), EventPayload: payload,
WorkflowRepoID: input.Repo.ID, WorkflowCommitSHA: commit.ID.String(),
}, parseErr)
}
}
// insertInvalidWorkflowRun records run as failed with parseErr as its summary.
func insertInvalidWorkflowRun(ctx context.Context, run *actions_model.ActionRun, parseErr error) {
now := timeutil.TimeStampNow()
run.Title = util.EllipsisDisplayString(run.Title, 255)
run.Status, run.Started, run.Stopped = actions_model.StatusFailure, now, now
if err := db.WithTx(ctx, func(ctx context.Context) (err error) {
if run.Index, err = db.GetNextResourceIndex(ctx, "action_run_index", run.RepoID); err != nil {
return err
}
if err := db.Insert(ctx, run); err != nil {
return err
}
attempt := &actions_model.ActionRunAttempt{RepoID: run.RepoID, RunID: run.ID, Attempt: 1, TriggerUserID: run.TriggerUserID, Status: run.Status, Started: now, Stopped: now}
if err := db.Insert(ctx, attempt); err != nil {
return err
}
run.LatestAttemptID = attempt.ID
if err := actions_model.UpdateRun(ctx, run, "latest_attempt_id"); err != nil {
return err
}
content := fmt.Sprintf("**Invalid workflow file: %s**\n\n```\n%v\n```\n", run.WorkflowID, parseErr)
return db.Insert(ctx, &actions_model.ActionRunJobSummary{
RepoID: run.RepoID, RunID: run.ID, RunAttemptID: attempt.ID, Content: content, ContentSize: int64(len(content)), ContentType: actions_model.JobSummaryContentTypeMarkdown,
})
}); err != nil {
log.Error("insert run for invalid workflow %q: %v", run.WorkflowID, err)
return
}
if err := createWorkflowCommitStatus(ctx, run.Repo, run.CommitSHA, run.WorkflowID+" ("+run.TriggerEvent+")", run.WorkflowID,
commitstatus.CommitStatusFailure, run.Link(), "Invalid workflow file", false); err != nil {
log.Error("create commit status for invalid workflow %q: %v", run.WorkflowID, err)
}
NotifyWorkflowRunStatusUpdate(ctx, run)
}