From 8433f3aa09cad7e245025545912667e0ec1cc0c6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Mar 2024 22:41:20 +0100 Subject: [PATCH] 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 --- routers/web/repo/badges/badges.go | 4 ++-- tests/integration/repo_badges_test.go | 30 +++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/routers/web/repo/badges/badges.go b/routers/web/repo/badges/badges.go index 7f4549d606..ed40e982a1 100644 --- a/routers/web/repo/badges/badges.go +++ b/routers/web/repo/badges/badges.go @@ -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), }) diff --git a/tests/integration/repo_badges_test.go b/tests/integration/repo_badges_test.go index b7020bbadd..dbf6acb098 100644 --- a/tests/integration/repo_badges_test.go +++ b/tests/integration/repo_badges_test.go @@ -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") + }) }) }) }