mirror of https://github.com/go-gitea/gitea
Implement actions badge svgs (#28102)
replace #27187 close #23688 The badge has two parts: label(workflow name) and message(action status). 5 colors are provided with 7 statuses. Color mapping: ```go var statusColorMap = map[actions_model.Status]string{ actions_model.StatusSuccess: "#4c1", // Green actions_model.StatusSkipped: "#dfb317", // Yellow actions_model.StatusUnknown: "#97ca00", // Light Green actions_model.StatusFailure: "#e05d44", // Red actions_model.StatusCancelled: "#fe7d37", // Orange actions_model.StatusWaiting: "#dfb317", // Yellow actions_model.StatusRunning: "#dfb317", // Yellow actions_model.StatusBlocked: "#dfb317", // Yellow } ``` preview: ![1](https://github.com/go-gitea/gitea/assets/70063547/5465cbaf-23cd-4437-9848-2738c3cb8985) ![2](https://github.com/go-gitea/gitea/assets/70063547/ec393d26-c6e6-4d38-b72c-51f2494c5e71) ![3](https://github.com/go-gitea/gitea/assets/70063547/3edb4fdf-1b08-4a02-ab2a-6bdd7f532fb2) ![4](https://github.com/go-gitea/gitea/assets/70063547/8c189de2-2169-4251-b115-0e39a52f3df8) ![5](https://github.com/go-gitea/gitea/assets/70063547/3fe22c73-c2d7-4fec-9ea4-c501a1e4e3bd) --------- Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Giteabot <teabot@gitea.io> Co-authored-by: delvh <dev.lh@web.de>pull/27183/merge
parent
e9f4c2db82
commit
db545b208b
@ -0,0 +1,37 @@ |
|||||||
|
--- |
||||||
|
date: "2023-02-25T00:00:00+00:00" |
||||||
|
title: "Badge" |
||||||
|
slug: "badge" |
||||||
|
sidebar_position: 11 |
||||||
|
toc: false |
||||||
|
draft: false |
||||||
|
aliases: |
||||||
|
- /en-us/badge |
||||||
|
menu: |
||||||
|
sidebar: |
||||||
|
parent: "usage" |
||||||
|
name: "Badge" |
||||||
|
sidebar_position: 11 |
||||||
|
identifier: "Badge" |
||||||
|
--- |
||||||
|
|
||||||
|
# Badge |
||||||
|
|
||||||
|
Gitea has its builtin Badge system which allows you to display the status of your repository in other places. You can use the following badges: |
||||||
|
|
||||||
|
## Workflow Badge |
||||||
|
|
||||||
|
The Gitea Actions workflow badge is a badge that shows the status of the latest workflow run. |
||||||
|
It is designed to be compatible with [GitHub Actions workflow badge](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge). |
||||||
|
|
||||||
|
You can use the following URL to get the badge: |
||||||
|
|
||||||
|
``` |
||||||
|
https://your-gitea-instance.com/{owner}/{repo}/actions/workflows/{workflow_file}?branch={branch}&event={event} |
||||||
|
``` |
||||||
|
|
||||||
|
- `{owner}`: The owner of the repository. |
||||||
|
- `{repo}`: The name of the repository. |
||||||
|
- `{workflow_file}`: The name of the workflow file. |
||||||
|
- `{branch}`: Optional. The branch of the workflow. Default to your repository's default branch. |
||||||
|
- `{event}`: Optional. The event of the workflow. Default to none. |
@ -0,0 +1,104 @@ |
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package badge |
||||||
|
|
||||||
|
import ( |
||||||
|
actions_model "code.gitea.io/gitea/models/actions" |
||||||
|
) |
||||||
|
|
||||||
|
// The Badge layout: |offset|label|message|
|
||||||
|
// We use 10x scale to calculate more precisely
|
||||||
|
// Then scale down to normal size in tmpl file
|
||||||
|
|
||||||
|
type Label struct { |
||||||
|
text string |
||||||
|
width int |
||||||
|
} |
||||||
|
|
||||||
|
func (l Label) Text() string { |
||||||
|
return l.text |
||||||
|
} |
||||||
|
|
||||||
|
func (l Label) Width() int { |
||||||
|
return l.width |
||||||
|
} |
||||||
|
|
||||||
|
func (l Label) TextLength() int { |
||||||
|
return int(float64(l.width-defaultOffset) * 9.5) |
||||||
|
} |
||||||
|
|
||||||
|
func (l Label) X() int { |
||||||
|
return l.width*5 + 10 |
||||||
|
} |
||||||
|
|
||||||
|
type Message struct { |
||||||
|
text string |
||||||
|
width int |
||||||
|
x int |
||||||
|
} |
||||||
|
|
||||||
|
func (m Message) Text() string { |
||||||
|
return m.text |
||||||
|
} |
||||||
|
|
||||||
|
func (m Message) Width() int { |
||||||
|
return m.width |
||||||
|
} |
||||||
|
|
||||||
|
func (m Message) X() int { |
||||||
|
return m.x |
||||||
|
} |
||||||
|
|
||||||
|
func (m Message) TextLength() int { |
||||||
|
return int(float64(m.width-defaultOffset) * 9.5) |
||||||
|
} |
||||||
|
|
||||||
|
type Badge struct { |
||||||
|
Color string |
||||||
|
FontSize int |
||||||
|
Label Label |
||||||
|
Message Message |
||||||
|
} |
||||||
|
|
||||||
|
func (b Badge) Width() int { |
||||||
|
return b.Label.width + b.Message.width |
||||||
|
} |
||||||
|
|
||||||
|
const ( |
||||||
|
defaultOffset = 9 |
||||||
|
defaultFontSize = 11 |
||||||
|
DefaultColor = "#9f9f9f" // Grey
|
||||||
|
defaultFontWidth = 7 // approximate speculation
|
||||||
|
) |
||||||
|
|
||||||
|
var StatusColorMap = map[actions_model.Status]string{ |
||||||
|
actions_model.StatusSuccess: "#4c1", // Green
|
||||||
|
actions_model.StatusSkipped: "#dfb317", // Yellow
|
||||||
|
actions_model.StatusUnknown: "#97ca00", // Light Green
|
||||||
|
actions_model.StatusFailure: "#e05d44", // Red
|
||||||
|
actions_model.StatusCancelled: "#fe7d37", // Orange
|
||||||
|
actions_model.StatusWaiting: "#dfb317", // Yellow
|
||||||
|
actions_model.StatusRunning: "#dfb317", // Yellow
|
||||||
|
actions_model.StatusBlocked: "#dfb317", // Yellow
|
||||||
|
} |
||||||
|
|
||||||
|
// GenerateBadge generates badge with given template
|
||||||
|
func GenerateBadge(label, message, color string) Badge { |
||||||
|
lw := defaultFontWidth*len(label) + defaultOffset |
||||||
|
mw := defaultFontWidth*len(message) + defaultOffset |
||||||
|
x := lw*10 + mw*5 - 10 |
||||||
|
return Badge{ |
||||||
|
Label: Label{ |
||||||
|
text: label, |
||||||
|
width: lw, |
||||||
|
}, |
||||||
|
Message: Message{ |
||||||
|
text: message, |
||||||
|
width: mw, |
||||||
|
x: x, |
||||||
|
}, |
||||||
|
FontSize: defaultFontSize * 10, |
||||||
|
Color: color, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package actions |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"net/http" |
||||||
|
"path/filepath" |
||||||
|
"strings" |
||||||
|
|
||||||
|
actions_model "code.gitea.io/gitea/models/actions" |
||||||
|
"code.gitea.io/gitea/modules/badge" |
||||||
|
"code.gitea.io/gitea/modules/util" |
||||||
|
"code.gitea.io/gitea/services/context" |
||||||
|
) |
||||||
|
|
||||||
|
func GetWorkflowBadge(ctx *context.Context) { |
||||||
|
workflowFile := ctx.Params("workflow_name") |
||||||
|
branch := ctx.Req.URL.Query().Get("branch") |
||||||
|
if branch == "" { |
||||||
|
branch = ctx.Repo.Repository.DefaultBranch |
||||||
|
} |
||||||
|
branchRef := fmt.Sprintf("refs/heads/%s", branch) |
||||||
|
event := ctx.Req.URL.Query().Get("event") |
||||||
|
|
||||||
|
badge, err := getWorkflowBadge(ctx, workflowFile, branchRef, event) |
||||||
|
if err != nil { |
||||||
|
ctx.ServerError("GetWorkflowBadge", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
ctx.Data["Badge"] = badge |
||||||
|
ctx.RespHeader().Set("Content-Type", "image/svg+xml") |
||||||
|
ctx.HTML(http.StatusOK, "shared/actions/runner_badge") |
||||||
|
} |
||||||
|
|
||||||
|
func getWorkflowBadge(ctx *context.Context, workflowFile, branchName, event string) (badge.Badge, error) { |
||||||
|
extension := filepath.Ext(workflowFile) |
||||||
|
workflowName := strings.TrimSuffix(workflowFile, extension) |
||||||
|
|
||||||
|
run, err := actions_model.GetWorkflowLatestRun(ctx, ctx.Repo.Repository.ID, workflowFile, branchName, event) |
||||||
|
if err != nil { |
||||||
|
if errors.Is(err, util.ErrNotExist) { |
||||||
|
return badge.GenerateBadge(workflowName, "no status", badge.DefaultColor), nil |
||||||
|
} |
||||||
|
return badge.Badge{}, err |
||||||
|
} |
||||||
|
|
||||||
|
color, ok := badge.StatusColorMap[run.Status] |
||||||
|
if !ok { |
||||||
|
return badge.GenerateBadge(workflowName, "unknown status", badge.DefaultColor), nil |
||||||
|
} |
||||||
|
return badge.GenerateBadge(workflowName, run.Status.String(), color), nil |
||||||
|
} |
After Width: | Height: | Size: 1.7 KiB |
Loading…
Reference in new issue