From dabfe1bcc02d4e2fee208051cf755258d48cf06f Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Fri, 15 Aug 2025 11:51:37 +0800 Subject: [PATCH 1/4] support subdirectory config for go-get since go 1.25 ref: https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86 Signed-off-by: a1012112796 <1012112796@qq.com> --- models/repo/repo.go | 6 +++++ models/repo/repo_unit.go | 24 +++++++++++++++++- modules/structs/repo.go | 2 ++ options/locale/locale_en-US.ini | 3 +++ routers/api/v1/repo/repo.go | 8 ++++++ routers/web/goget.go | 18 +++++++++++++- routers/web/repo/setting/setting.go | 4 ++- services/context/repo.go | 7 ++++++ services/forms/repo_form.go | 2 ++ templates/repo/settings/options.tmpl | 14 ++++++++++- templates/swagger/v1_json.tmpl | 5 ++++ tests/integration/goget_test.go | 37 ++++++++++++++++++++++++++++ 12 files changed, 126 insertions(+), 4 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 2403b3b40bafe..4708adec4195a 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -468,6 +468,12 @@ func (repo *Repository) MustGetUnit(ctx context.Context, tp unit.Type) *RepoUnit Type: tp, Config: cfg, } + case unit.TypePackages: + cfg := new(PackagesConfig) + return &RepoUnit{ + Type: tp, + Config: cfg, + } } return &RepoUnit{ diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index a5207bc22a805..f8677854f3215 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -264,9 +264,11 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { r.Config = new(IssuesConfig) case unit.TypeActions: r.Config = new(ActionsConfig) + case unit.TypePackages: + r.Config = new(PackagesConfig) case unit.TypeProjects: r.Config = new(ProjectsConfig) - case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypePackages: + case unit.TypeCode, unit.TypeReleases, unit.TypeWiki: fallthrough default: r.Config = new(UnitConfig) @@ -319,6 +321,26 @@ func (r *RepoUnit) ProjectsConfig() *ProjectsConfig { return r.Config.(*ProjectsConfig) } +// PackagesConfig returns config for unit.PackagesConfig +func (r *RepoUnit) PackagesConfig() *PackagesConfig { + return r.Config.(*PackagesConfig) +} + +// PackagesConfig describes package config +type PackagesConfig struct { + GoModuleSubDir string +} + +// FromDB fills up a PackagesConfig from serialized format. +func (cfg *PackagesConfig) FromDB(bs []byte) error { + return json.UnmarshalHandleDoubleEncode(bs, &cfg) +} + +// ToDB exports a PackagesConfig to a serialized format. +func (cfg *PackagesConfig) ToDB() ([]byte, error) { + return json.Marshal(cfg) +} + func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) { var tmpUnits []*RepoUnit if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil { diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 404718def0f81..67e7da926f74e 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -227,6 +227,8 @@ type EditRepoOption struct { MirrorInterval *string `json:"mirror_interval,omitempty"` // enable prune - remove obsolete remote-tracking references when mirroring EnablePrune *bool `json:"enable_prune,omitempty"` + // set the subdirectory for Go modules + GoModuleSubDir *string `json:"go_module_sub_dir,omitempty"` } // GenerateRepoOption options when creating a repository using a template diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index d7e73a0cfbb08..b020c1be7c3ac 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2629,6 +2629,9 @@ settings.rename_branch_from=old branch name settings.rename_branch_to=new branch name settings.rename_branch=Rename branch +settings.go_module_sub_dir = Golang module subdirectory +settings.go_module_sub_dir_desc = The subdirectory in repository redirect for go module (which is supported since go 1.25, see %[2]s for more detail) + diff.browse_source = Browse Source diff.parent = parent diff.commit = commit diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index e69b7729a0fb0..0d737d4e97560 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -994,9 +994,17 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if opts.HasPackages != nil && !unit_model.TypePackages.UnitGlobalDisabled() { if *opts.HasPackages { + unit := repo.MustGetUnit(ctx, unit_model.TypePackages) + cfg := unit.PackagesConfig() + + if opts.GoModuleSubDir != nil { + cfg.GoModuleSubDir = *opts.GoModuleSubDir + } + units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, Type: unit_model.TypePackages, + Config: cfg, }) } else { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) diff --git a/routers/web/goget.go b/routers/web/goget.go index 67e0bee866c12..c5ed7c871b32f 100644 --- a/routers/web/goget.go +++ b/routers/web/goget.go @@ -56,7 +56,18 @@ func goGet(ctx *context.Context) { if err == nil && len(repo.DefaultBranch) > 0 { branchName = repo.DefaultBranch } - prefix := setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName)) + + subDir := "" + if repo != nil { + subDir = context.GetGoModuleSubDirConfig(ctx, repo) + } + + var prefix string + if len(subDir) > 0 { + prefix = setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName), subDir) + } else { + prefix = setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName)) + } appURL, _ := url.Parse(setting.AppURL) @@ -73,6 +84,11 @@ func goGet(ctx *context.Context) { } else { cloneURL = repo_model.ComposeHTTPSCloneURL(ctx, ownerName, repoName) } + + if len(subDir) > 0 { + cloneURL += " " + util.PathEscapeSegments(subDir) + } + goImportContent := fmt.Sprintf("%s git %s", goGetImport, cloneURL /*CloneLink*/) goSourceContent := fmt.Sprintf("%s _ %s %s", goGetImport, prefix+"{/dir}" /*GoDocDirectory*/, prefix+"{/dir}/{file}#L{line}" /*GoDocFile*/) goGetCli := fmt.Sprintf("go get %s%s", insecure, goGetImport) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 0865d9d7c0f59..bba445f741f50 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -608,7 +608,9 @@ func handleSettingsPostAdvanced(ctx *context.Context) { } if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() { - units = append(units, newRepoUnit(repo, unit_model.TypePackages, nil)) + units = append(units, newRepoUnit(repo, unit_model.TypePackages, &repo_model.PackagesConfig{ + GoModuleSubDir: form.GoModuleSubDir, + })) } else if !unit_model.TypePackages.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) } diff --git a/services/context/repo.go b/services/context/repo.go index afc6de9b1666d..adfd438c0e498 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -344,6 +344,13 @@ func EarlyResponseForGoGetMeta(ctx *Context) { ctx.PlainText(http.StatusOK, htmlMeta) } +// GetGoModuleSubDirConfig retrieves the subdirectory configuration for a Go module. +func GetGoModuleSubDirConfig(ctx *Context, repo *repo_model.Repository) string { + pkgCfg := repo.MustGetUnit(ctx, unit_model.TypePackages).PackagesConfig() + + return strings.TrimSpace(pkgCfg.GoModuleSubDir) +} + // RedirectToRepo redirect to a differently-named repository func RedirectToRepo(ctx *Base, redirectRepoID int64) { ownerName := ctx.PathParam("username") diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index cb267f891ccb7..89639a6d5d38e 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -150,6 +150,8 @@ type RepoSettingForm struct { EnableActions bool + GoModuleSubDir string + IsArchived bool // Signing Settings diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index fc42056e0a2bb..36aa90933cf17 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -499,16 +499,28 @@ +
{{$isPackagesEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypePackages}} {{$isPackagesGlobalDisabled := ctx.Consts.RepoUnitTypePackages.UnitGlobalDisabled}} + {{$pkgUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypePackages}}
- +
+
+
+ + +

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

+
+
+ +
+ {{if .EnableActions}} {{$isActionsEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeActions}} {{$isActionsGlobalDisabled := ctx.Consts.RepoUnitTypeActions.UnitGlobalDisabled}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 749d86901de93..84efe618c37ac 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -24328,6 +24328,11 @@ "external_wiki": { "$ref": "#/definitions/ExternalWiki" }, + "go_module_sub_dir": { + "description": "set the subdirectory for Go modules", + "type": "string", + "x-go-name": "GoModuleSubDir" + }, "has_actions": { "description": "either `true` to enable actions unit, or `false` to disable them.", "type": "boolean", diff --git a/tests/integration/goget_test.go b/tests/integration/goget_test.go index 854f8d7a2dbe1..efa1ed4b9ac80 100644 --- a/tests/integration/goget_test.go +++ b/tests/integration/goget_test.go @@ -8,6 +8,10 @@ import ( "net/http" "testing" + auth_model "code.gitea.io/gitea/models/auth" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/tests" @@ -34,6 +38,39 @@ func TestGoGet(t *testing.T) { assert.Equal(t, expected, resp.Body.String()) } +func TestGoGetSubDir(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + + // Get user2's token + session := loginUser(t, user2.Name) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + repoEditOption := getRepoEditOptionFromRepo(repo1) + goModuleSubDir := "package" + repoEditOption.GoModuleSubDir = &goModuleSubDir + req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption). + AddTokenAuth(token2) + MakeRequest(t, req, http.StatusOK) + + req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/plah?go-get=1", user2.Name, repo1.Name)) + resp := MakeRequest(t, req, http.StatusOK) + + expected := fmt.Sprintf(` + + + + + + + go get --insecure %[1]s:%[2]s/%[4]s/%[5]s + +`, setting.Domain, setting.HTTPPort, setting.AppURL, user2.Name, repo1.Name) + + assert.Equal(t, expected, resp.Body.String()) +} + func TestGoGetForSSH(t *testing.T) { defer tests.PrepareTestEnv(t)() From 7d8595bad7e7388c94f1c1c46dcf2cb03260dd2d Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Sat, 16 Aug 2025 14:57:33 +0800 Subject: [PATCH 2/4] maybe add a special unit named as `misc` to sore these special repo level configs --- models/repo/repo.go | 4 ++-- models/repo/repo_unit.go | 24 ++++++++++++------------ models/unit/unit.go | 26 ++++++++++++++++++++++++++ options/locale/locale_en-US.ini | 1 + routers/api/v1/repo/repo.go | 24 ++++++++++++++++-------- routers/web/repo/setting/setting.go | 8 +++++--- services/context/context.go | 1 + services/context/repo.go | 4 ++-- templates/repo/settings/options.tmpl | 28 +++++++++++++++------------- 9 files changed, 80 insertions(+), 40 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 4708adec4195a..1818553c7b1aa 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -468,8 +468,8 @@ func (repo *Repository) MustGetUnit(ctx context.Context, tp unit.Type) *RepoUnit Type: tp, Config: cfg, } - case unit.TypePackages: - cfg := new(PackagesConfig) + case unit.TypeMisc: + cfg := new(MiscConfig) return &RepoUnit{ Type: tp, Config: cfg, diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index f8677854f3215..27966611eec10 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -264,11 +264,11 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { r.Config = new(IssuesConfig) case unit.TypeActions: r.Config = new(ActionsConfig) - case unit.TypePackages: - r.Config = new(PackagesConfig) case unit.TypeProjects: r.Config = new(ProjectsConfig) - case unit.TypeCode, unit.TypeReleases, unit.TypeWiki: + case unit.TypeMisc: + r.Config = new(MiscConfig) + case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypePackages: fallthrough default: r.Config = new(UnitConfig) @@ -321,23 +321,23 @@ func (r *RepoUnit) ProjectsConfig() *ProjectsConfig { return r.Config.(*ProjectsConfig) } -// PackagesConfig returns config for unit.PackagesConfig -func (r *RepoUnit) PackagesConfig() *PackagesConfig { - return r.Config.(*PackagesConfig) +// MiscConfig returns config for unit.MiscConfig +func (r *RepoUnit) MiscConfig() *MiscConfig { + return r.Config.(*MiscConfig) } -// PackagesConfig describes package config -type PackagesConfig struct { +// MiscConfig describes repo misc config +type MiscConfig struct { GoModuleSubDir string } -// FromDB fills up a PackagesConfig from serialized format. -func (cfg *PackagesConfig) FromDB(bs []byte) error { +// FromDB fills up a MiscConfig from serialized format. +func (cfg *MiscConfig) FromDB(bs []byte) error { return json.UnmarshalHandleDoubleEncode(bs, &cfg) } -// ToDB exports a PackagesConfig to a serialized format. -func (cfg *PackagesConfig) ToDB() ([]byte, error) { +// ToDB exports a MiscConfig to a serialized format. +func (cfg *MiscConfig) ToDB() ([]byte, error) { return json.Marshal(cfg) } diff --git a/models/unit/unit.go b/models/unit/unit.go index c0560678ca9aa..bf13491836782 100644 --- a/models/unit/unit.go +++ b/models/unit/unit.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) // Type is Unit's Type @@ -34,6 +35,10 @@ const ( TypePackages // 9 Packages TypeActions // 10 Actions + // misc is a special uint to store special configs for a repo which is not related to any unit, + // it should be considered as enabled anyway + TypeMisc Type = 999 // 999 misc + // FIXME: TEAM-UNIT-PERMISSION: the team unit "admin" permission's design is not right, when a new unit is added in the future, // admin team won't inherit the correct admin permission for the new unit, need to have a complete fix before adding any new unit. ) @@ -65,6 +70,7 @@ var ( TypeProjects, TypePackages, TypeActions, + TypeMisc, } // DefaultRepoUnits contains the default unit types @@ -77,12 +83,14 @@ var ( TypeProjects, TypePackages, TypeActions, + TypeMisc, } // ForkRepoUnits contains the default unit types for forks DefaultForkRepoUnits = []Type{ TypeCode, TypePullRequests, + TypeMisc, } // DefaultMirrorRepoUnits contains the default unit types for mirrors @@ -93,6 +101,7 @@ var ( TypeWiki, TypeProjects, TypePackages, + TypeMisc, } // DefaultTemplateRepoUnits contains the default unit types for templates @@ -104,12 +113,14 @@ var ( TypeWiki, TypeProjects, TypePackages, + TypeMisc, } // NotAllowedDefaultRepoUnits contains units that can't be default NotAllowedDefaultRepoUnits = []Type{ TypeExternalWiki, TypeExternalTracker, + TypeMisc, } disabledRepoUnitsAtomic atomic.Pointer[[]Type] // the units that have been globally disabled @@ -163,6 +174,11 @@ func LoadUnitConfig() error { if len(invalidKeys) > 0 { log.Warn("Invalid keys in disabled repo units: %s", strings.Join(invalidKeys, ", ")) } + if slices.Contains(disabledRepoUnits, TypeMisc) { + log.Warn("Misc unit should not be disabled") + disabledRepoUnits = util.SliceRemoveAll(disabledRepoUnits, TypeMisc) + } + DisabledRepoUnitsSet(disabledRepoUnits) setDefaultRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultRepoUnits...) @@ -328,6 +344,15 @@ var ( perm.AccessModeOwner, } + UnitMisc = Unit{ + TypeMisc, + "repo.misc", + "/misc", + "misc.unit.desc", + 999, + perm.AccessModeOwner, + } + // Units contains all the units Units = map[Type]Unit{ TypeCode: UnitCode, @@ -340,6 +365,7 @@ var ( TypeProjects: UnitProjects, TypePackages: UnitPackages, TypeActions: UnitActions, + TypeMisc: UnitMisc, } ) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b020c1be7c3ac..74769e88bd24a 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2629,6 +2629,7 @@ settings.rename_branch_from=old branch name settings.rename_branch_to=new branch name settings.rename_branch=Rename branch +misc = Misc settings.go_module_sub_dir = Golang module subdirectory settings.go_module_sub_dir_desc = The subdirectory in repository redirect for go module (which is supported since go 1.25, see %[2]s for more detail) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 0d737d4e97560..fc89a4d58a48f 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -994,17 +994,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if opts.HasPackages != nil && !unit_model.TypePackages.UnitGlobalDisabled() { if *opts.HasPackages { - unit := repo.MustGetUnit(ctx, unit_model.TypePackages) - cfg := unit.PackagesConfig() - - if opts.GoModuleSubDir != nil { - cfg.GoModuleSubDir = *opts.GoModuleSubDir - } - units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, Type: unit_model.TypePackages, - Config: cfg, }) } else { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) @@ -1022,6 +1014,22 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { } } + miscCfg := repo.MustGetUnit(ctx, unit_model.TypeMisc).MiscConfig() + misCfgUpdated := false + + if opts.GoModuleSubDir != nil { + miscCfg.GoModuleSubDir = *opts.GoModuleSubDir + misCfgUpdated = true + } + + if misCfgUpdated { + units = append(units, repo_model.RepoUnit{ + RepoID: repo.ID, + Type: unit_model.TypeMisc, + Config: miscCfg, + }) + } + if len(units)+len(deleteUnitTypes) > 0 { if err := repo_service.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil { ctx.APIErrorInternal(err) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index bba445f741f50..5a23a75aff207 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -608,9 +608,7 @@ func handleSettingsPostAdvanced(ctx *context.Context) { } if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() { - units = append(units, newRepoUnit(repo, unit_model.TypePackages, &repo_model.PackagesConfig{ - GoModuleSubDir: form.GoModuleSubDir, - })) + units = append(units, newRepoUnit(repo, unit_model.TypePackages, nil)) } else if !unit_model.TypePackages.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) } @@ -640,6 +638,10 @@ func handleSettingsPostAdvanced(ctx *context.Context) { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests) } + miscCfg := repo.MustGetUnit(ctx, unit_model.TypeMisc).MiscConfig() + miscCfg.GoModuleSubDir = form.GoModuleSubDir + units = append(units, newRepoUnit(repo, unit_model.TypeMisc, miscCfg)) + if len(units) == 0 { ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit")) ctx.Redirect(ctx.Repo.RepoLink + "/settings") diff --git a/services/context/context.go b/services/context/context.go index 32ec260aab931..05d1b988f3d16 100644 --- a/services/context/context.go +++ b/services/context/context.go @@ -119,6 +119,7 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext { "RepoUnitTypeProjects": unit.TypeProjects, "RepoUnitTypePackages": unit.TypePackages, "RepoUnitTypeActions": unit.TypeActions, + "RepoUnitTypeMisc": unit.TypeMisc, } return tmplCtx } diff --git a/services/context/repo.go b/services/context/repo.go index adfd438c0e498..41ca476d1fd82 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -346,9 +346,9 @@ func EarlyResponseForGoGetMeta(ctx *Context) { // GetGoModuleSubDirConfig retrieves the subdirectory configuration for a Go module. func GetGoModuleSubDirConfig(ctx *Context, repo *repo_model.Repository) string { - pkgCfg := repo.MustGetUnit(ctx, unit_model.TypePackages).PackagesConfig() + miscCfg := repo.MustGetUnit(ctx, unit_model.TypeMisc).MiscConfig() - return strings.TrimSpace(pkgCfg.GoModuleSubDir) + return strings.TrimSpace(miscCfg.GoModuleSubDir) } // RedirectToRepo redirect to a differently-named repository diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 36aa90933cf17..d2f249aaf1ae7 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -499,28 +499,16 @@ -
{{$isPackagesEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypePackages}} {{$isPackagesGlobalDisabled := ctx.Consts.RepoUnitTypePackages.UnitGlobalDisabled}} - {{$pkgUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypePackages}}
- +
-
-
- - -

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

-
-
- -
- {{if .EnableActions}} {{$isActionsEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeActions}} {{$isActionsGlobalDisabled := ctx.Consts.RepoUnitTypeActions.UnitGlobalDisabled}} @@ -659,6 +647,20 @@ {{end}} +
+ {{$miscUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypeMisc}} +
+ +
+ +
+
+ + +

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

+
+
+
From 26f9a9147bf3dc9b365d0b586fd43eee47e1b272 Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Sun, 17 Aug 2025 11:43:23 +0800 Subject: [PATCH 3/4] Revert "maybe add a special unit named as `misc` to sore these special repo level configs" This reverts commit 7d8595bad7e7388c94f1c1c46dcf2cb03260dd2d. --- models/repo/repo.go | 4 ++-- models/repo/repo_unit.go | 24 ++++++++++++------------ models/unit/unit.go | 26 -------------------------- options/locale/locale_en-US.ini | 1 - routers/api/v1/repo/repo.go | 24 ++++++++---------------- routers/web/repo/setting/setting.go | 8 +++----- services/context/context.go | 1 - services/context/repo.go | 4 ++-- templates/repo/settings/options.tmpl | 28 +++++++++++++--------------- 9 files changed, 40 insertions(+), 80 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 1818553c7b1aa..4708adec4195a 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -468,8 +468,8 @@ func (repo *Repository) MustGetUnit(ctx context.Context, tp unit.Type) *RepoUnit Type: tp, Config: cfg, } - case unit.TypeMisc: - cfg := new(MiscConfig) + case unit.TypePackages: + cfg := new(PackagesConfig) return &RepoUnit{ Type: tp, Config: cfg, diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index 27966611eec10..f8677854f3215 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -264,11 +264,11 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { r.Config = new(IssuesConfig) case unit.TypeActions: r.Config = new(ActionsConfig) + case unit.TypePackages: + r.Config = new(PackagesConfig) case unit.TypeProjects: r.Config = new(ProjectsConfig) - case unit.TypeMisc: - r.Config = new(MiscConfig) - case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypePackages: + case unit.TypeCode, unit.TypeReleases, unit.TypeWiki: fallthrough default: r.Config = new(UnitConfig) @@ -321,23 +321,23 @@ func (r *RepoUnit) ProjectsConfig() *ProjectsConfig { return r.Config.(*ProjectsConfig) } -// MiscConfig returns config for unit.MiscConfig -func (r *RepoUnit) MiscConfig() *MiscConfig { - return r.Config.(*MiscConfig) +// PackagesConfig returns config for unit.PackagesConfig +func (r *RepoUnit) PackagesConfig() *PackagesConfig { + return r.Config.(*PackagesConfig) } -// MiscConfig describes repo misc config -type MiscConfig struct { +// PackagesConfig describes package config +type PackagesConfig struct { GoModuleSubDir string } -// FromDB fills up a MiscConfig from serialized format. -func (cfg *MiscConfig) FromDB(bs []byte) error { +// FromDB fills up a PackagesConfig from serialized format. +func (cfg *PackagesConfig) FromDB(bs []byte) error { return json.UnmarshalHandleDoubleEncode(bs, &cfg) } -// ToDB exports a MiscConfig to a serialized format. -func (cfg *MiscConfig) ToDB() ([]byte, error) { +// ToDB exports a PackagesConfig to a serialized format. +func (cfg *PackagesConfig) ToDB() ([]byte, error) { return json.Marshal(cfg) } diff --git a/models/unit/unit.go b/models/unit/unit.go index bf13491836782..c0560678ca9aa 100644 --- a/models/unit/unit.go +++ b/models/unit/unit.go @@ -14,7 +14,6 @@ import ( "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" ) // Type is Unit's Type @@ -35,10 +34,6 @@ const ( TypePackages // 9 Packages TypeActions // 10 Actions - // misc is a special uint to store special configs for a repo which is not related to any unit, - // it should be considered as enabled anyway - TypeMisc Type = 999 // 999 misc - // FIXME: TEAM-UNIT-PERMISSION: the team unit "admin" permission's design is not right, when a new unit is added in the future, // admin team won't inherit the correct admin permission for the new unit, need to have a complete fix before adding any new unit. ) @@ -70,7 +65,6 @@ var ( TypeProjects, TypePackages, TypeActions, - TypeMisc, } // DefaultRepoUnits contains the default unit types @@ -83,14 +77,12 @@ var ( TypeProjects, TypePackages, TypeActions, - TypeMisc, } // ForkRepoUnits contains the default unit types for forks DefaultForkRepoUnits = []Type{ TypeCode, TypePullRequests, - TypeMisc, } // DefaultMirrorRepoUnits contains the default unit types for mirrors @@ -101,7 +93,6 @@ var ( TypeWiki, TypeProjects, TypePackages, - TypeMisc, } // DefaultTemplateRepoUnits contains the default unit types for templates @@ -113,14 +104,12 @@ var ( TypeWiki, TypeProjects, TypePackages, - TypeMisc, } // NotAllowedDefaultRepoUnits contains units that can't be default NotAllowedDefaultRepoUnits = []Type{ TypeExternalWiki, TypeExternalTracker, - TypeMisc, } disabledRepoUnitsAtomic atomic.Pointer[[]Type] // the units that have been globally disabled @@ -174,11 +163,6 @@ func LoadUnitConfig() error { if len(invalidKeys) > 0 { log.Warn("Invalid keys in disabled repo units: %s", strings.Join(invalidKeys, ", ")) } - if slices.Contains(disabledRepoUnits, TypeMisc) { - log.Warn("Misc unit should not be disabled") - disabledRepoUnits = util.SliceRemoveAll(disabledRepoUnits, TypeMisc) - } - DisabledRepoUnitsSet(disabledRepoUnits) setDefaultRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultRepoUnits...) @@ -344,15 +328,6 @@ var ( perm.AccessModeOwner, } - UnitMisc = Unit{ - TypeMisc, - "repo.misc", - "/misc", - "misc.unit.desc", - 999, - perm.AccessModeOwner, - } - // Units contains all the units Units = map[Type]Unit{ TypeCode: UnitCode, @@ -365,7 +340,6 @@ var ( TypeProjects: UnitProjects, TypePackages: UnitPackages, TypeActions: UnitActions, - TypeMisc: UnitMisc, } ) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 74769e88bd24a..b020c1be7c3ac 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2629,7 +2629,6 @@ settings.rename_branch_from=old branch name settings.rename_branch_to=new branch name settings.rename_branch=Rename branch -misc = Misc settings.go_module_sub_dir = Golang module subdirectory settings.go_module_sub_dir_desc = The subdirectory in repository redirect for go module (which is supported since go 1.25, see %[2]s for more detail) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index fc89a4d58a48f..0d737d4e97560 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -994,9 +994,17 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if opts.HasPackages != nil && !unit_model.TypePackages.UnitGlobalDisabled() { if *opts.HasPackages { + unit := repo.MustGetUnit(ctx, unit_model.TypePackages) + cfg := unit.PackagesConfig() + + if opts.GoModuleSubDir != nil { + cfg.GoModuleSubDir = *opts.GoModuleSubDir + } + units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, Type: unit_model.TypePackages, + Config: cfg, }) } else { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) @@ -1014,22 +1022,6 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { } } - miscCfg := repo.MustGetUnit(ctx, unit_model.TypeMisc).MiscConfig() - misCfgUpdated := false - - if opts.GoModuleSubDir != nil { - miscCfg.GoModuleSubDir = *opts.GoModuleSubDir - misCfgUpdated = true - } - - if misCfgUpdated { - units = append(units, repo_model.RepoUnit{ - RepoID: repo.ID, - Type: unit_model.TypeMisc, - Config: miscCfg, - }) - } - if len(units)+len(deleteUnitTypes) > 0 { if err := repo_service.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil { ctx.APIErrorInternal(err) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 5a23a75aff207..bba445f741f50 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -608,7 +608,9 @@ func handleSettingsPostAdvanced(ctx *context.Context) { } if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() { - units = append(units, newRepoUnit(repo, unit_model.TypePackages, nil)) + units = append(units, newRepoUnit(repo, unit_model.TypePackages, &repo_model.PackagesConfig{ + GoModuleSubDir: form.GoModuleSubDir, + })) } else if !unit_model.TypePackages.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) } @@ -638,10 +640,6 @@ func handleSettingsPostAdvanced(ctx *context.Context) { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests) } - miscCfg := repo.MustGetUnit(ctx, unit_model.TypeMisc).MiscConfig() - miscCfg.GoModuleSubDir = form.GoModuleSubDir - units = append(units, newRepoUnit(repo, unit_model.TypeMisc, miscCfg)) - if len(units) == 0 { ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit")) ctx.Redirect(ctx.Repo.RepoLink + "/settings") diff --git a/services/context/context.go b/services/context/context.go index 05d1b988f3d16..32ec260aab931 100644 --- a/services/context/context.go +++ b/services/context/context.go @@ -119,7 +119,6 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext { "RepoUnitTypeProjects": unit.TypeProjects, "RepoUnitTypePackages": unit.TypePackages, "RepoUnitTypeActions": unit.TypeActions, - "RepoUnitTypeMisc": unit.TypeMisc, } return tmplCtx } diff --git a/services/context/repo.go b/services/context/repo.go index 41ca476d1fd82..adfd438c0e498 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -346,9 +346,9 @@ func EarlyResponseForGoGetMeta(ctx *Context) { // GetGoModuleSubDirConfig retrieves the subdirectory configuration for a Go module. func GetGoModuleSubDirConfig(ctx *Context, repo *repo_model.Repository) string { - miscCfg := repo.MustGetUnit(ctx, unit_model.TypeMisc).MiscConfig() + pkgCfg := repo.MustGetUnit(ctx, unit_model.TypePackages).PackagesConfig() - return strings.TrimSpace(miscCfg.GoModuleSubDir) + return strings.TrimSpace(pkgCfg.GoModuleSubDir) } // RedirectToRepo redirect to a differently-named repository diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index d2f249aaf1ae7..36aa90933cf17 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -499,16 +499,28 @@
+
{{$isPackagesEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypePackages}} {{$isPackagesGlobalDisabled := ctx.Consts.RepoUnitTypePackages.UnitGlobalDisabled}} + {{$pkgUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypePackages}}
- +
+
+
+ + +

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

+
+
+ +
+ {{if .EnableActions}} {{$isActionsEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeActions}} {{$isActionsGlobalDisabled := ctx.Consts.RepoUnitTypeActions.UnitGlobalDisabled}} @@ -647,20 +659,6 @@ {{end}} -
- {{$miscUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypeMisc}} -
- -
- -
-
- - -

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

-
-
-
From 1b09fcb70e172cc320183a0a7c2d799f6000f97d Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Sun, 17 Aug 2025 12:37:26 +0800 Subject: [PATCH 4/4] use unitCode --- models/repo/repo.go | 4 +-- models/repo/repo_unit.go | 45 +++++++++++++--------------- routers/api/v1/repo/repo.go | 16 +++++----- routers/web/repo/setting/setting.go | 8 ++--- services/context/repo.go | 4 +-- templates/repo/settings/options.tmpl | 28 ++++++++--------- 6 files changed, 49 insertions(+), 56 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 4708adec4195a..fbb42b5e2db1e 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -468,8 +468,8 @@ func (repo *Repository) MustGetUnit(ctx context.Context, tp unit.Type) *RepoUnit Type: tp, Config: cfg, } - case unit.TypePackages: - cfg := new(PackagesConfig) + case unit.TypeCode: + cfg := new(CodeConfig) return &RepoUnit{ Type: tp, Config: cfg, diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index f8677854f3215..4250560e5dac3 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -264,11 +264,11 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { r.Config = new(IssuesConfig) case unit.TypeActions: r.Config = new(ActionsConfig) - case unit.TypePackages: - r.Config = new(PackagesConfig) case unit.TypeProjects: r.Config = new(ProjectsConfig) - case unit.TypeCode, unit.TypeReleases, unit.TypeWiki: + case unit.TypeCode: + r.Config = new(CodeConfig) + case unit.TypeReleases, unit.TypeWiki, unit.TypePackages: fallthrough default: r.Config = new(UnitConfig) @@ -281,9 +281,24 @@ func (r *RepoUnit) Unit() unit.Unit { return unit.Units[r.Type] } +// CodeConfig describes code config +type CodeConfig struct { + GoModuleSubDir string +} + +// FromDB fills up a CodeConfig from serialized format. +func (cfg *CodeConfig) FromDB(bs []byte) error { + return json.UnmarshalHandleDoubleEncode(bs, &cfg) +} + +// ToDB exports a CodeConfig to a serialized format. +func (cfg *CodeConfig) ToDB() ([]byte, error) { + return json.Marshal(cfg) +} + // CodeConfig returns config for unit.TypeCode -func (r *RepoUnit) CodeConfig() *UnitConfig { - return r.Config.(*UnitConfig) +func (r *RepoUnit) CodeConfig() *CodeConfig { + return r.Config.(*CodeConfig) } // PullRequestsConfig returns config for unit.TypePullRequests @@ -321,26 +336,6 @@ func (r *RepoUnit) ProjectsConfig() *ProjectsConfig { return r.Config.(*ProjectsConfig) } -// PackagesConfig returns config for unit.PackagesConfig -func (r *RepoUnit) PackagesConfig() *PackagesConfig { - return r.Config.(*PackagesConfig) -} - -// PackagesConfig describes package config -type PackagesConfig struct { - GoModuleSubDir string -} - -// FromDB fills up a PackagesConfig from serialized format. -func (cfg *PackagesConfig) FromDB(bs []byte) error { - return json.UnmarshalHandleDoubleEncode(bs, &cfg) -} - -// ToDB exports a PackagesConfig to a serialized format. -func (cfg *PackagesConfig) ToDB() ([]byte, error) { - return json.Marshal(cfg) -} - func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) { var tmpUnits []*RepoUnit if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil { diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 0d737d4e97560..8a11d37a8108a 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -871,10 +871,16 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if opts.HasCode != nil && !unit_model.TypeCode.UnitGlobalDisabled() { if *opts.HasCode { + cfg := &repo_model.CodeConfig{} + + if opts.GoModuleSubDir != nil { + cfg.GoModuleSubDir = *opts.GoModuleSubDir + } + units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, Type: unit_model.TypeCode, - Config: &repo_model.UnitConfig{}, + Config: cfg, }) } else { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode) @@ -994,17 +1000,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if opts.HasPackages != nil && !unit_model.TypePackages.UnitGlobalDisabled() { if *opts.HasPackages { - unit := repo.MustGetUnit(ctx, unit_model.TypePackages) - cfg := unit.PackagesConfig() - - if opts.GoModuleSubDir != nil { - cfg.GoModuleSubDir = *opts.GoModuleSubDir - } - units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, Type: unit_model.TypePackages, - Config: cfg, }) } else { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index bba445f741f50..8c69078ab06ff 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -524,7 +524,9 @@ func handleSettingsPostAdvanced(ctx *context.Context) { } if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() { - units = append(units, newRepoUnit(repo, unit_model.TypeCode, nil)) + units = append(units, newRepoUnit(repo, unit_model.TypeCode, &repo_model.CodeConfig{ + GoModuleSubDir: form.GoModuleSubDir, + })) } else if !unit_model.TypeCode.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode) } @@ -608,9 +610,7 @@ func handleSettingsPostAdvanced(ctx *context.Context) { } if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() { - units = append(units, newRepoUnit(repo, unit_model.TypePackages, &repo_model.PackagesConfig{ - GoModuleSubDir: form.GoModuleSubDir, - })) + units = append(units, newRepoUnit(repo, unit_model.TypePackages, nil)) } else if !unit_model.TypePackages.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages) } diff --git a/services/context/repo.go b/services/context/repo.go index adfd438c0e498..71f2e168f8b5f 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -346,9 +346,9 @@ func EarlyResponseForGoGetMeta(ctx *Context) { // GetGoModuleSubDirConfig retrieves the subdirectory configuration for a Go module. func GetGoModuleSubDirConfig(ctx *Context, repo *repo_model.Repository) string { - pkgCfg := repo.MustGetUnit(ctx, unit_model.TypePackages).PackagesConfig() + codeCfg := repo.MustGetUnit(ctx, unit_model.TypeCode).CodeConfig() - return strings.TrimSpace(pkgCfg.GoModuleSubDir) + return strings.TrimSpace(codeCfg.GoModuleSubDir) } // RedirectToRepo redirect to a differently-named repository diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 36aa90933cf17..c048d0f01f2a7 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -304,14 +304,26 @@ {{$isCodeEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeCode}} {{$isCodeGlobalDisabled := ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled}} + {{$codeUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypeCode}} +
- +
+
+
+ + +

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

+
+
+ +
+ {{$isInternalWikiEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeWiki}} {{$isExternalWikiEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeExternalWiki}} {{$isWikiEnabled := or $isInternalWikiEnabled $isExternalWikiEnabled}} @@ -499,28 +511,16 @@
-
{{$isPackagesEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypePackages}} {{$isPackagesGlobalDisabled := ctx.Consts.RepoUnitTypePackages.UnitGlobalDisabled}} - {{$pkgUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypePackages}}
- +
-
-
- - -

{{ctx.Locale.Tr "repo.settings.go_module_sub_dir_desc" "https://github.com/golang/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86" "github.com/golang/go@835e36fc7f"}}

-
-
- -
- {{if .EnableActions}} {{$isActionsEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeActions}} {{$isActionsGlobalDisabled := ctx.Consts.RepoUnitTypeActions.UnitGlobalDisabled}}