mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-25 14:13:40 +09:00
Updates actionslib to https://gitea.com/gitea/actionslib/releases/tag/v1.2.1, moves workflow parsing into it and aligns behaviour with GitHub. 1. `uses:` supports `self:` (Gitea-only feature) and `$/` paths. 1. `strategy`, `matrix`, `max-parallel` and `fail-fast` accept expressions, including over `needs`. A job whose `name`, `runs-on` or `continue-on-error` reads `needs` is resolved once they finish. 1. A job `if:` may only read `github`, `needs`, `vars` and `inputs` and is decided before the matrix, as on github.com. 1. Matrix `fail-fast` cancels the other combinations, and `always()` jobs keep running when a run is cancelled. 1. Invalid workflow files, including a malformed `on:` and unknown or cyclic `needs`, show up on push as failed runs with the error. 1. A job whose `if:` or `concurrency:` fails to evaluate is skipped or failed with the error, instead of staying blocked. 1. Reusable workflows: a missing and an unreadable repository fail alike, public callers cannot use private workflows, nested jobs cannot exceed the caller's token permissions. 1. Runner labels match case-insensitively, and `runs-on` accepts an array from an expression. Runner PR: https://gitea.com/gitea/runner/pulls/1247 Docs PR: https://gitea.com/gitea/docs/pulls/553 Fixes: https://github.com/go-gitea/gitea/issues/38990 Fixes: https://github.com/go-gitea/gitea/issues/39382 Fixes: https://github.com/go-gitea/gitea/issues/32364 Fixes: https://github.com/go-gitea/gitea/issues/36077 Fixes: https://github.com/go-gitea/gitea/issues/23277 Fixes: https://github.com/go-gitea/gitea/issues/29020 Co-authored-by: Claude (Opus 5) <noreply@anthropic.com> Co-authored-by: Zettat123 <zettat123@gmail.com>
72 lines
2.8 KiB
Go
72 lines
2.8 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/json"
|
|
"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 := json.Marshal(input.Payload)
|
|
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
|
|
}
|
|
now := timeutil.TimeStampNow()
|
|
run := &actions_model.ActionRun{
|
|
Title: util.EllipsisDisplayString(commit.MessageTitle(), 255), 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: string(payload),
|
|
WorkflowRepoID: input.Repo.ID, WorkflowCommitSHA: commit.ID.String(), Status: actions_model.StatusFailure, Started: now, Stopped: now,
|
|
}
|
|
if err := db.WithTx(ctx, func(ctx context.Context) 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", entryName, 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", entryName, err)
|
|
continue
|
|
}
|
|
if err := createWorkflowCommitStatus(ctx, run.Repo, run.CommitSHA, entryName+" ("+run.TriggerEvent+")", run.WorkflowID,
|
|
commitstatus.CommitStatusFailure, run.Link(), "Invalid workflow file"); err != nil {
|
|
log.Error("create commit status for invalid workflow %q: %v", entryName, err)
|
|
}
|
|
NotifyWorkflowRunStatusUpdate(ctx, run)
|
|
}
|
|
}
|