Skip to content

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

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

Closed
wants to merge 3 commits into from
Closed
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
13 changes: 13 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1258,24 +1258,31 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Number of repositories that are displayed on one explore page
;; Deprecated in v1.24
;EXPLORE_PAGING_NUM = 20
;;
;; Number of issues that are displayed on one page
;; Deprecated in v1.24
;ISSUE_PAGING_NUM = 20
;;
;; Number of maximum commits displayed in one activity feed
;; Deprecated in v1.24
;FEED_MAX_COMMIT_NUM = 5
;;
;; Number of items that are displayed in home feed
;; Deprecated in v1.24
;FEED_PAGING_NUM = 20
;;
;; Number of items that are displayed in a single subsitemap
;; Deprecated in v1.24
;SITEMAP_PAGING_NUM = 20
;;
;; Number of maximum commits displayed in commit graph.
;; Deprecated in v1.24
;GRAPH_MAX_COMMIT_NUM = 100
;;
;; Number of line of codes shown for a code comment
;; Deprecated in v1.24
;CODE_COMMENT_LINES = 4
;;
;; Max size of files to be displayed (default is 8MiB)
Expand All @@ -1285,6 +1292,7 @@ LEVEL = Info
;AMBIGUOUS_UNICODE_DETECTION = true
;;
;; Whether the email of the user should be shown in the Explore Users page
;; Deprecated in v1.24
;SHOW_USER_EMAIL = true
;;
;; Set the default theme for the Gitea install
Expand All @@ -1303,6 +1311,7 @@ LEVEL = Info
;REACTIONS = +1, -1, laugh, hooray, confused, heart, rocket, eyes
;;
;; Change the number of users that are displayed in reactions tooltip (triggered by mouse hover).
;; Deprecated in v1.24
;REACTION_MAX_USER_NUM = 10
;;
;; Additional Emojis not defined in the utf8 standard
Expand All @@ -1311,17 +1320,21 @@ LEVEL = Info
;CUSTOM_EMOJIS = gitea, codeberg, gitlab, git, github, gogs
;;
;; Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
;; Deprecated in v1.24
;DEFAULT_SHOW_FULL_NAME = false
;;
;; Whether to search within description at repository search on explore page.
;; Deprecated in v1.24
;SEARCH_REPO_DESCRIPTION = true
;;
;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).
;; Deprecated in v1.24
;ONLY_SHOW_RELEVANT_REPOS = false
;;
;; Change the sort type of the explore pages.
;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest".
;; Deprecated in v1.24
;EXPLORE_PAGING_DEFAULT_SORT = recentupdate
;;
;; The tense all timestamps should be rendered in. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) and `mixed`.
Expand Down
2 changes: 1 addition & 1 deletion models/actions/run_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,6 @@ func GetActors(ctx context.Context, repoID int64) ([]*user_model.User, error) {
GroupBy("`action_run`.trigger_user_id").
Where(builder.Eq{"`action_run`.repo_id": repoID}))).
Cols("id", "name", "full_name", "avatar", "avatar_email", "use_custom_avatar").
OrderBy(user_model.GetOrderByName()).
OrderBy(user_model.GetOrderByName(ctx)).
Find(&actors)
}
4 changes: 2 additions & 2 deletions models/activities/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (a *Action) ShortActUserName(ctx context.Context) string {

// GetActDisplayName gets the action's display name based on DEFAULT_SHOW_FULL_NAME, or falls back to the username if it is blank.
func (a *Action) GetActDisplayName(ctx context.Context) string {
if setting.UI.DefaultShowFullName {
if setting.Config().UI.DefaultShowFullName.Value(ctx) {
trimmedFullName := strings.TrimSpace(a.GetActFullName(ctx))
if len(trimmedFullName) > 0 {
return trimmedFullName
Expand All @@ -238,7 +238,7 @@ func (a *Action) GetActDisplayName(ctx context.Context) string {

// GetActDisplayNameTitle gets the action's display name used for the title (tooltip) based on DEFAULT_SHOW_FULL_NAME
func (a *Action) GetActDisplayNameTitle(ctx context.Context) string {
if setting.UI.DefaultShowFullName {
if setting.Config().UI.DefaultShowFullName.Value(ctx) {
return a.ShortActUserName(ctx)
}
return a.GetActFullName(ctx)
Expand Down
2 changes: 1 addition & 1 deletion models/issues/issue_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func (issues IssueList) LoadAssignees(ctx context.Context) error {
}
rows, err := db.GetEngine(ctx).Table("issue_assignees").
Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id").
In("`issue_assignees`.issue_id", issueIDs[:limit]).OrderBy(user_model.GetOrderByName()).
In("`issue_assignees`.issue_id", issueIDs[:limit]).OrderBy(user_model.GetOrderByName(ctx)).
Rows(new(AssigneeIssue))
if err != nil {
return err
Expand Down
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
10 changes: 5 additions & 5 deletions models/issues/reaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,9 @@ func (list ReactionList) LoadUsers(ctx context.Context, repo *repo_model.Reposit
}

// GetFirstUsers returns first reacted user display names separated by comma
func (list ReactionList) GetFirstUsers() string {
func (list ReactionList) GetFirstUsers(ctx context.Context) string {
var buffer bytes.Buffer
rem := setting.UI.ReactionMaxUserNum
rem := setting.Config().UI.ReactionMaxUserNum.Value(ctx)
for _, reaction := range list {
if buffer.Len() > 0 {
buffer.WriteString(", ")
Expand All @@ -371,9 +371,9 @@ func (list ReactionList) GetFirstUsers() string {
}

// GetMoreUserCount returns count of not shown users in reaction tooltip
func (list ReactionList) GetMoreUserCount() int {
if len(list) <= setting.UI.ReactionMaxUserNum {
func (list ReactionList) GetMoreUserCount(ctx context.Context) int {
if len(list) <= setting.Config().UI.ReactionMaxUserNum.Value(ctx) {
return 0
}
return len(list) - setting.UI.ReactionMaxUserNum
return len(list) - setting.Config().UI.ReactionMaxUserNum.Value(ctx)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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"`
# }
-
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 @@ -375,6 +375,7 @@ func prepareMigrationTasks() []*migration {
newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge),
newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin),
newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables),
newMigration(315, "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)
}
98 changes: 98 additions & 0 deletions models/migrations/v1_24/v315.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_24 //nolint

import (
"math"

"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, err := util.ConfigSectionToMap(
setting.UI, "ui",
[]string{
"Reactions", "CustomEmojis", "MaxDisplayFileSize", "DefaultTheme", "Themes",
"FileIconTheme", "PreferredTimestampTense", "AmbiguousUnicodeDetection",
}...,
)
if err != nil {
return err
}

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

_, err = sess.Exec("UPDATE system_setting SET version=version+1 WHERE setting_key=?", keyRevision)
if 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/v315_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, 16, cnt)
}
4 changes: 2 additions & 2 deletions models/organization/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ func (org *Organization) OrganisationLink() string {
}

// ShortName ellipses username to length
func (org *Organization) ShortName(length int) string {
return org.AsUser().ShortName(length)
func (org *Organization) ShortName(ctx context.Context, length int) string {
return org.AsUser().ShortName(ctx, length)
}

// HomeLink returns the user or organization home page link.
Expand Down
2 changes: 1 addition & 1 deletion models/organization/org_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func GetOrgAssignees(ctx context.Context, orgID int64) (_ []*user_model.User, er
if len(userIDs) > 0 {
if err = e.In("id", uniqueUserIDs.Values()).
Where(builder.Eq{"`user`.is_active": true}).
OrderBy(user_model.GetOrderByName()).
OrderBy(user_model.GetOrderByName(ctx)).
Find(&users); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion models/repo/user_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
if len(uniqueUserIDs) > 0 {
if err = e.In("id", uniqueUserIDs.Values()).
Where(builder.Eq{"`user`.is_active": true}).
OrderBy(user_model.GetOrderByName()).
OrderBy(user_model.GetOrderByName(ctx)).
Find(&users); err != nil {
return nil, err
}
Expand Down
Loading
Loading