From 015efcd8bfd451ef593192eb43cfcfb7001f7861 Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Thu, 30 May 2024 15:04:01 +0800
Subject: [PATCH] Use repo as of renderctx's member rather than a repoPath on
 metas (#29222)

Use a `gitrepo.Repository` in the markup's RenderContext but not store
the repository's path.
---
 models/issues/comment_code.go            |  3 +-
 models/repo/repo.go                      |  7 ++--
 modules/gitrepo/url.go                   |  8 ++++
 modules/markup/html.go                   | 11 +++---
 modules/markup/html_test.go              | 41 +++++++++++++-------
 modules/markup/main_test.go              | 14 +++++++
 modules/markup/markdown/main_test.go     | 21 ++++++++++
 modules/markup/markdown/markdown_test.go | 49 ++++++++++++++----------
 modules/markup/renderer.go               |  2 +
 routers/common/markup.go                 |  6 ++-
 routers/web/feed/convert.go              |  3 +-
 routers/web/repo/commit.go               |  1 +
 routers/web/repo/issue.go                |  5 +++
 routers/web/repo/milestone.go            |  2 +
 routers/web/repo/projects.go             |  2 +
 routers/web/repo/release.go              |  1 +
 routers/web/user/home.go                 |  1 +
 services/mailer/mail.go                  |  3 +-
 services/mailer/mail_release.go          |  3 +-
 19 files changed, 135 insertions(+), 48 deletions(-)
 create mode 100644 modules/gitrepo/url.go
 create mode 100644 modules/markup/main_test.go
 create mode 100644 modules/markup/markdown/main_test.go

diff --git a/models/issues/comment_code.go b/models/issues/comment_code.go
index f860dacfac..6f23d3326a 100644
--- a/models/issues/comment_code.go
+++ b/models/issues/comment_code.go
@@ -113,7 +113,8 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
 
 		var err error
 		if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
-			Ctx: ctx,
+			Ctx:  ctx,
+			Repo: issue.Repo,
 			Links: markup.Links{
 				Base: issue.Repo.Link(),
 			},
diff --git a/models/repo/repo.go b/models/repo/repo.go
index 5d5707d1ac..f02c55fc89 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -472,10 +472,9 @@ func (repo *Repository) MustOwner(ctx context.Context) *user_model.User {
 func (repo *Repository) ComposeMetas(ctx context.Context) map[string]string {
 	if len(repo.RenderingMetas) == 0 {
 		metas := map[string]string{
-			"user":     repo.OwnerName,
-			"repo":     repo.Name,
-			"repoPath": repo.RepoPath(),
-			"mode":     "comment",
+			"user": repo.OwnerName,
+			"repo": repo.Name,
+			"mode": "comment",
 		}
 
 		unit, err := repo.GetUnit(ctx, unit.TypeExternalTracker)
diff --git a/modules/gitrepo/url.go b/modules/gitrepo/url.go
new file mode 100644
index 0000000000..b355d0fa93
--- /dev/null
+++ b/modules/gitrepo/url.go
@@ -0,0 +1,8 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package gitrepo
+
+func RepoGitURL(repo Repository) string {
+	return repoPath(repo)
+}
diff --git a/modules/markup/html.go b/modules/markup/html.go
index 2958dc9646..0af74d2680 100644
--- a/modules/markup/html.go
+++ b/modules/markup/html.go
@@ -16,7 +16,7 @@ import (
 
 	"code.gitea.io/gitea/modules/base"
 	"code.gitea.io/gitea/modules/emoji"
-	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/markup/common"
 	"code.gitea.io/gitea/modules/references"
@@ -1140,7 +1140,7 @@ func emojiProcessor(ctx *RenderContext, node *html.Node) {
 // hashCurrentPatternProcessor renders SHA1 strings to corresponding links that
 // are assumed to be in the same repository.
 func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
-	if ctx.Metas == nil || ctx.Metas["user"] == "" || ctx.Metas["repo"] == "" || ctx.Metas["repoPath"] == "" {
+	if ctx.Metas == nil || ctx.Metas["user"] == "" || ctx.Metas["repo"] == "" || (ctx.Repo == nil && ctx.GitRepo == nil) {
 		return
 	}
 
@@ -1172,13 +1172,14 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
 		if !inCache {
 			if ctx.GitRepo == nil {
 				var err error
-				ctx.GitRepo, err = git.OpenRepository(ctx.Ctx, ctx.Metas["repoPath"])
+				var closer io.Closer
+				ctx.GitRepo, closer, err = gitrepo.RepositoryFromContextOrOpen(ctx.Ctx, ctx.Repo)
 				if err != nil {
-					log.Error("unable to open repository: %s Error: %v", ctx.Metas["repoPath"], err)
+					log.Error("unable to open repository: %s Error: %v", gitrepo.RepoGitURL(ctx.Repo), err)
 					return
 				}
 				ctx.AddCancel(func() {
-					ctx.GitRepo.Close()
+					closer.Close()
 					ctx.GitRepo = nil
 				})
 			}
diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go
index a2ae18d777..0091397768 100644
--- a/modules/markup/html_test.go
+++ b/modules/markup/html_test.go
@@ -4,16 +4,13 @@
 package markup_test
 
 import (
-	"context"
 	"io"
-	"os"
 	"strings"
 	"testing"
 
-	"code.gitea.io/gitea/models/unittest"
 	"code.gitea.io/gitea/modules/emoji"
 	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/markup"
 	"code.gitea.io/gitea/modules/markup/markdown"
 	"code.gitea.io/gitea/modules/setting"
@@ -22,18 +19,33 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-var localMetas = map[string]string{
-	"user":     "gogits",
-	"repo":     "gogs",
-	"repoPath": "../../tests/gitea-repositories-meta/user13/repo11.git/",
+var (
+	testRepoOwnerName = "user13"
+	testRepoName      = "repo11"
+	localMetas        = map[string]string{
+		"user": testRepoOwnerName,
+		"repo": testRepoName,
+	}
+)
+
+type mockRepo struct {
+	OwnerName string
+	RepoName  string
 }
 
-func TestMain(m *testing.M) {
-	unittest.InitSettings()
-	if err := git.InitSimple(context.Background()); err != nil {
-		log.Fatal("git init failed, err: %v", err)
+func (m *mockRepo) GetOwnerName() string {
+	return m.OwnerName
+}
+
+func (m *mockRepo) GetName() string {
+	return m.RepoName
+}
+
+func newMockRepo(ownerName, repoName string) gitrepo.Repository {
+	return &mockRepo{
+		OwnerName: ownerName,
+		RepoName:  repoName,
 	}
-	os.Exit(m.Run())
 }
 
 func TestRender_Commits(t *testing.T) {
@@ -46,6 +58,7 @@ func TestRender_Commits(t *testing.T) {
 				AbsolutePrefix: true,
 				Base:           markup.TestRepoURL,
 			},
+			Repo:  newMockRepo(testRepoOwnerName, testRepoName),
 			Metas: localMetas,
 		}, input)
 		assert.NoError(t, err)
@@ -53,7 +66,7 @@ func TestRender_Commits(t *testing.T) {
 	}
 
 	sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
-	repo := markup.TestRepoURL
+	repo := markup.TestAppURL + testRepoOwnerName + "/" + testRepoName + "/"
 	commit := util.URLJoin(repo, "commit", sha)
 	tree := util.URLJoin(repo, "tree", sha, "src")
 
diff --git a/modules/markup/main_test.go b/modules/markup/main_test.go
new file mode 100644
index 0000000000..a8f6f1c564
--- /dev/null
+++ b/modules/markup/main_test.go
@@ -0,0 +1,14 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package markup_test
+
+import (
+	"testing"
+
+	"code.gitea.io/gitea/models/unittest"
+)
+
+func TestMain(m *testing.M) {
+	unittest.MainTest(m)
+}
diff --git a/modules/markup/markdown/main_test.go b/modules/markup/markdown/main_test.go
new file mode 100644
index 0000000000..f33eeb13b2
--- /dev/null
+++ b/modules/markup/markdown/main_test.go
@@ -0,0 +1,21 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package markdown
+
+import (
+	"context"
+	"testing"
+
+	"code.gitea.io/gitea/models/unittest"
+	"code.gitea.io/gitea/modules/markup"
+)
+
+func TestMain(m *testing.M) {
+	markup.Init(&markup.ProcessorHelper{
+		IsUsernameMentionable: func(ctx context.Context, username string) bool {
+			return username == "r-lyeh"
+		},
+	})
+	unittest.MainTest(m)
+}
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index bc6ad7fb3c..b4a7efa8dd 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -6,12 +6,11 @@ package markdown_test
 import (
 	"context"
 	"html/template"
-	"os"
 	"strings"
 	"testing"
 
-	"code.gitea.io/gitea/models/unittest"
 	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/markup"
 	"code.gitea.io/gitea/modules/markup/markdown"
@@ -25,28 +24,36 @@ import (
 )
 
 const (
-	AppURL  = "http://localhost:3000/"
-	FullURL = AppURL + "gogits/gogs/"
+	AppURL            = "http://localhost:3000/"
+	testRepoOwnerName = "user13"
+	testRepoName      = "repo11"
+	FullURL           = AppURL + testRepoOwnerName + "/" + testRepoName + "/"
 )
 
 // these values should match the const above
 var localMetas = map[string]string{
-	"user":     "gogits",
-	"repo":     "gogs",
-	"repoPath": "../../../tests/gitea-repositories-meta/user13/repo11.git/",
+	"user": testRepoOwnerName,
+	"repo": testRepoName,
 }
 
-func TestMain(m *testing.M) {
-	unittest.InitSettings()
-	if err := git.InitSimple(context.Background()); err != nil {
-		log.Fatal("git init failed, err: %v", err)
+type mockRepo struct {
+	OwnerName string
+	RepoName  string
+}
+
+func (m *mockRepo) GetOwnerName() string {
+	return m.OwnerName
+}
+
+func (m *mockRepo) GetName() string {
+	return m.RepoName
+}
+
+func newMockRepo(ownerName, repoName string) gitrepo.Repository {
+	return &mockRepo{
+		OwnerName: ownerName,
+		RepoName:  repoName,
 	}
-	markup.Init(&markup.ProcessorHelper{
-		IsUsernameMentionable: func(ctx context.Context, username string) bool {
-			return username == "r-lyeh"
-		},
-	})
-	os.Exit(m.Run())
 }
 
 func TestRender_StandardLinks(t *testing.T) {
@@ -133,11 +140,11 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
 <li><a href="` + baseURLContent + `/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
 <li><a href="` + baseURLContent + `/Tips" rel="nofollow">Tips</a></li>
 </ul>
-<p>See commit <a href="/gogits/gogs/commit/65f1bf27bc" rel="nofollow"><code>65f1bf27bc</code></a></p>
+<p>See commit <a href="/` + testRepoOwnerName + `/` + testRepoName + `/commit/65f1bf27bc" rel="nofollow"><code>65f1bf27bc</code></a></p>
 <p>Ideas and codes</p>
 <ul>
 <li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" class="ref-issue" rel="nofollow">ocornut/imgui#786</a></li>
-<li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/gogits/gogs/issues/786" class="ref-issue" rel="nofollow">#786</a></li>
+<li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="` + FullURL + `issues/786" class="ref-issue" rel="nofollow">#786</a></li>
 <li>Node graph editors <a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">https://github.com/ocornut/imgui/issues/306</a></li>
 <li><a href="` + baseURLContent + `/memory_editor_example" rel="nofollow">Memory Editor</a></li>
 <li><a href="` + baseURLContent + `/plot_var_example" rel="nofollow">Plot var helper</a></li>
@@ -222,7 +229,7 @@ See commit 65f1bf27bc
 Ideas and codes
 
 - Bezier widget (by @r-lyeh) ` + AppURL + `ocornut/imgui/issues/786
-- Bezier widget (by @r-lyeh) ` + AppURL + `gogits/gogs/issues/786
+- Bezier widget (by @r-lyeh) ` + FullURL + `issues/786
 - Node graph editors https://github.com/ocornut/imgui/issues/306
 - [[Memory Editor|memory_editor_example]]
 - [[Plot var helper|plot_var_example]]`,
@@ -299,6 +306,7 @@ func TestTotal_RenderWiki(t *testing.T) {
 			Links: markup.Links{
 				Base: FullURL,
 			},
+			Repo:   newMockRepo(testRepoOwnerName, testRepoName),
 			Metas:  localMetas,
 			IsWiki: true,
 		}, sameCases[i])
@@ -344,6 +352,7 @@ func TestTotal_RenderString(t *testing.T) {
 				Base:       FullURL,
 				BranchPath: "master",
 			},
+			Repo:  newMockRepo(testRepoOwnerName, testRepoName),
 			Metas: localMetas,
 		}, sameCases[i])
 		assert.NoError(t, err)
diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go
index 005fcc278b..f836f12ad3 100644
--- a/modules/markup/renderer.go
+++ b/modules/markup/renderer.go
@@ -16,6 +16,7 @@ import (
 	"sync"
 
 	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
@@ -77,6 +78,7 @@ type RenderContext struct {
 	Metas            map[string]string
 	DefaultLink      string
 	GitRepo          *git.Repository
+	Repo             gitrepo.Repository
 	ShaExistCache    map[string]bool
 	cancelFn         func()
 	SidebarTocNode   ast.Node
diff --git a/routers/common/markup.go b/routers/common/markup.go
index 2d5638ef61..f7d096008a 100644
--- a/routers/common/markup.go
+++ b/routers/common/markup.go
@@ -9,6 +9,7 @@ import (
 	"net/http"
 	"strings"
 
+	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/modules/markup"
 	"code.gitea.io/gitea/modules/markup/markdown"
 	"code.gitea.io/gitea/modules/setting"
@@ -66,7 +67,9 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
 	}
 
 	meta := map[string]string{}
+	var repoCtx *repo_model.Repository
 	if repo != nil && repo.Repository != nil {
+		repoCtx = repo.Repository
 		if mode == "comment" {
 			meta = repo.Repository.ComposeMetas(ctx)
 		} else {
@@ -78,7 +81,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
 	}
 
 	if err := markup.Render(&markup.RenderContext{
-		Ctx: ctx,
+		Ctx:  ctx,
+		Repo: repoCtx,
 		Links: markup.Links{
 			AbsolutePrefix: true,
 			Base:           urlPrefix,
diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go
index 20fcda6664..cb62858631 100644
--- a/routers/web/feed/convert.go
+++ b/routers/web/feed/convert.go
@@ -297,7 +297,8 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release) (
 
 		link := &feeds.Link{Href: rel.HTMLURL()}
 		content, err = markdown.RenderString(&markup.RenderContext{
-			Ctx: ctx,
+			Ctx:  ctx,
+			Repo: rel.Repo,
 			Links: markup.Links{
 				Base: rel.Repo.Link(),
 			},
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index a2c6ac33e8..7b5e72593f 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -382,6 +382,7 @@ func Diff(ctx *context.Context) {
 			},
 			Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 			GitRepo: ctx.Repo.GitRepo,
+			Repo:    ctx.Repo.Repository,
 			Ctx:     ctx,
 		}, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message, charset.ConvertOpts{}))))
 		if err != nil {
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index ce459f23b9..18f975b4a6 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -1466,6 +1466,7 @@ func ViewIssue(ctx *context.Context) {
 		},
 		Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 		GitRepo: ctx.Repo.GitRepo,
+		Repo:    ctx.Repo.Repository,
 		Ctx:     ctx,
 	}, issue.Content)
 	if err != nil {
@@ -1622,6 +1623,7 @@ func ViewIssue(ctx *context.Context) {
 				},
 				Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 				GitRepo: ctx.Repo.GitRepo,
+				Repo:    ctx.Repo.Repository,
 				Ctx:     ctx,
 			}, comment.Content)
 			if err != nil {
@@ -1699,6 +1701,7 @@ func ViewIssue(ctx *context.Context) {
 				},
 				Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 				GitRepo: ctx.Repo.GitRepo,
+				Repo:    ctx.Repo.Repository,
 				Ctx:     ctx,
 			}, comment.Content)
 			if err != nil {
@@ -2276,6 +2279,7 @@ func UpdateIssueContent(ctx *context.Context) {
 		},
 		Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 		GitRepo: ctx.Repo.GitRepo,
+		Repo:    ctx.Repo.Repository,
 		Ctx:     ctx,
 	}, issue.Content)
 	if err != nil {
@@ -3196,6 +3200,7 @@ func UpdateCommentContent(ctx *context.Context) {
 			},
 			Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 			GitRepo: ctx.Repo.GitRepo,
+			Repo:    ctx.Repo.Repository,
 			Ctx:     ctx,
 		}, comment.Content)
 		if err != nil {
diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go
index 95a4fe60cc..c6c8cb5cfb 100644
--- a/routers/web/repo/milestone.go
+++ b/routers/web/repo/milestone.go
@@ -86,6 +86,7 @@ func Milestones(ctx *context.Context) {
 			},
 			Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 			GitRepo: ctx.Repo.GitRepo,
+			Repo:    ctx.Repo.Repository,
 			Ctx:     ctx,
 		}, m.Content)
 		if err != nil {
@@ -282,6 +283,7 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {
 		},
 		Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 		GitRepo: ctx.Repo.GitRepo,
+		Repo:    ctx.Repo.Repository,
 		Ctx:     ctx,
 	}, milestone.Content)
 	if err != nil {
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index 9ce5535a0e..2e32f478aa 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -96,6 +96,7 @@ func Projects(ctx *context.Context) {
 			},
 			Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 			GitRepo: ctx.Repo.GitRepo,
+			Repo:    ctx.Repo.Repository,
 			Ctx:     ctx,
 		}, projects[i].Description)
 		if err != nil {
@@ -357,6 +358,7 @@ func ViewProject(ctx *context.Context) {
 		},
 		Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 		GitRepo: ctx.Repo.GitRepo,
+		Repo:    ctx.Repo.Repository,
 		Ctx:     ctx,
 	}, project.Description)
 	if err != nil {
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 7ba23f0701..8ba2adf3f1 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -119,6 +119,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
 			},
 			Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 			GitRepo: ctx.Repo.GitRepo,
+			Repo:    ctx.Repo.Repository,
 			Ctx:     ctx,
 		}, r.Note)
 		if err != nil {
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index c3f34039e9..b03a514030 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -262,6 +262,7 @@ func Milestones(ctx *context.Context) {
 			},
 			Metas: milestones[i].Repo.ComposeMetas(ctx),
 			Ctx:   ctx,
+			Repo:  milestones[i].Repo,
 		}, milestones[i].Content)
 		if err != nil {
 			ctx.ServerError("RenderString", err)
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index 04194dcf26..000cc835c8 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -220,7 +220,8 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
 
 	// This is the body of the new issue or comment, not the mail body
 	body, err := markdown.RenderString(&markup.RenderContext{
-		Ctx: ctx,
+		Ctx:  ctx,
+		Repo: ctx.Issue.Repo,
 		Links: markup.Links{
 			AbsolutePrefix: true,
 			Base:           ctx.Issue.Repo.HTMLURL(),
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index 2aac21e552..b7a4da0db9 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -57,7 +57,8 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
 
 	var err error
 	rel.RenderedNote, err = markdown.RenderString(&markup.RenderContext{
-		Ctx: ctx,
+		Ctx:  ctx,
+		Repo: rel.Repo,
 		Links: markup.Links{
 			Base: rel.Repo.HTMLURL(),
 		},