mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-15 10:55:49 +00:00
ef4c6abbb9
Previously, if no branch was explicitly specified for a workflow, it
defaulted to the default branch of the repo. This worked fine for
workflows that were triggered on push, but it prevented showing badges
for workflows that only run on tags, or on schedule - since they do not
run on a specific branch.
Thus, relax the conditions, and if no branch is specified, just return
the latest run of the given workflow. If one is specified, *then*
restrict it to said branch.
Fixes #3487.
Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
(cherry picked from commit d6915f4d5f
)
165 lines
4.5 KiB
Go
165 lines
4.5 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package badges
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
|
|
actions_model "code.gitea.io/gitea/models/actions"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
"code.gitea.io/gitea/models/unit"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
context_module "code.gitea.io/gitea/services/context"
|
|
)
|
|
|
|
func getBadgeURL(ctx *context_module.Context, label, text, color string) string {
|
|
sb := &strings.Builder{}
|
|
_ = setting.Badges.GeneratorURLTemplateTemplate.Execute(sb, map[string]string{
|
|
"label": url.PathEscape(strings.ReplaceAll(label, "-", "--")),
|
|
"text": url.PathEscape(strings.ReplaceAll(text, "-", "--")),
|
|
"color": url.PathEscape(color),
|
|
})
|
|
|
|
badgeURL := sb.String()
|
|
q := ctx.Req.URL.Query()
|
|
// Remove any `branch` or `event` query parameters. They're used by the
|
|
// workflow badge route, and do not need forwarding to the badge generator.
|
|
delete(q, "branch")
|
|
delete(q, "event")
|
|
if len(q) > 0 {
|
|
return fmt.Sprintf("%s?%s", badgeURL, q.Encode())
|
|
}
|
|
return badgeURL
|
|
}
|
|
|
|
func redirectToBadge(ctx *context_module.Context, label, text, color string) {
|
|
ctx.Redirect(getBadgeURL(ctx, label, text, color))
|
|
}
|
|
|
|
func errorBadge(ctx *context_module.Context, label, text string) {
|
|
ctx.Redirect(getBadgeURL(ctx, label, text, "crimson"))
|
|
}
|
|
|
|
func GetWorkflowBadge(ctx *context_module.Context) {
|
|
branch := ctx.Req.URL.Query().Get("branch")
|
|
if branch != "" {
|
|
branch = fmt.Sprintf("refs/heads/%s", branch)
|
|
}
|
|
event := ctx.Req.URL.Query().Get("event")
|
|
|
|
workflowFile := ctx.Params("workflow_name")
|
|
run, err := actions_model.GetLatestRunForBranchAndWorkflow(ctx, ctx.Repo.Repository.ID, branch, workflowFile, event)
|
|
if err != nil {
|
|
errorBadge(ctx, workflowFile, "Not found")
|
|
return
|
|
}
|
|
|
|
var color string
|
|
switch run.Status {
|
|
case actions_model.StatusUnknown:
|
|
color = "lightgrey"
|
|
case actions_model.StatusWaiting:
|
|
color = "lightgrey"
|
|
case actions_model.StatusRunning:
|
|
color = "gold"
|
|
case actions_model.StatusSuccess:
|
|
color = "brightgreen"
|
|
case actions_model.StatusFailure:
|
|
color = "crimson"
|
|
case actions_model.StatusCancelled:
|
|
color = "orange"
|
|
case actions_model.StatusSkipped:
|
|
color = "blue"
|
|
case actions_model.StatusBlocked:
|
|
color = "yellow"
|
|
default:
|
|
color = "lightgrey"
|
|
}
|
|
|
|
redirectToBadge(ctx, workflowFile, run.Status.String(), color)
|
|
}
|
|
|
|
func getIssueOrPullBadge(ctx *context_module.Context, label, variant string, num int) {
|
|
var text string
|
|
if len(variant) > 0 {
|
|
text = fmt.Sprintf("%d %s", num, variant)
|
|
} else {
|
|
text = fmt.Sprintf("%d", num)
|
|
}
|
|
redirectToBadge(ctx, label, text, "blue")
|
|
}
|
|
|
|
func getIssueBadge(ctx *context_module.Context, variant string, num int) {
|
|
if !ctx.Repo.CanRead(unit.TypeIssues) &&
|
|
!ctx.Repo.CanRead(unit.TypeExternalTracker) {
|
|
errorBadge(ctx, "issues", "Not found")
|
|
return
|
|
}
|
|
|
|
_, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalTracker)
|
|
if err == nil {
|
|
errorBadge(ctx, "issues", "Not found")
|
|
return
|
|
}
|
|
|
|
getIssueOrPullBadge(ctx, "issues", variant, num)
|
|
}
|
|
|
|
func getPullBadge(ctx *context_module.Context, variant string, num int) {
|
|
if !ctx.Repo.Repository.CanEnablePulls() || !ctx.Repo.CanRead(unit.TypePullRequests) {
|
|
errorBadge(ctx, "pulls", "Not found")
|
|
return
|
|
}
|
|
|
|
getIssueOrPullBadge(ctx, "pulls", variant, num)
|
|
}
|
|
|
|
func GetOpenIssuesBadge(ctx *context_module.Context) {
|
|
getIssueBadge(ctx, "open", ctx.Repo.Repository.NumOpenIssues)
|
|
}
|
|
|
|
func GetClosedIssuesBadge(ctx *context_module.Context) {
|
|
getIssueBadge(ctx, "closed", ctx.Repo.Repository.NumClosedIssues)
|
|
}
|
|
|
|
func GetTotalIssuesBadge(ctx *context_module.Context) {
|
|
getIssueBadge(ctx, "", ctx.Repo.Repository.NumIssues)
|
|
}
|
|
|
|
func GetOpenPullsBadge(ctx *context_module.Context) {
|
|
getPullBadge(ctx, "open", ctx.Repo.Repository.NumOpenPulls)
|
|
}
|
|
|
|
func GetClosedPullsBadge(ctx *context_module.Context) {
|
|
getPullBadge(ctx, "closed", ctx.Repo.Repository.NumClosedPulls)
|
|
}
|
|
|
|
func GetTotalPullsBadge(ctx *context_module.Context) {
|
|
getPullBadge(ctx, "", ctx.Repo.Repository.NumPulls)
|
|
}
|
|
|
|
func GetStarsBadge(ctx *context_module.Context) {
|
|
redirectToBadge(ctx, "stars", fmt.Sprintf("%d", ctx.Repo.Repository.NumStars), "blue")
|
|
}
|
|
|
|
func GetLatestReleaseBadge(ctx *context_module.Context) {
|
|
release, err := repo_model.GetLatestReleaseByRepoID(ctx, ctx.Repo.Repository.ID)
|
|
if err != nil {
|
|
if repo_model.IsErrReleaseNotExist(err) {
|
|
errorBadge(ctx, "release", "Not found")
|
|
return
|
|
}
|
|
ctx.ServerError("GetLatestReleaseByRepoID", err)
|
|
}
|
|
|
|
if err := release.LoadAttributes(ctx); err != nil {
|
|
ctx.ServerError("LoadAttributes", err)
|
|
return
|
|
}
|
|
|
|
redirectToBadge(ctx, "release", release.TagName, "blue")
|
|
}
|