Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move UI configurations that do not require restarting gitea to take effect to the admin dashboard #33909

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions models/issues/milestone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func TestGetMilestones(t *testing.T) {
milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
ListOptions: db.ListOptions{
Page: page,
PageSize: setting.UI.IssuePagingNum,
PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()),
},
RepoID: repo.ID,
IsClosed: optional.Some(false),
Expand All @@ -115,7 +115,7 @@ func TestGetMilestones(t *testing.T) {
milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
ListOptions: db.ListOptions{
Page: page,
PageSize: setting.UI.IssuePagingNum,
PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()),
},
RepoID: repo.ID,
IsClosed: optional.Some(true),
Expand Down Expand Up @@ -231,7 +231,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) {
openMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
ListOptions: db.ListOptions{
Page: page,
PageSize: setting.UI.IssuePagingNum,
PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()),
},
RepoIDs: []int64{repo1.ID, repo2.ID},
IsClosed: optional.Some(false),
Expand All @@ -249,7 +249,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) {
issues_model.FindMilestoneOptions{
ListOptions: db.ListOptions{
Page: page,
PageSize: setting.UI.IssuePagingNum,
PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()),
},
RepoIDs: []int64{repo1.ID, repo2.ID},
IsClosed: optional.Some(true),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-
id: 1
setting_key: revision
version: 1

-
id: 2
setting_key: picture.enable_federated_avatar
setting_value: false
version: 1

-
id: 3
setting_key: picture.disable_gravatar
setting_value: true
version: 1
1 change: 1 addition & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ func prepareMigrationTasks() []*migration {
newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables),
newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner),
newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
newMigration(317, "Migrate the configuration of the ui section of the ini configuration file to the system setting table.", v1_24.MigrateIniToDatabase),
}
return preparedMigrations
}
Expand Down
14 changes: 14 additions & 0 deletions models/migrations/v1_24/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_24 //nolint

import (
"testing"

"code.gitea.io/gitea/models/migrations/base"
)

func TestMain(m *testing.M) {
base.MainTest(m)
}
103 changes: 103 additions & 0 deletions models/migrations/v1_24/v317.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_24 //nolint

import (
"fmt"
"math"
"strconv"

"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"

"xorm.io/xorm"
)

const keyRevision = "revision"

type Setting struct {
ID int64 `xorm:"pk autoincr"`
SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase
SettingValue string `xorm:"text"`
Version int `xorm:"version"`
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
}

// TableName sets the table name for the settings struct
func (s *Setting) TableName() string {
return "system_setting"
}

func MigrateIniToDatabase(x *xorm.Engine) error {
uiMap := make(map[string]string)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("EXPLORE_PAGING_NUM"))] = strconv.Itoa(setting.ExplorePagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("SITEMAP_PAGING_NUM"))] = strconv.Itoa(setting.SitemapPagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("ISSUE_PAGING_NUM"))] = strconv.Itoa(setting.IssuePagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("REPO_SEARCH_PAGING_NUM"))] = strconv.Itoa(setting.RepoSearchPagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("MEMBERS_PAGING_NUM"))] = strconv.Itoa(setting.MembersPagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("FEED_MAX_COMMIT_NUM"))] = strconv.Itoa(setting.FeedMaxCommitNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("FEED_PAGING_NUM"))] = strconv.Itoa(setting.FeedPagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("PACKAGES_PAGING_NUM"))] = strconv.Itoa(setting.PackagesPagingNum)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("CODE_COMMENT_LINES"))] = strconv.Itoa(setting.CodeCommentLines)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("SHOW_USER_EMAIL"))] = strconv.FormatBool(setting.ShowUserEmail)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("SEARCH_REPO_DESCRIPTION"))] = strconv.FormatBool(setting.SearchRepoDescription)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("ONLY_SHOW_RELEVANT_REPOS"))] = strconv.FormatBool(setting.OnlyShowRelevantRepos)
uiMap[fmt.Sprintf("ui.%s", util.ToSnakeCase("EXPLORE_PAGING_DEFAULT_SORT"))] = fmt.Sprintf("\"%s\"", setting.ExploreDefaultSort)

sess := x.NewSession()
defer sess.Close()

if err := sess.Begin(); err != nil {
return err
}

if err := sess.Sync(new(Setting)); err != nil {
return err
}

_ = getRevision(sess) // prepare the "revision" key ahead

if _, err := sess.Exec("UPDATE system_setting SET version=version+1 WHERE setting_key=?", keyRevision); err != nil {
return err
}
for k, v := range uiMap {
res, err := sess.Exec("UPDATE system_setting SET version=version+1, setting_value=? WHERE setting_key=?", v, k)
if err != nil {
return err
}
rows, _ := res.RowsAffected()
if rows == 0 { // if no existing row, insert a new row
if _, err = sess.Insert(&Setting{SettingKey: k, SettingValue: v}); err != nil {
return err
}
}
}

return sess.Commit()
}

func getRevision(sess *xorm.Session) int {
revision := &Setting{}
exist, err := sess.Where("setting_key = ?", keyRevision).Get(revision)
if err != nil {
return 0
} else if !exist {
_, err = sess.Insert(&Setting{SettingKey: keyRevision, Version: 1})
if err != nil {
return 0
}
return 1
}

if revision.Version <= 0 || revision.Version >= math.MaxInt-1 {
_, err = sess.Exec("UPDATE system_setting SET version=1 WHERE setting_key=?", keyRevision)
if err != nil {
return 0
}
return 1
}
return revision.Version
}
27 changes: 27 additions & 0 deletions models/migrations/v1_24/v317_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_24 //nolint

import (
"testing"

"code.gitea.io/gitea/models/migrations/base"

"github.com/stretchr/testify/assert"
)

func Test_MigrateIniToDatabase(t *testing.T) {
// Prepare and load the testing database
x, deferable := base.PrepareTestEnv(t, 0, new(Setting))
defer deferable()
if x == nil || t.Failed() {
return
}

assert.NoError(t, MigrateIniToDatabase(x))

cnt, err := x.Table("system_setting").Where("setting_key LIKE 'ui.%'").Count()
assert.NoError(t, err)
assert.EqualValues(t, 13, cnt)
}
4 changes: 2 additions & 2 deletions modules/indexer/code/gitgrep/gitgrep.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ func PerformSearch(ctx context.Context, page int, repoID int64, gitRepo *git.Rep
}

total = len(res)
pageStart := min((page-1)*setting.UI.RepoSearchPagingNum, len(res))
pageEnd := min(page*setting.UI.RepoSearchPagingNum, len(res))
pageStart := min((page-1)*setting.Config().UI.RepoSearchPagingNum.Value(ctx), len(res))
pageEnd := min(page*setting.Config().UI.RepoSearchPagingNum.Value(ctx), len(res))
res = res[pageStart:pageEnd]
for _, r := range res {
searchResults = append(searchResults, &code_indexer.Result{
Expand Down
69 changes: 69 additions & 0 deletions modules/setting/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package setting

import (
"context"
"sync"

"code.gitea.io/gitea/modules/log"
Expand Down Expand Up @@ -51,9 +52,62 @@ type RepositoryStruct struct {
OpenWithEditorApps *config.Value[OpenWithEditorAppsType]
}

type UIStruct struct {
ExplorePagingNum *config.Value[int]
SitemapPagingNum *config.Value[int]
IssuePagingNum *config.Value[int]
RepoSearchPagingNum *config.Value[int]
MembersPagingNum *config.Value[int]
FeedMaxCommitNum *config.Value[int]
FeedPagingNum *config.Value[int]
PackagesPagingNum *config.Value[int]
CodeCommentLines *config.Value[int]
ShowUserEmail *config.Value[bool]
SearchRepoDescription *config.Value[bool]
OnlyShowRelevantRepos *config.Value[bool]
ExploreDefaultSort *config.Value[string]
}

func (u *UIStruct) ToStruct(ctx context.Context) UIForm {
return UIForm{
ExplorePagingNum: u.ExplorePagingNum.Value(ctx),
SitemapPagingNum: u.SitemapPagingNum.Value(ctx),
IssuePagingNum: u.IssuePagingNum.Value(ctx),
RepoSearchPagingNum: u.RepoSearchPagingNum.Value(ctx),
MembersPagingNum: u.MembersPagingNum.Value(ctx),
FeedMaxCommitNum: u.FeedMaxCommitNum.Value(ctx),
FeedPagingNum: u.FeedPagingNum.Value(ctx),
PackagesPagingNum: u.PackagesPagingNum.Value(ctx),
CodeCommentLines: u.CodeCommentLines.Value(ctx),
ShowUserEmail: u.ShowUserEmail.Value(ctx),
SearchRepoDescription: u.SearchRepoDescription.Value(ctx),
OnlyShowRelevantRepos: u.OnlyShowRelevantRepos.Value(ctx),
ExplorePagingDefaultSort: u.ExploreDefaultSort.Value(ctx),
ExplorePagingSortOption: []string{"recentupdate", "alphabetically", "reverselastlogin", "newest", "oldest"},
}
}

type UIForm struct {
ExplorePagingNum int
SitemapPagingNum int
IssuePagingNum int
RepoSearchPagingNum int
MembersPagingNum int
FeedMaxCommitNum int
FeedPagingNum int
PackagesPagingNum int
CodeCommentLines int
ShowUserEmail bool
SearchRepoDescription bool
OnlyShowRelevantRepos bool
ExplorePagingDefaultSort string
ExplorePagingSortOption []string
}

type ConfigStruct struct {
Picture *PictureStruct
Repository *RepositoryStruct
UI *UIStruct
}

var (
Expand All @@ -71,6 +125,21 @@ func initDefaultConfig() {
Repository: &RepositoryStruct{
OpenWithEditorApps: config.ValueJSON[OpenWithEditorAppsType]("repository.open-with.editor-apps"),
},
UI: &UIStruct{
ExplorePagingNum: config.ValueJSON[int]("ui.explore_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "EXPLORE_PAGING_NUM"}).WithDefault(20),
SitemapPagingNum: config.ValueJSON[int]("ui.sitemap_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "SITEMAP_PAGING_NUM"}).WithDefault(20),
IssuePagingNum: config.ValueJSON[int]("ui.issue_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "ISSUE_PAGING_NUM"}).WithDefault(20),
RepoSearchPagingNum: config.ValueJSON[int]("ui.repo_search_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "REPO_SEARCH_PAGING_NUM"}).WithDefault(20),
MembersPagingNum: config.ValueJSON[int]("ui.members_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "MEMBERS_PAGING_NUM"}).WithDefault(20),
FeedMaxCommitNum: config.ValueJSON[int]("ui.feed_max_commit_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "FEED_MAX_COMMIT_NUM"}).WithDefault(20),
FeedPagingNum: config.ValueJSON[int]("ui.feed_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "FEED_PAGE_NUM"}).WithDefault(20),
PackagesPagingNum: config.ValueJSON[int]("ui.packages_paging_num").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "PACKAGES_PAGING_NUM"}).WithDefault(20),
CodeCommentLines: config.ValueJSON[int]("ui.code_comment_lines").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "CODE_COMMENT_LINES"}).WithDefault(4),
ShowUserEmail: config.ValueJSON[bool]("ui.show_user_email").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "SHOW_USER_EMAIL"}).WithDefault(true),
SearchRepoDescription: config.ValueJSON[bool]("ui.search_repo_description").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "SEARCH_REPO_DESCRIPTION"}).WithDefault(false),
OnlyShowRelevantRepos: config.ValueJSON[bool]("ui.only_show_relevant_repos").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "ONLY_SHOW_RELEVANT_REPOS"}).WithDefault(false),
ExploreDefaultSort: config.ValueJSON[string]("ui.explore_paging_default_sort").WithFileConfig(config.CfgSecKey{Sec: "ui", Key: "EXPLORE_PAGING_DEFAULT_SORT"}).WithDefault("recentupdate"),
},
}
}

Expand Down
Loading