Added instance-level variables (#28115)
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)
This commit is contained in:
parent
0407a402bb
commit
d0f24ff4ca
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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" .}}
|
||||
|
|
|
@ -60,12 +60,15 @@
|
|||
{{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}}
|
||||
|
|
Loading…
Reference in New Issue