]> source.dussan.org Git - gitea.git/commitdiff
Added instance-level variables (#28115)
authorJean-Baptiste Gomond <dev@jbgomond.com>
Mon, 25 Dec 2023 07:28:59 +0000 (08:28 +0100)
committerGitHub <noreply@github.com>
Mon, 25 Dec 2023 07:28:59 +0000 (07:28 +0000)
This PR adds instance-level variables, and so closes #27726

![gitea_instance_variables_1](https://github.com/go-gitea/gitea/assets/8344487/ad409cd4-ce36-4c84-a764-34451b0fb63a)

![gitea_instance_variables_2](https://github.com/go-gitea/gitea/assets/8344487/426f0965-dec6-4560-948c-067cdeddd720)

![gitea_instance_variables_3](https://github.com/go-gitea/gitea/assets/8344487/cf1d7776-4938-4825-922e-cbbbf28a5f33)

models/actions/variable.go
routers/api/actions/runner/utils.go
routers/web/repo/setting/variables.go
routers/web/web.go
templates/admin/actions.tmpl
templates/admin/navbar.tmpl

index 030b7bae92aed82655bc80e5a438ef3b9723f18d..12717e0ae46142a728db116b1e5274602aaedbac 100644 (file)
@@ -31,8 +31,8 @@ func init() {
 }
 
 func (v *ActionVariable) Validate() error {
-       if v.OwnerID == 0 && v.RepoID == 0 {
-               return errors.New("the variable is not bound to any scope")
+       if v.OwnerID != 0 && v.RepoID != 0 {
+               return errors.New("a variable should not be bound to an owner and a repository at the same time")
        }
        return nil
 }
@@ -58,12 +58,8 @@ type FindVariablesOpts struct {
 
 func (opts FindVariablesOpts) ToConds() builder.Cond {
        cond := builder.NewCond()
-       if opts.OwnerID > 0 {
-               cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
-       }
-       if opts.RepoID > 0 {
-               cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
-       }
+       cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
+       cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
        return cond
 }
 
index bf913f2c05783184118abac7b723c3a9eaf4e2f8..2555f86c80d80a2bd1030986c35d84726e0669f2 100644 (file)
@@ -94,6 +94,12 @@ func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[s
 func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string {
        variables := map[string]string{}
 
+       // Global
+       globalVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{})
+       if err != nil {
+               log.Error("find global variables: %v", err)
+       }
+
        // Org / User level
        ownerVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{OwnerID: task.Job.Run.Repo.OwnerID})
        if err != nil {
@@ -106,8 +112,8 @@ func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map
                log.Error("find variables of repo: %d, error: %v", task.Job.Run.RepoID, err)
        }
 
-       // Level precedence: Repo > Org / User
-       for _, v := range append(ownerVariables, repoVariables...) {
+       // Level precedence: Repo > Org / User > Global
+       for _, v := range append(globalVariables, append(ownerVariables, repoVariables...)...) {
                variables[v.Name] = v.Data
        }
 
index a697a5d8d857fe2d3a3146799f35897e545780ef..428aa0bd5c4fed5653e303d8dabea519c14adc14 100644 (file)
@@ -15,9 +15,10 @@ import (
 )
 
 const (
-       tplRepoVariables base.TplName = "repo/settings/actions"
-       tplOrgVariables  base.TplName = "org/settings/actions"
-       tplUserVariables base.TplName = "user/settings/actions"
+       tplRepoVariables  base.TplName = "repo/settings/actions"
+       tplOrgVariables   base.TplName = "org/settings/actions"
+       tplUserVariables  base.TplName = "user/settings/actions"
+       tplAdminVariables base.TplName = "admin/actions"
 )
 
 type variablesCtx struct {
@@ -26,6 +27,7 @@ type variablesCtx struct {
        IsRepo            bool
        IsOrg             bool
        IsUser            bool
+       IsGlobal          bool
        VariablesTemplate base.TplName
        RedirectLink      string
 }
@@ -33,6 +35,7 @@ type variablesCtx struct {
 func getVariablesCtx(ctx *context.Context) (*variablesCtx, error) {
        if ctx.Data["PageIsRepoSettings"] == true {
                return &variablesCtx{
+                       OwnerID:           0,
                        RepoID:            ctx.Repo.Repository.ID,
                        IsRepo:            true,
                        VariablesTemplate: tplRepoVariables,
@@ -48,6 +51,7 @@ func getVariablesCtx(ctx *context.Context) (*variablesCtx, error) {
                }
                return &variablesCtx{
                        OwnerID:           ctx.ContextUser.ID,
+                       RepoID:            0,
                        IsOrg:             true,
                        VariablesTemplate: tplOrgVariables,
                        RedirectLink:      ctx.Org.OrgLink + "/settings/actions/variables",
@@ -57,12 +61,23 @@ func getVariablesCtx(ctx *context.Context) (*variablesCtx, error) {
        if ctx.Data["PageIsUserSettings"] == true {
                return &variablesCtx{
                        OwnerID:           ctx.Doer.ID,
+                       RepoID:            0,
                        IsUser:            true,
                        VariablesTemplate: tplUserVariables,
                        RedirectLink:      setting.AppSubURL + "/user/settings/actions/variables",
                }, nil
        }
 
+       if ctx.Data["PageIsAdmin"] == true {
+               return &variablesCtx{
+                       OwnerID:           0,
+                       RepoID:            0,
+                       IsGlobal:          true,
+                       VariablesTemplate: tplAdminVariables,
+                       RedirectLink:      setting.AppSubURL + "/admin/actions/variables",
+               }, nil
+       }
+
        return nil, errors.New("unable to set Variables context")
 }
 
index 359b608c71e7286149c8faf6e4b74f7102b55534..02fb11b1f516e305142668417aef74af445990c5 100644 (file)
@@ -417,7 +417,7 @@ func registerRoutes(m *web.Route) {
                m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksEditPost)
        }
 
-       addSettingVariablesRoutes := func() {
+       addSettingsVariablesRoutes := func() {
                m.Group("/variables", func() {
                        m.Get("", repo_setting.Variables)
                        m.Post("/new", web.Bind(forms.EditVariableForm{}), repo_setting.VariableCreate)
@@ -618,7 +618,7 @@ func registerRoutes(m *web.Route) {
                        m.Get("", user_setting.RedirectToDefaultSetting)
                        addSettingsRunnersRoutes()
                        addSettingsSecretsRoutes()
-                       addSettingVariablesRoutes()
+                       addSettingsVariablesRoutes()
                }, actions.MustEnableActions)
 
                m.Get("/organization", user_setting.Organization)
@@ -763,6 +763,7 @@ func registerRoutes(m *web.Route) {
                m.Group("/actions", func() {
                        m.Get("", admin.RedirectToDefaultSetting)
                        addSettingsRunnersRoutes()
+                       addSettingsVariablesRoutes()
                })
        }, adminReq, ctxDataSet("EnableOAuth2", setting.OAuth2.Enable, "EnablePackages", setting.Packages.Enabled))
        // ***** END: Admin *****
@@ -905,7 +906,7 @@ func registerRoutes(m *web.Route) {
                                        m.Get("", org_setting.RedirectToDefaultSetting)
                                        addSettingsRunnersRoutes()
                                        addSettingsSecretsRoutes()
-                                       addSettingVariablesRoutes()
+                                       addSettingsVariablesRoutes()
                                }, actions.MustEnableActions)
 
                                m.Methods("GET,POST", "/delete", org.SettingsDelete)
@@ -1084,7 +1085,7 @@ func registerRoutes(m *web.Route) {
                                m.Get("", repo_setting.RedirectToDefaultSetting)
                                addSettingsRunnersRoutes()
                                addSettingsSecretsRoutes()
-                               addSettingVariablesRoutes()
+                               addSettingsVariablesRoutes()
                        }, actions.MustEnableActions)
                        // the follow handler must be under "settings", otherwise this incomplete repo can't be accessed
                        m.Group("/migrate", func() {
index 9640e0fd1f4c9a1ec676199ea6e7fb5ad4960645..597863d73b15ee8ec69349049bcd3457b24f09d0 100644 (file)
@@ -3,5 +3,8 @@
        {{if eq .PageType "runners"}}
                {{template "shared/actions/runner_list" .}}
        {{end}}
+       {{if eq .PageType "variables"}}
+               {{template "shared/variables/variable_list" .}}
+       {{end}}
        </div>
 {{template "admin/layout_footer" .}}
index 8ece95239c1ff3a2e4ba0c8ac10a6b705f61ac40..b22db1d1fc8f4d1580e5f7728974260fc7c78370 100644 (file)
                        {{end}}
                {{end}}
                {{if .EnableActions}}
-               <details class="item toggleable-item" {{if .PageIsSharedSettingsRunners}}open{{end}}>
+               <details class="item toggleable-item" {{if or .PageIsSharedSettingsRunners .PageIsSharedSettingsVariables}}open{{end}}>
                        <summary>{{ctx.Locale.Tr "actions.actions"}}</summary>
                        <div class="menu">
                                <a class="{{if .PageIsSharedSettingsRunners}}active {{end}}item" href="{{AppSubUrl}}/admin/actions/runners">
                                        {{ctx.Locale.Tr "actions.runners"}}
                                </a>
+                               <a class="{{if .PageIsSharedSettingsVariables}}active {{end}}item" href="{{AppSubUrl}}/admin/actions/variables">
+                                       {{ctx.Locale.Tr "actions.variables"}}
+                               </a>
                        </div>
                </details>
                {{end}}