diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index e44a7875872..c93aed05f4c 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -38,7 +38,7 @@ jobs: contents: read steps: - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v7 + - uses: astral-sh/setup-uv@v8.0.0 - run: uv python install 3.14 - uses: pnpm/action-setup@v5 - uses: actions/setup-node@v6 @@ -58,7 +58,7 @@ jobs: contents: read steps: - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v7 + - uses: astral-sh/setup-uv@v8.0.0 - run: uv python install 3.14 - run: make deps-py - run: make lint-yaml diff --git a/Makefile b/Makefile index 8b0adf1906f..8c73dc350d4 100644 --- a/Makefile +++ b/Makefile @@ -525,7 +525,7 @@ test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test .PHONY: playwright playwright: deps-frontend @# on GitHub Actions VMs, playwright's system deps are pre-installed - @pnpm exec playwright install $(if $(GITHUB_ACTIONS),,--with-deps) chromium $(if $(CI),firefox) $(PLAYWRIGHT_FLAGS) + @pnpm exec playwright install $(if $(GITHUB_ACTIONS),,--with-deps) chromium firefox $(PLAYWRIGHT_FLAGS) .PHONY: test-e2e test-e2e: playwright $(EXECUTABLE_E2E) diff --git a/cmd/generate.go b/cmd/generate.go index b94ff79aaec..21f8b42bff7 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -78,11 +78,7 @@ func runGenerateInternalToken(_ context.Context, c *cli.Command) error { } func runGenerateLfsJwtSecret(_ context.Context, c *cli.Command) error { - _, jwtSecretBase64, err := generate.NewJwtSecretWithBase64() - if err != nil { - return err - } - + _, jwtSecretBase64 := generate.NewJwtSecretWithBase64() fmt.Printf("%s", jwtSecretBase64) if isatty.IsTerminal(os.Stdout.Fd()) { diff --git a/modules/generate/generate.go b/modules/generate/generate.go index 2d9a3dd9022..ac845044923 100644 --- a/modules/generate/generate.go +++ b/modules/generate/generate.go @@ -54,13 +54,13 @@ func DecodeJwtSecretBase64(src string) ([]byte, error) { } // NewJwtSecretWithBase64 generates a jwt secret with its base64 encoded value intended to be used for saving into config file -func NewJwtSecretWithBase64() ([]byte, string, error) { +func NewJwtSecretWithBase64() ([]byte, string) { bytes := make([]byte, defaultJwtSecretLen) - _, err := io.ReadFull(rand.Reader, bytes) + _, err := rand.Read(bytes) if err != nil { - return nil, "", err + panic(err) // rand.Read never fails } - return bytes, base64.RawURLEncoding.EncodeToString(bytes), nil + return bytes, base64.RawURLEncoding.EncodeToString(bytes) } // NewSecretKey generate a new value intended to be used by SECRET_KEY. diff --git a/modules/generate/generate_test.go b/modules/generate/generate_test.go index af640a60c1e..f9dd20cc7fe 100644 --- a/modules/generate/generate_test.go +++ b/modules/generate/generate_test.go @@ -25,10 +25,12 @@ func TestDecodeJwtSecretBase64(t *testing.T) { } func TestNewJwtSecretWithBase64(t *testing.T) { - secret, encoded, err := NewJwtSecretWithBase64() - assert.NoError(t, err) + secret, encoded := NewJwtSecretWithBase64() assert.Len(t, secret, 32) decoded, err := DecodeJwtSecretBase64(encoded) assert.NoError(t, err) assert.Equal(t, secret, decoded) + + secret2, _ := NewJwtSecretWithBase64() + assert.NotEqual(t, secret, secret2) } diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 26dbde9932a..e231b037cc1 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -583,3 +583,20 @@ func TestMarkdownLink(t *testing.T) { assert.Equal(t, `

https://example.com/__init__.py

`, string(result)) } + +func TestMarkdownUlDir(t *testing.T) { + defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, false)() + result, err := markdown.RenderString(markup.NewTestRenderContext(), ` +* a + * b +`) + assert.NoError(t, err) + assert.Equal(t, ` +`, string(result)) +} diff --git a/modules/markup/markdown/transform_list.go b/modules/markup/markdown/transform_list.go index c89ad2f2cf3..6cafa8ff78e 100644 --- a/modules/markup/markdown/transform_list.go +++ b/modules/markup/markdown/transform_list.go @@ -81,5 +81,16 @@ func (g *ASTTransformer) transformList(_ *markup.RenderContext, v *ast.List, rc v.AppendChild(v, newChild) } } - g.applyElementDir(v) + + nestedList := false + for p := v.Parent(); p != nil; p = p.Parent() { + if _, ok := p.(*ast.List); ok { + nestedList = true + break + } + } + if !nestedList { + // "dir=auto" should be only added to top-level "ul". https://github.com/go-gitea/gitea/issues/35058 + g.applyElementDir(v) + } } diff --git a/modules/setting/lfs.go b/modules/setting/lfs.go index 7f2d0ae1590..3ec21860ae6 100644 --- a/modules/setting/lfs.go +++ b/modules/setting/lfs.go @@ -81,10 +81,7 @@ func loadLFSFrom(rootCfg ConfigProvider) error { jwtSecretBase64 := loadSecret(rootCfg.Section("server"), "LFS_JWT_SECRET_URI", "LFS_JWT_SECRET") LFS.JWTSecretBytes, err = generate.DecodeJwtSecretBase64(jwtSecretBase64) if err != nil { - LFS.JWTSecretBytes, jwtSecretBase64, err = generate.NewJwtSecretWithBase64() - if err != nil { - return fmt.Errorf("error generating JWT Secret for custom config: %v", err) - } + LFS.JWTSecretBytes, jwtSecretBase64 = generate.NewJwtSecretWithBase64() // Save secret saveCfg, err := rootCfg.PrepareSaving() diff --git a/modules/setting/oauth2.go b/modules/setting/oauth2.go index 2dfe77dda9a..8e0210aa518 100644 --- a/modules/setting/oauth2.go +++ b/modules/setting/oauth2.go @@ -139,10 +139,7 @@ func loadOAuth2From(rootCfg ConfigProvider) { if InstallLock { jwtSecretBytes, err := generate.DecodeJwtSecretBase64(jwtSecretBase64) if err != nil { - jwtSecretBytes, jwtSecretBase64, err = generate.NewJwtSecretWithBase64() - if err != nil { - log.Fatal("error generating JWT secret: %v", err) - } + jwtSecretBytes, jwtSecretBase64 = generate.NewJwtSecretWithBase64() saveCfg, err := rootCfg.PrepareSaving() if err != nil { log.Fatal("save oauth2.JWT_SECRET failed: %v", err) @@ -162,10 +159,7 @@ var generalSigningSecret atomic.Pointer[[]byte] func GetGeneralTokenSigningSecret() []byte { old := generalSigningSecret.Load() if old == nil || len(*old) == 0 { - jwtSecret, _, err := generate.NewJwtSecretWithBase64() - if err != nil { - log.Fatal("Unable to generate general JWT secret: %v", err) - } + jwtSecret, _ := generate.NewJwtSecretWithBase64() if generalSigningSecret.CompareAndSwap(old, &jwtSecret) { return jwtSecret } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 3a5eb5904f7..f81be1255ab 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -25,8 +25,7 @@ import ( "code.gitea.io/gitea/services/gitdiff" ) -// NewFuncMap returns functions for injecting to templates -func NewFuncMap() template.FuncMap { +func newFuncMapWebPage() template.FuncMap { return map[string]any{ "DumpVar": dumpVar, "NIL": func() any { return nil }, @@ -40,7 +39,6 @@ func NewFuncMap() template.FuncMap { "QueryEscape": queryEscape, "QueryBuild": QueryBuild, "SanitizeHTML": SanitizeHTML, - "DotEscape": dotEscape, "PathEscape": url.PathEscape, "PathEscapeSegments": util.PathEscapeSegments, @@ -61,6 +59,7 @@ func NewFuncMap() template.FuncMap { // ----------------------------------------------------------------- // time / number / format + "ShortSha": base.ShortSha, "FileSize": base.FileSize, "CountFmt": countFmt, "Sec2Hour": util.SecToHours, @@ -73,6 +72,7 @@ func NewFuncMap() template.FuncMap { "AssetURI": public.AssetURI, "ScriptImport": scriptImport, + // ----------------------------------------------------------------- // setting "AppName": func() string { @@ -84,17 +84,10 @@ func NewFuncMap() template.FuncMap { "AssetUrlPrefix": func() string { return setting.StaticURLPrefix + "/assets" }, - "AppUrl": func() string { - // The usage of AppUrl should be avoided as much as possible, - // because the AppURL(ROOT_URL) may not match user's visiting site and the ROOT_URL in app.ini may be incorrect. - // And it's difficult for Gitea to guess absolute URL correctly with zero configuration, - // because Gitea doesn't know whether the scheme is HTTP or HTTPS unless the reverse proxy could tell Gitea. - return setting.AppURL - }, "AppVer": func() string { return setting.AppVer }, - "AppDomain": func() string { // documented in mail-templates.md + "AppDomain": func() string { // TODO: helm registry still uses it, need to use current request host in the future return setting.Domain }, "ShowFooterTemplateLoadTime": func() bool { @@ -143,7 +136,6 @@ func NewFuncMap() template.FuncMap { // ----------------------------------------------------------------- // misc (TODO: move them to MiscUtils to avoid bloating the main func map) - "ShortSha": base.ShortSha, "ActionContent2Commits": ActionContent2Commits, "IsMultilineCommitMessage": isMultilineCommitMessage, "CommentMustAsDiff": gitdiff.CommentMustAsDiff, @@ -177,11 +169,6 @@ func queryEscape(s string) template.URL { return template.URL(url.QueryEscape(s)) } -// dotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent auto-linkers from detecting these as urls -func dotEscape(raw string) string { - return strings.ReplaceAll(raw, ".", "\u200d.\u200d") -} - // iif is an "inline-if", similar util.Iif[T] but templates need the non-generic version, // and it could be simply used as "{{iif expr trueVal}}" (omit the falseVal). func iif(condition any, vals ...any) any { diff --git a/modules/templates/mail.go b/modules/templates/mail.go index ca13626468d..181c6312b03 100644 --- a/modules/templates/mail.go +++ b/modules/templates/mail.go @@ -6,12 +6,14 @@ package templates import ( "html/template" "io" + "net/url" "regexp" "slices" "strings" "sync" texttmpl "text/template" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -34,6 +36,11 @@ type MailRender struct { mockedBodyTemplates map[string]*template.Template } +// dotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent auto-linkers from detecting these as urls +func dotEscape(raw string) string { + return strings.ReplaceAll(raw, ".", "\u200d.\u200d") +} + // mailSubjectTextFuncMap returns functions for injecting to text templates, it's only used for mail subject func mailSubjectTextFuncMap() texttmpl.FuncMap { return texttmpl.FuncMap{ @@ -41,6 +48,7 @@ func mailSubjectTextFuncMap() texttmpl.FuncMap { "Eval": evalTokens, "EllipsisString": util.EllipsisDisplayString, + "AppName": func() string { return setting.AppName }, @@ -50,6 +58,48 @@ func mailSubjectTextFuncMap() texttmpl.FuncMap { } } +func mailBodyFuncMap() template.FuncMap { + // Some of them are documented in mail-templates.md + return template.FuncMap{ + "DumpVar": dumpVar, + "NIL": func() any { return nil }, + + // html/template related functions + "dict": dict, + "Iif": iif, + "Eval": evalTokens, + "HTMLFormat": htmlFormat, + "QueryEscape": queryEscape, + "QueryBuild": QueryBuild, + "SanitizeHTML": SanitizeHTML, + + "PathEscape": url.PathEscape, + "PathEscapeSegments": util.PathEscapeSegments, + + "DotEscape": dotEscape, + + // utils + "StringUtils": NewStringUtils, + "SliceUtils": NewSliceUtils, + "JsonUtils": NewJsonUtils, + + // time / number / format + "ShortSha": base.ShortSha, + "FileSize": base.FileSize, + + // setting + "AppName": func() string { + return setting.AppName + }, + "AppUrl": func() string { + return setting.AppURL + }, + "AppDomain": func() string { + return setting.Domain + }, + } +} + var mailSubjectSplit = regexp.MustCompile(`(?m)^-{3,}\s*$`) func newMailRenderer() (*MailRender, error) { @@ -103,7 +153,7 @@ func newMailRenderer() (*MailRender, error) { return renderer.tmplRenderer.Templates().HasTemplate(name) } - staticFuncMap := NewFuncMap() + staticFuncMap := mailBodyFuncMap() renderer.BodyTemplates.ExecuteTemplate = func(w io.Writer, name string, data any) error { if t, ok := renderer.mockedBodyTemplates[name]; ok { return t.Execute(w, data) @@ -131,7 +181,7 @@ func (r *MailRender) MockTemplate(name, subject, body string) func() { texttmpl.Must(r.SubjectTemplates.New(name).Parse(subject)) oldBody, hasOldBody := r.mockedBodyTemplates[name] - mockFuncMap := NewFuncMap() + mockFuncMap := mailBodyFuncMap() r.mockedBodyTemplates[name] = template.Must(template.New(name).Funcs(mockFuncMap).Parse(body)) return func() { r.SubjectTemplates = oldSubject diff --git a/modules/templates/page.go b/modules/templates/page.go index 8f6c82fc4ba..32e52bb68e4 100644 --- a/modules/templates/page.go +++ b/modules/templates/page.go @@ -24,13 +24,13 @@ type pageRenderer struct { } func (r *pageRenderer) funcMap(ctx context.Context) template.FuncMap { - pageFuncMap := NewFuncMap() + pageFuncMap := newFuncMapWebPage() pageFuncMap["ctx"] = func() any { return ctx } return pageFuncMap } func (r *pageRenderer) funcMapDummy() template.FuncMap { - dummyFuncMap := NewFuncMap() + dummyFuncMap := newFuncMapWebPage() dummyFuncMap["ctx"] = func() any { return nil } // for template compilation only, no context available return dummyFuncMap } diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index e796064ce3c..1600b279000 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -1043,6 +1043,7 @@ "repo.forks": "Forks", "repo.stars": "Stars", "repo.reactions_more": "and %d more", + "repo.reactions": "Reactions", "repo.unit_disabled": "The site administrator has disabled this repository section.", "repo.language_other": "Other", "repo.adopt_search": "Enter username to search for unadopted repositories… (leave blank to find all)", @@ -3223,10 +3224,8 @@ "admin.config.server_config": "Server Configuration", "admin.config.app_name": "Site Title", "admin.config.app_ver": "Gitea Version", - "admin.config.app_url": "Gitea Base URL", "admin.config.custom_conf": "Configuration File Path", "admin.config.custom_file_root_path": "Custom File Root Path", - "admin.config.domain": "Server Domain", "admin.config.disable_router_log": "Disable Router Log", "admin.config.run_user": "Run As Username", "admin.config.run_mode": "Run Mode", diff --git a/playwright.config.ts b/playwright.config.ts index 9904e76f94a..9dc8a7c1b5c 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -5,6 +5,8 @@ const timeoutFactor = Number(env.GITEA_TEST_E2E_TIMEOUT_FACTOR) || 1; const timeout = 5000 * timeoutFactor; export default defineConfig({ + workers: '50%', + fullyParallel: true, testDir: './tests/e2e/', outputDir: './tests/e2e-output/', testMatch: /.*\.test\.ts/, @@ -28,11 +30,11 @@ export default defineConfig({ permissions: ['clipboard-read', 'clipboard-write'], }, }, - ...env.CI ? [{ + { name: 'firefox', use: { ...devices['Desktop Firefox'], }, - }] : [], + }, ], }); diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 74bcf53167c..d98e0849ebc 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1228,10 +1228,10 @@ func Routes() *web.Router { m.Group("/branch_protections", func() { m.Get("", repo.ListBranchProtections) m.Post("", bind(api.CreateBranchProtectionOption{}), mustNotBeArchived, repo.CreateBranchProtection) - m.Group("/{name}", func() { + m.Group("/*", func() { m.Get("", repo.GetBranchProtection) m.Patch("", bind(api.EditBranchProtectionOption{}), mustNotBeArchived, repo.EditBranchProtection) - m.Delete("", repo.DeleteBranchProtection) + m.Delete("", mustNotBeArchived, repo.DeleteBranchProtection) }) m.Post("/priority", bind(api.UpdateBranchProtectionPriories{}), mustNotBeArchived, repo.UpdateBranchProtectionPriories) }, reqToken(), reqAdmin()) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index c3b3fc10855..295e4c2b5ed 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -563,7 +563,7 @@ func GetBranchProtection(ctx *context.APIContext) { // "$ref": "#/responses/notFound" repo := ctx.Repo.Repository - bpName := ctx.PathParam("name") + bpName := ctx.PathParam("*") bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { ctx.APIErrorInternal(err) @@ -845,7 +845,7 @@ func EditBranchProtection(ctx *context.APIContext) { // "$ref": "#/responses/repoArchivedError" form := web.GetForm(ctx).(*api.EditBranchProtectionOption) repo := ctx.Repo.Repository - bpName := ctx.PathParam("name") + bpName := ctx.PathParam("*") protectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { ctx.APIErrorInternal(err) @@ -1168,7 +1168,7 @@ func DeleteBranchProtection(ctx *context.APIContext) { // "$ref": "#/responses/notFound" repo := ctx.Repo.Repository - bpName := ctx.PathParam("name") + bpName := ctx.PathParam("*") bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 9e77637282a..28bc508879b 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -107,15 +107,18 @@ func GetAnnotatedTag(ctx *context.APIContext) { return } - if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil { + tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha) + if err != nil { ctx.APIError(http.StatusBadRequest, err) - } else { - commit, err := ctx.Repo.GitRepo.GetTagCommit(tag.Name) - if err != nil { - ctx.APIError(http.StatusBadRequest, err) - } - ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit)) + return } + + commit, err := ctx.Repo.GitRepo.GetTagCommit(tag.Name) + if err != nil { + ctx.APIError(http.StatusBadRequest, err) + return + } + ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit)) } // GetTag get the tag of a repository diff --git a/routers/install/install.go b/routers/install/install.go index 81fcdfa384c..dec0b31e5cd 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -371,12 +371,11 @@ func SubmitInstall(ctx *context.Context) { if form.LFSRootPath != "" { cfg.Section("server").Key("LFS_START_SERVER").SetValue("true") cfg.Section("lfs").Key("PATH").SetValue(form.LFSRootPath) - var lfsJwtSecret string - if _, lfsJwtSecret, err = generate.NewJwtSecretWithBase64(); err != nil { - ctx.RenderWithErrDeprecated(ctx.Tr("install.lfs_jwt_secret_failed", err), tplInstall, &form) - return + + if !cfg.Section("server").HasKey("LFS_JWT_SECRET_URI") { + _, lfsJwtSecret := generate.NewJwtSecretWithBase64() + cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(lfsJwtSecret) } - cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(lfsJwtSecret) } else { cfg.Section("server").Key("LFS_START_SERVER").SetValue("false") } @@ -437,11 +436,7 @@ func SubmitInstall(ctx *context.Context) { // FIXME: at the moment, no matter oauth2 is enabled or not, it must generate a "oauth2 JWT_SECRET" // see the "loadOAuth2From" in "setting/oauth2.go" if !cfg.Section("oauth2").HasKey("JWT_SECRET") && !cfg.Section("oauth2").HasKey("JWT_SECRET_URI") { - _, jwtSecretBase64, err := generate.NewJwtSecretWithBase64() - if err != nil { - ctx.RenderWithErrDeprecated(ctx.Tr("install.secret_key_failed", err), tplInstall, &form) - return - } + _, jwtSecretBase64 := generate.NewJwtSecretWithBase64() cfg.Section("oauth2").Key("JWT_SECRET").SetValue(jwtSecretBase64) } diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index a449796ec12..bf48e554dfd 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -123,9 +123,7 @@ func Config(ctx *context.Context) { ctx.Data["PageIsAdminConfigSummary"] = true ctx.Data["CustomConf"] = setting.CustomConf - ctx.Data["AppUrl"] = setting.AppURL ctx.Data["AppBuiltWith"] = setting.AppBuiltWith - ctx.Data["Domain"] = setting.Domain ctx.Data["RunUser"] = setting.RunUser ctx.Data["RunMode"] = util.ToTitleCase(setting.RunMode) ctx.Data["GitVersion"] = git.DefaultFeatures().VersionInfo() diff --git a/services/context/context_template.go b/services/context/context_template.go index 52c74611878..4e28c0f7dfd 100644 --- a/services/context/context_template.go +++ b/services/context/context_template.go @@ -5,10 +5,13 @@ package context import ( "context" + "html/template" "net/http" "strconv" + "strings" "time" + "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/services/webtheme" @@ -69,3 +72,14 @@ func (c TemplateContext) CurrentWebBanner() *setting.WebBannerType { } return nil } + +// AppFullLink returns a full URL link with AppSubURL for the given app link (no AppSubURL) +// If no link is given, it returns the current app full URL with sub-path but without trailing slash (that's why it is not named as AppURL) +func (c TemplateContext) AppFullLink(link ...string) template.URL { + s := httplib.GuessCurrentAppURL(c.parentContext()) + s = strings.TrimSuffix(s, "/") + if len(link) == 0 { + return template.URL(s) + } + return template.URL(s + strings.TrimPrefix(link[0], "/")) +} diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 6dc6e0d5ea1..b68f2c1a7ae 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -11,10 +11,6 @@
{{AppVer}}{{.AppBuiltWith}}
{{ctx.Locale.Tr "admin.config.custom_conf"}}
{{.CustomConf}}
-
{{ctx.Locale.Tr "admin.config.app_url"}}
-
{{.AppUrl}}
-
{{ctx.Locale.Tr "admin.config.domain"}}
-
{{.Domain}}
{{ctx.Locale.Tr "admin.config.disable_router_log"}}
{{svg (Iif .DisableRouterLog "octicon-check" "octicon-x")}}
diff --git a/templates/base/head_opengraph.tmpl b/templates/base/head_opengraph.tmpl index cb96fb6d6de..93624ea4b09 100644 --- a/templates/base/head_opengraph.tmpl +++ b/templates/base/head_opengraph.tmpl @@ -16,7 +16,7 @@ {{end}} {{else if or .PageIsDiff .IsViewFile}} - + {{if and .PageIsDiff .Commit}} {{- $commitMessageParts := StringUtils.Cut .Commit.Message "\n" -}} {{- $commitMessageBody := index $commitMessageParts 1 -}} @@ -41,7 +41,7 @@ - + {{end}} diff --git a/templates/base/head_script.tmpl b/templates/base/head_script.tmpl index 403417892f8..824b0596437 100644 --- a/templates/base/head_script.tmpl +++ b/templates/base/head_script.tmpl @@ -7,7 +7,7 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly. window.addEventListener('error', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);}); window.addEventListener('unhandledrejection', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);}); window.config = { - appUrl: '{{AppUrl}}', + appUrl: '{{ctx.AppFullLink "/"}}', appSubUrl: '{{AppSubUrl}}', assetUrlPrefix: '{{AssetUrlPrefix}}', runModeIsProd: {{.RunModeIsProd}}, diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl index d548ed81dc0..1584792b6bf 100644 --- a/templates/devtest/gitea-ui.tmpl +++ b/templates/devtest/gitea-ui.tmpl @@ -84,12 +84,6 @@ -
-

<origin-url>

-
-
-
-

<overflow-menu>

diff --git a/templates/package/content/alpine.tmpl b/templates/package/content/alpine.tmpl index 5c144b97790..9fb7ce9fac4 100644 --- a/templates/package/content/alpine.tmpl +++ b/templates/package/content/alpine.tmpl @@ -4,12 +4,12 @@
-
/$branch/$repository
+
{{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/alpine/$branch/$repository

{{ctx.Locale.Tr "packages.alpine.registry.info"}}

-
curl -JO 
+
curl -JO {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/alpine/key
diff --git a/templates/package/content/arch.tmpl b/templates/package/content/arch.tmpl index 6ce18affac8..951bd53246d 100644 --- a/templates/package/content/arch.tmpl +++ b/templates/package/content/arch.tmpl @@ -7,7 +7,7 @@
{{range $i, $repo := .Repositories}}{{if $i}}
 {{end}}[{{$repo}}]
 SigLevel = Optional TrustAll
-Server = 
+Server = {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/arch/$repo/$arch
 {{end}}
diff --git a/templates/package/content/cargo.tmpl b/templates/package/content/cargo.tmpl index 8b51074af44..ebb23e86597 100644 --- a/templates/package/content/cargo.tmpl +++ b/templates/package/content/cargo.tmpl @@ -8,8 +8,8 @@ default = "gitea" [registries.gitea] -index = "sparse+" # Sparse index -# index = "" # Git +index = "sparse+{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/cargo/" # Sparse index +# index = "{{ctx.AppFullLink}}/{{.PackageDescriptor.Owner.Name}}/_cargo-index.git" # Git [net] git-fetch-with-cli = true
diff --git a/templates/package/content/chef.tmpl b/templates/package/content/chef.tmpl index b3713808f65..d1c17d36a49 100644 --- a/templates/package/content/chef.tmpl +++ b/templates/package/content/chef.tmpl @@ -4,7 +4,7 @@
-
knife[:supermarket_site] = ''
+
knife[:supermarket_site] = '{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/chef'
diff --git a/templates/package/content/composer.tmpl b/templates/package/content/composer.tmpl index 45698208696..2e8cfb77ebc 100644 --- a/templates/package/content/composer.tmpl +++ b/templates/package/content/composer.tmpl @@ -7,7 +7,7 @@
{
 	"repositories": [{
 			"type": "composer",
-			"url": ""
+			"url": "{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/composer"
 		}
 	]
 }
diff --git a/templates/package/content/conan.tmpl b/templates/package/content/conan.tmpl index b68a45fde30..13fd5fa76aa 100644 --- a/templates/package/content/conan.tmpl +++ b/templates/package/content/conan.tmpl @@ -4,7 +4,7 @@
-
conan remote add gitea 
+
conan remote add gitea {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/conan
diff --git a/templates/package/content/conda.tmpl b/templates/package/content/conda.tmpl index 031b51aa108..622ec7ee76d 100644 --- a/templates/package/content/conda.tmpl +++ b/templates/package/content/conda.tmpl @@ -4,11 +4,11 @@
-
channel_alias: 
+				
channel_alias: {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/conda
 channels:
-  - 
+  - {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/conda
 default_channels:
-  - 
+ - {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/conda
diff --git a/templates/package/content/cran.tmpl b/templates/package/content/cran.tmpl index ae58e6f334c..0f0f167c3de 100644 --- a/templates/package/content/cran.tmpl +++ b/templates/package/content/cran.tmpl @@ -4,7 +4,7 @@
-
options("repos" = c(getOption("repos"), c(gitea="")))
+
options("repos" = c(getOption("repos"), c(gitea="{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/cran")))
diff --git a/templates/package/content/debian.tmpl b/templates/package/content/debian.tmpl index 73b82578357..7f843effb45 100644 --- a/templates/package/content/debian.tmpl +++ b/templates/package/content/debian.tmpl @@ -4,8 +4,8 @@
-
sudo curl  -o /etc/apt/keyrings/gitea-{{$.PackageDescriptor.Owner.Name}}.asc
-echo "deb [signed-by=/etc/apt/keyrings/gitea-{{$.PackageDescriptor.Owner.Name}}.asc]  $distribution $component" | sudo tee -a /etc/apt/sources.list.d/gitea.list
+				
sudo curl {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/debian/repository.key -o /etc/apt/keyrings/gitea-{{$.PackageDescriptor.Owner.Name}}.asc
+echo "deb [signed-by=/etc/apt/keyrings/gitea-{{$.PackageDescriptor.Owner.Name}}.asc] {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/debian $distribution $component" | sudo tee -a /etc/apt/sources.list.d/gitea.list
 sudo apt update

{{ctx.Locale.Tr "packages.debian.registry.info"}}

diff --git a/templates/package/content/generic.tmpl b/templates/package/content/generic.tmpl index 2fd952105f2..6e57e21ca1b 100644 --- a/templates/package/content/generic.tmpl +++ b/templates/package/content/generic.tmpl @@ -6,7 +6,7 @@

 {{- range .PackageDescriptor.Files -}}
-curl -OJ 
+curl -OJ {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/generic/{{$.PackageDescriptor.Package.Name}}/{{$.PackageDescriptor.Version.Version}}/{{.File.Name}}
 {{end -}}
 				
diff --git a/templates/package/content/go.tmpl b/templates/package/content/go.tmpl index 80d1ab231a4..54ab18475db 100644 --- a/templates/package/content/go.tmpl +++ b/templates/package/content/go.tmpl @@ -4,7 +4,7 @@
-
GOPROXY= go install {{$.PackageDescriptor.Package.Name}}@{{$.PackageDescriptor.Version.Version}}
+
GOPROXY={{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/go go install {{$.PackageDescriptor.Package.Name}}@{{$.PackageDescriptor.Version.Version}}
diff --git a/templates/package/content/helm.tmpl b/templates/package/content/helm.tmpl index da846e934db..7a077a582dd 100644 --- a/templates/package/content/helm.tmpl +++ b/templates/package/content/helm.tmpl @@ -4,7 +4,7 @@
-
helm repo add {{AppDomain}} 
+				
helm repo add {{AppDomain}} {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/helm
 helm repo update
diff --git a/templates/package/content/maven.tmpl b/templates/package/content/maven.tmpl index ea09023d599..612593a72e1 100644 --- a/templates/package/content/maven.tmpl +++ b/templates/package/content/maven.tmpl @@ -11,19 +11,19 @@
<repositories>
 	<repository>
 		<id>gitea</id>
-		<url></url>
+		<url>{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/maven</url>
 	</repository>
 </repositories>
 
 <distributionManagement>
 	<repository>
 		<id>gitea</id>
-		<url></url>
+		<url>{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/maven</url>
 	</repository>
 
 	<snapshotRepository>
 		<id>gitea</id>
-		<url></url>
+		<url>{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/maven</url>
 	</snapshotRepository>
 </distributionManagement>
@@ -41,7 +41,7 @@
-
mvn dependency:get -DremoteRepositories= -Dartifact={{.PackageDescriptor.Metadata.GroupID}}:{{.PackageDescriptor.Metadata.ArtifactID}}:{{.PackageDescriptor.Version.Version}}
+
mvn dependency:get -DremoteRepositories={{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/maven -Dartifact={{.PackageDescriptor.Metadata.GroupID}}:{{.PackageDescriptor.Metadata.ArtifactID}}:{{.PackageDescriptor.Version.Version}}
diff --git a/templates/package/content/npm.tmpl b/templates/package/content/npm.tmpl index bb024348d07..28bcf45ee87 100644 --- a/templates/package/content/npm.tmpl +++ b/templates/package/content/npm.tmpl @@ -4,7 +4,7 @@
-
{{if .PackageDescriptor.Metadata.Scope}}{{.PackageDescriptor.Metadata.Scope}}:{{end}}registry=
+
{{if .PackageDescriptor.Metadata.Scope}}{{.PackageDescriptor.Metadata.Scope}}:{{end}}registry={{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/npm/
diff --git a/templates/package/content/nuget.tmpl b/templates/package/content/nuget.tmpl index 6e7e80a36e8..7f874044cc1 100644 --- a/templates/package/content/nuget.tmpl +++ b/templates/package/content/nuget.tmpl @@ -4,7 +4,7 @@
-
dotnet nuget add source --name {{.PackageDescriptor.Owner.Name}} --username your_username --password your_token 
+
dotnet nuget add source --name {{.PackageDescriptor.Owner.Name}} --username your_username --password your_token {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/nuget/index.json
diff --git a/templates/package/content/pub.tmpl b/templates/package/content/pub.tmpl index 2f63cde3a63..9eefcf71625 100644 --- a/templates/package/content/pub.tmpl +++ b/templates/package/content/pub.tmpl @@ -4,7 +4,7 @@
-
dart pub add {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}} --hosted-url=
+
dart pub add {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}} --hosted-url={{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/pub/
diff --git a/templates/package/content/pypi.tmpl b/templates/package/content/pypi.tmpl index 15d8971eaa7..4afdc1b72a7 100644 --- a/templates/package/content/pypi.tmpl +++ b/templates/package/content/pypi.tmpl @@ -4,7 +4,7 @@
-
pip install --index-url  --extra-index-url https://pypi.org/simple {{.PackageDescriptor.Package.Name}}
+
pip install --index-url {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/pypi/simple/ --extra-index-url https://pypi.org/simple {{.PackageDescriptor.Package.Name}}
diff --git a/templates/package/content/rpm.tmpl b/templates/package/content/rpm.tmpl index 8aebe628060..7eba0d317ff 100644 --- a/templates/package/content/rpm.tmpl +++ b/templates/package/content/rpm.tmpl @@ -11,19 +11,19 @@ # {{ctx.Locale.Tr "packages.rpm.distros.redhat"}} {{- range $group := .Groups}} {{- if $group}}{{$group = print "/" $group}}{{end}} -dnf config-manager --add-repo +dnf config-manager --add-repo {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/rpm{{$group}}.repo {{- end}} # Fedora 41+ (DNF5) {{- range $group := .Groups}} {{- if $group}}{{$group = print "/" $group}}{{end}} -dnf config-manager addrepo --from-repofile= +dnf config-manager addrepo --from-repofile={{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/rpm{{$group}}.repo {{- end}} # {{ctx.Locale.Tr "packages.rpm.distros.suse"}} {{- range $group := .Groups}} {{- if $group}}{{$group = print "/" $group}}{{end}} -zypper addrepo +zypper addrepo {{ctx.AppFullLink}}/api/packages/{{$.PackageDescriptor.Owner.Name}}/rpm{{$group}}.repo {{- end}}
diff --git a/templates/package/content/rubygems.tmpl b/templates/package/content/rubygems.tmpl index 610dfc78563..140ecfb7d9b 100644 --- a/templates/package/content/rubygems.tmpl +++ b/templates/package/content/rubygems.tmpl @@ -4,11 +4,11 @@
-
gem install {{.PackageDescriptor.Package.Name}} --version "{{.PackageDescriptor.Version.Version}}" --source ""
+
gem install {{.PackageDescriptor.Package.Name}} --version "{{.PackageDescriptor.Version.Version}}" --source "{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/rubygems"
-
source "" do
+				
source "{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/rubygems" do
 	gem "{{.PackageDescriptor.Package.Name}}", "{{.PackageDescriptor.Version.Version}}"
 end
diff --git a/templates/package/content/swift.tmpl b/templates/package/content/swift.tmpl index aacbc83980f..c6afd4885f5 100644 --- a/templates/package/content/swift.tmpl +++ b/templates/package/content/swift.tmpl @@ -4,7 +4,7 @@
-
swift package-registry set 
+
swift package-registry set {{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/swift
diff --git a/templates/package/content/vagrant.tmpl b/templates/package/content/vagrant.tmpl index 7666284b871..bf68f2a4e2c 100644 --- a/templates/package/content/vagrant.tmpl +++ b/templates/package/content/vagrant.tmpl @@ -4,7 +4,7 @@
-
vagrant box add --box-version {{.PackageDescriptor.Version.Version}} ""
+
vagrant box add --box-version {{.PackageDescriptor.Version.Version}} "{{ctx.AppFullLink}}/api/packages/{{.PackageDescriptor.Owner.Name}}/vagrant/{{.PackageDescriptor.Package.Name}}"
diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index 3e1afab79f0..ac08e567813 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -1,6 +1,6 @@ {{$canWriteProject := and .CanWriteProjects (or (not .Repository) (not .Repository.IsArchived))}} -
+

{{.Project.Title}}

diff --git a/templates/repo/issue/view_content/add_reaction.tmpl b/templates/repo/issue/view_content/add_reaction.tmpl index 2f5764d9643..9b8d0344c99 100644 --- a/templates/repo/issue/view_content/add_reaction.tmpl +++ b/templates/repo/issue/view_content/add_reaction.tmpl @@ -1,5 +1,5 @@ {{if ctx.RootData.IsSigned}} -