Fix repo badges when the label or text contains dashes

shields.io uses dashes to separate parts of the badge it needs to
return. If our label or text parts contain dashes, we need to encode
those for shields.io to recognise what we want it to do, and to have the
correct text on the badge, too.

Fortunately, this is as simple as replacing all dashes with double
dashes in both the label and the text parts. We do not need to do the
same for the color, because that part is not user controlled.

This fixes the badges for cases when a workflow name includes dashes, or
when a release's tag name does.

Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
This commit is contained in:
Gergely Nagy 2024-03-20 22:41:20 +01:00
parent 3fb488e80d
commit 8433f3aa09
No known key found for this signature in database
2 changed files with 30 additions and 4 deletions

View file

@ -18,8 +18,8 @@ import (
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(label),
"text": url.PathEscape(text),
"label": url.PathEscape(strings.ReplaceAll(label, "-", "--")),
"text": url.PathEscape(strings.ReplaceAll(text, "-", "--")),
"color": url.PathEscape(color),
})

View file

@ -12,13 +12,16 @@ import (
"testing"
actions_model "code.gitea.io/gitea/models/actions"
auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/services/release"
files_service "code.gitea.io/gitea/services/repository/files"
"code.gitea.io/gitea/tests"
@ -39,10 +42,14 @@ func TestBadges(t *testing.T) {
TreePath: ".gitea/workflows/pr.yml",
ContentReader: strings.NewReader("name: test\non:\n push:\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"),
},
{
Operation: "create",
TreePath: ".gitea/workflows/self-test.yaml",
ContentReader: strings.NewReader("name: test\non:\n push:\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"),
},
},
)
assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
assert.Equal(t, 2, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
return repo, f
}
@ -84,6 +91,11 @@ func TestBadges(t *testing.T) {
resp = MakeRequest(t, req, http.StatusSeeOther)
assertBadge(t, resp, "pr.yml-Not%20found-crimson")
// Workflow with a dash in its name
req = NewRequestf(t, "GET", "/user2/%s/badges/workflows/self-test.yaml/badge.svg", repo.Name)
resp = MakeRequest(t, req, http.StatusSeeOther)
assertBadge(t, resp, "self--test.yaml-waiting-lightgrey")
// GitHub compatibility
req = NewRequestf(t, "GET", "/user2/%s/actions/workflows/pr.yml/badge.svg", repo.Name)
resp = MakeRequest(t, req, http.StatusSeeOther)
@ -195,6 +207,20 @@ func TestBadges(t *testing.T) {
req = NewRequestf(t, "GET", "/user2/%s/badges/release.svg", repo.Name)
resp = MakeRequest(t, req, http.StatusSeeOther)
assertBadge(t, resp, "release-Not%20found-crimson")
t.Run("Dashes in the name", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
session := loginUser(t, repo.Owner.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
err := release.CreateNewTag(git.DefaultContext, repo.Owner, repo, "main", "repo-name-2.0", "dash in the tag name")
assert.NoError(t, err)
createNewReleaseUsingAPI(t, session, token, repo.Owner, repo, "repo-name-2.0", "main", "dashed release", "dashed release")
req := NewRequestf(t, "GET", "/user2/%s/badges/release.svg", repo.Name)
resp := MakeRequest(t, req, http.StatusSeeOther)
assertBadge(t, resp, "release-repo--name--2.0-blue")
})
})
})
}