diff --git a/models/actions/run.go b/models/actions/run.go index 8078613fb8f5b..cfb36eeb75352 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -335,6 +335,21 @@ func GetRunByIndex(ctx context.Context, repoID, index int64) (*ActionRun, error) return run, nil } +func GetRepoBranchLastRun(ctx context.Context, repoID int64, branch, workflowFile string) (*ActionRun, error) { + var run ActionRun + has, err := db.GetEngine(ctx).Where("repo_id=?", repoID). + And("ref = ?", branch). + And("workflow_id = ?", workflowFile). + Desc("id"). + Get(&run) + if err != nil { + return nil, err + } else if !has { + return nil, util.NewNotExistErrorf("run with repo_id %d, ref %s, workflow_id %s", repoID, branch, workflowFile) + } + return &run, nil +} + // UpdateRun updates a run. // It requires the inputted run has Version set. // It will return error if the version is not matched (it means the run has been changed after loaded). diff --git a/public/assets/img/svg/gitea_actions_failed.svg b/public/assets/img/svg/gitea_actions_failed.svg new file mode 100644 index 0000000000000..f862e6935ecf8 --- /dev/null +++ b/public/assets/img/svg/gitea_actions_failed.svg @@ -0,0 +1,20 @@ + + Gitea Actions: FAILED + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/img/svg/gitea_actions_pass.svg b/public/assets/img/svg/gitea_actions_pass.svg new file mode 100644 index 0000000000000..cf9f0154f4deb --- /dev/null +++ b/public/assets/img/svg/gitea_actions_pass.svg @@ -0,0 +1,20 @@ + + Gitea Actions: PASS + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/img/svg/gitea_actions_pending.svg b/public/assets/img/svg/gitea_actions_pending.svg new file mode 100644 index 0000000000000..1fdadfedfb3de --- /dev/null +++ b/public/assets/img/svg/gitea_actions_pending.svg @@ -0,0 +1,20 @@ + + Gitea Actions: PENDING + + + + + + + + + + + + + \ No newline at end of file diff --git a/routers/web/repo/actions/badge.go b/routers/web/repo/actions/badge.go new file mode 100644 index 0000000000000..a9bca5209b0a1 --- /dev/null +++ b/routers/web/repo/actions/badge.go @@ -0,0 +1,48 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "errors" + "fmt" + "strings" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" +) + +func GetWorkflowBadge(ctx *context.Context) { + workflowFile := ctx.PathParamRaw("*") + if !strings.HasSuffix(workflowFile, "/badge.svg") { + ctx.NotFound("Not found", fmt.Errorf("%s not a badge request", ctx.Req.URL.Path)) + return + } + + workflowFile = strings.TrimSuffix(workflowFile, "/badge.svg") + run, err := actions_model.GetRepoBranchLastRun(ctx, ctx.Repo.Repository.ID, + git.RefNameFromBranch(ctx.Repo.Repository.DefaultBranch).String(), + workflowFile) + if err != nil { + if errors.Is(err, util.ErrNotExist) { + ctx.NotFound("Not found", fmt.Errorf("%s not found", workflowFile)) + return + } + ctx.ServerError("GetWorkflowBadge", err) + return + } + + switch run.Status { + case actions_model.StatusSuccess, actions_model.StatusSkipped: + ctx.Redirect(setting.AbsoluteAssetURL + "/assets/img/svg/gitea_actions_pass.svg") + case actions_model.StatusUnknown, actions_model.StatusFailure, actions_model.StatusCancelled: + ctx.Redirect(setting.AbsoluteAssetURL + "/assets/img/svg/gitea_actions_failed.svg") + case actions_model.StatusWaiting, actions_model.StatusRunning, actions_model.StatusBlocked: + ctx.Redirect(setting.AbsoluteAssetURL + "/assets/img/svg/gitea_actions_pending.svg") + default: + ctx.NotFound("Not found", fmt.Errorf("unknown status %d", run.Status)) + } +} diff --git a/routers/web/web.go b/routers/web/web.go index 99862505b48a1..d71716b159991 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1330,6 +1330,9 @@ func registerRoutes(m *web.Route) { m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView) m.Post("/rerun", reqRepoActionsWriter, actions.Rerun) }) + m.Group("/workflows", func() { + m.Get("/*", actions.GetWorkflowBadge) + }) }, reqRepoActionsReader, actions.MustEnableActions) m.Group("/wiki", func() {