feat: support .mokogitea, .profile, and .github as org/user profile repo names #657

Merged
jmiller merged 7 commits from dev into main 2026-06-20 18:06:09 +00:00
5 changed files with 68 additions and 19 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<name>MokoGitea</name>
<org>MokoConsulting</org>
<description>Moko fork of Gitea - adding project board REST API endpoints and custom enhancements</description>
<version>06.19.00</version>
<version>06.18.03</version>
<version-prefix>v1.26.1+MOKO</version-prefix>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokoplatform.Automation
# VERSION: 06.19.00
# VERSION: 06.18.03
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+2
View File
@@ -212,6 +212,8 @@ func TestIsUsableRepoName(t *testing.T) {
assert.NoError(t, IsUsableRepoName("a"))
assert.NoError(t, IsUsableRepoName("-1_."))
assert.NoError(t, IsUsableRepoName(".profile"))
assert.NoError(t, IsUsableRepoName(".mokogitea"))
assert.NoError(t, IsUsableRepoName(".github"))
assert.Error(t, IsUsableRepoName("-"))
assert.Error(t, IsUsableRepoName("🌞"))
+16 -5
View File
@@ -158,13 +158,24 @@ func Wiki(ctx *context.Context) {
}
// findOrgWikiCommit locates the profile repo's wiki and returns its HEAD commit.
// The org wiki lives in the .wiki.git sidecar of the profile repo (e.g. .profile.wiki.git).
// The org wiki lives in the .wiki.git sidecar of the profile repo (e.g. .mokogitea.wiki.git).
// Tries fallback repo names (.profile, .github) if the primary doesn't exist.
func findOrgWikiCommit(ctx *context.Context, orgID int64, repoName string) (*repo_model.Repository, *git.Commit) {
dbRepo, err := repo_model.GetRepositoryByName(ctx, orgID, repoName)
if err != nil {
if !repo_model.IsErrRepoNotExist(err) {
log.Error("findOrgWikiCommit: GetRepositoryByName(%d, %s): %v", orgID, repoName, err)
namesToTry := shared_user.ProfileRepoFallbacks(repoName)
var dbRepo *repo_model.Repository
var err error
for _, name := range namesToTry {
dbRepo, err = repo_model.GetRepositoryByName(ctx, orgID, name)
if err == nil {
break
}
if !repo_model.IsErrRepoNotExist(err) {
log.Error("findOrgWikiCommit: GetRepositoryByName(%d, %s): %v", orgID, name, err)
return nil, nil
}
}
if dbRepo == nil {
return nil, nil
}
+48 -12
View File
@@ -93,17 +93,27 @@ func prepareContextForProfileBigAvatar(ctx *context.Context) {
func FindOwnerProfileReadme(ctx *context.Context, doer *user_model.User, optProfileRepoName ...string) (profileDbRepo *repo_model.Repository, profileReadmeBlob *git.Blob) {
profileRepoName := util.OptionalArg(optProfileRepoName, RepoNameProfile)
profileDbRepo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, profileRepoName)
if err != nil {
if !repo_model.IsErrRepoNotExist(err) {
log.Error("FindOwnerProfileReadme failed to GetRepositoryByName: %v", err)
namesToTry := ProfileRepoFallbacks(profileRepoName)
var err error
for _, name := range namesToTry {
profileDbRepo, err = repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, name)
if err == nil {
break
}
if !repo_model.IsErrRepoNotExist(err) {
log.Error("FindOwnerProfileReadme failed to GetRepositoryByName(%s): %v", name, err)
return nil, nil
}
}
if profileDbRepo == nil {
return nil, nil
}
perm, err := access_model.GetDoerRepoPermission(ctx, profileDbRepo, doer)
if err != nil {
log.Error("FindOwnerProfileReadme failed to GetRepositoryByName: %v", err)
log.Error("FindOwnerProfileReadme failed to GetDoerRepoPermission: %v", err)
return nil, nil
}
if profileDbRepo.IsEmpty || !perm.CanRead(unit.TypeCode) {
@@ -135,12 +145,29 @@ type PrepareOwnerHeaderResult struct {
}
const (
RepoNameProfilePrivate = ".profile-private"
RepoNameProfile = ".profile"
RepoNameWikiPublic = ".profile"
RepoNameWikiPrivate = ".profile-private"
RepoNameProfile = ".mokogitea"
RepoNameProfilePrivate = ".mokogitea-private"
RepoNameWikiPublic = ".mokogitea"
RepoNameWikiPrivate = ".mokogitea-private"
)
// profileFallbacks maps primary repo names to their fallback alternatives.
// Priority: .mokogitea > .profile > .github
var profileFallbacks = map[string][]string{
RepoNameProfile: {".profile", ".github"},
RepoNameProfilePrivate: {".profile-private", ".github-private"},
}
// ProfileRepoFallbacks returns the list of repo names to try for a given
// profile repo name, with the primary name first and fallbacks after.
func ProfileRepoFallbacks(repoName string) []string {
names := []string{repoName}
if fallbacks, ok := profileFallbacks[repoName]; ok {
names = append(names, fallbacks...)
}
return names
}
func RenderUserOrgHeader(ctx *context.Context) (result *PrepareOwnerHeaderResult, err error) {
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
@@ -210,10 +237,19 @@ func loadHeaderCount(ctx *context.Context) error {
}
// OrgWikiRepoExists checks whether a profile repo's wiki exists and has content.
// Tries fallback repo names (.mokogitea, .github) if the primary doesn't exist.
func OrgWikiRepoExists(ctx *context.Context, ownerID int64, repoName string) bool {
dbRepo, err := repo_model.GetRepositoryByName(ctx, ownerID, repoName)
if err != nil {
log.Trace("OrgWikiRepoExists: repo %s not found for owner %d: %v", repoName, ownerID, err)
namesToTry := ProfileRepoFallbacks(repoName)
var dbRepo *repo_model.Repository
var err error
for _, name := range namesToTry {
dbRepo, err = repo_model.GetRepositoryByName(ctx, ownerID, name)
if err == nil {
break
}
}
if dbRepo == nil {
return false
}
wikiRepo := dbRepo.WikiStorageRepo()