From 524349007100375dd2ac98cc38cae65c502c45fa Mon Sep 17 00:00:00 2001 From: "Alex Lau(AvengerMoJo)" Date: Tue, 9 Apr 2024 01:09:17 +0800 Subject: [PATCH 1/7] Enable the global workflow and require_action in org setting Signed-off-by: Alex Lau(AvengerMoJo) --- models/actions/require_action.go | 82 ++++++++++ models/migrations/migrations.go | 3 + models/migrations/v1_23/v295.go | 21 +++ models/repo/repo_unit.go | 17 +++ options/locale/locale_en-US.ini | 23 +++ routers/web/org/setting/require_action.go | 14 ++ routers/web/repo/actions/actions.go | 6 + routers/web/repo/actions/view.go | 35 +++++ routers/web/repo/setting/require_action.go | 80 ++++++++++ routers/web/shared/actions/require_action.go | 74 +++++++++ routers/web/web.go | 12 ++ services/actions/require_action.go | 18 +++ services/forms/user_form.go | 7 + templates/org/settings/actions.tmpl | 4 +- templates/org/settings/navbar.tmpl | 3 + templates/repo/actions/list.tmpl | 10 ++ .../shared/actions/require_action_list.tmpl | 143 ++++++++++++++++++ 17 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 models/actions/require_action.go create mode 100644 models/migrations/v1_23/v295.go create mode 100644 routers/web/org/setting/require_action.go create mode 100644 routers/web/repo/setting/require_action.go create mode 100644 routers/web/shared/actions/require_action.go create mode 100644 services/actions/require_action.go create mode 100644 templates/shared/actions/require_action_list.tmpl diff --git a/models/actions/require_action.go b/models/actions/require_action.go new file mode 100644 index 000000000000..990bd2a6ed01 --- /dev/null +++ b/models/actions/require_action.go @@ -0,0 +1,82 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +// WIP RequireAction + +package actions + +import ( + "context" + + "code.gitea.io/gitea/models/db" + //"code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/builder" +) + +type RequireAction struct { + ID int64 `xorm:"pk autoincr"` + OrgID int64 `xorm:"index"` + RepoName string `xorm:"VARCHAR(255)"` + WorkflowName string `xorm:"VARCHAR(255) UNIQUE(require_action) NOT NULL"` + //Description string `xorm:"LONGTEXT NOT NULL"` + CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + // RepoRange string // glob match which repositories could use this runner +} + +type GlobalWorkflow struct { + RepoName string + Filename string +} + +func init() { + db.RegisterModel(new(RequireAction)) +} + +type FindRequireActionOptions struct { + db.ListOptions + RequireActionID int64 + OrgID int64 + RepoName string +} + +func (opts FindRequireActionOptions) ToConds() builder.Cond { + cond := builder.NewCond() + if opts.OrgID > 0 { + cond = cond.And(builder.Eq{"org_id": opts.OrgID}) + } + if opts.RequireActionID > 0 { + cond = cond.And(builder.Eq{"id": opts.RequireActionID}) + } + if opts.RepoName != "" { + cond = cond.And(builder.Eq{"repo_name": opts.RepoName}) + } + return cond +} + +// LoadAttributes loads the attributes of the require action +func (r *RequireAction) LoadAttributes(ctx context.Context) error { + // place holder for now. + return nil +} + +// if the workflow is removable +func (r *RequireAction) Removable(orgID int64) bool { + // everyone can remove for now + if r.OrgID == orgID { + return true + } + return false +} + + +func AddRequireAction(ctx context.Context, orgID int64, repoName string, workflowName string) (*RequireAction, error) { + ra := &RequireAction{ + OrgID: orgID, + RepoName: repoName, + WorkflowName: workflowName, + } + return ra, db.Insert(ctx, ra) +} diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 387cd96a5347..5462ae960cef 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -576,7 +576,10 @@ var migrations = []Migration{ // Gitea 1.22.0 ends at 294 + // v294 -> v295 NewMigration("Add unique index for project issue table", v1_23.AddUniqueIndexForProjectIssue), + // v295 -> v296 + NewMigration("Add RequireAction Global Workflow", v1_23.AddRequireActionTable), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_23/v295.go b/models/migrations/v1_23/v295.go new file mode 100644 index 000000000000..20656bf6dbe7 --- /dev/null +++ b/models/migrations/v1_23/v295.go @@ -0,0 +1,21 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_23 //nolint + +import ( + "code.gitea.io/gitea/modules/timeutil" + "xorm.io/xorm" +) + +func AddRequireActionTable(x *xorm.Engine) error { + type RequireAction struct { + ID int64 `xorm:"pk autoincr"` + OrgID int64 `xorm:"index"` + RepoName string `xorm:"VARCHAR(255)"` + WorkflowName string `xorm:"VARCHAR(255) UNIQUE(require_action) NOT NULL"` + CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + } + return x.Sync(new(RequireAction)) +} diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index 5a841f4d312e..86286394c383 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -168,10 +168,27 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle { type ActionsConfig struct { DisabledWorkflows []string + EnabledGlobalWorkflows []string } func (cfg *ActionsConfig) EnableWorkflow(file string) { cfg.DisabledWorkflows = util.SliceRemoveAll(cfg.DisabledWorkflows, file) +} + +func (cfg *ActionsConfig) DisableGlobalWorkflow(file string) { + cfg.EnabledGlobalWorkflows = util.SliceRemoveAll(cfg.EnabledGlobalWorkflows, file) +} + +func (cfg *ActionsConfig) IsGlobalWorkflowEnabled(file string) bool { + return slices.Contains(cfg.EnabledGlobalWorkflows, file) +} + +func (cfg *ActionsConfig) EnableGlobalWorkflow(file string) { + cfg.EnabledGlobalWorkflows = append(cfg.EnabledGlobalWorkflows, file) +} + +func (cfg *ActionsConfig) GetGlobalWorkflow() []string { + return cfg.EnabledGlobalWorkflows } func (cfg *ActionsConfig) ToString() string { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 0a3d12d7a40f..25587e259074 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3640,11 +3640,34 @@ runs.no_workflows.documentation = For more information on Gitea Actions, see 0 && ctx.Repo.IsAdmin() { ctx.Data["AllowDisableOrEnableWorkflow"] = true ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflow) + ctx.Data["CurGlobalWorkflowEnable"] = actionsConfig.IsGlobalWorkflowEnabled(workflow) + isGlobal = actionsConfig.IsGlobalWorkflowEnabled(workflow) } // if status or actor query param is not given to frontend href, (href="//actions") @@ -209,6 +212,9 @@ func List(ctx *context.Context) { pager.AddParamString("workflow", workflow) pager.AddParamString("actor", fmt.Sprint(actorID)) pager.AddParamString("status", fmt.Sprint(status)) + if isGlobal { + pager.AddParamString("global", fmt.Sprint(isGlobal)) + } ctx.Data["Page"] = pager ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0 diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 41989589bebc..ff679e4b8fa3 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -714,3 +714,38 @@ func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable bool) { url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) ctx.JSONRedirect(redirectURL) } + +func DisableGlobalWorkflowFile(ctx *context_module.Context) { + disableOrEnableGlobalWorkflowFile(ctx, true) +} + +func EnableGlobalWorkflowFile(ctx *context_module.Context) { + disableOrEnableGlobalWorkflowFile(ctx, false) +} + +func disableOrEnableGlobalWorkflowFile(ctx *context_module.Context, isGlobalEnable bool) { + workflow := ctx.FormString("workflow") + if len(workflow) == 0 { + ctx.ServerError("workflow", nil) + return + } + cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) + cfg := cfgUnit.ActionsConfig() + if isGlobalEnable { + cfg.DisableGlobalWorkflow(workflow) + } else { + cfg.EnableGlobalWorkflow(workflow) + } + if err := repo_model.UpdateRepoUnit(ctx, cfgUnit); err != nil { + ctx.ServerError("UpdateRepoUnit", err) + return + } + if isGlobalEnable { + ctx.Flash.Success(ctx.Tr("actions.workflow.global_disable_success", workflow)) + } else { + ctx.Flash.Success(ctx.Tr("actions.workflow.global_enable_success", workflow)) + } + redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(workflow), + url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) + ctx.JSONRedirect(redirectURL) +} diff --git a/routers/web/repo/setting/require_action.go b/routers/web/repo/setting/require_action.go new file mode 100644 index 000000000000..7ea54d571750 --- /dev/null +++ b/routers/web/repo/setting/require_action.go @@ -0,0 +1,80 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +// WIP RequireAction + +package setting + +import ( + "errors" + "net/http" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/base" + // "code.gitea.io/gitea/modules/log" + + "code.gitea.io/gitea/services/context" + + //"code.gitea.io/gitea/modules/setting" + shared "code.gitea.io/gitea/routers/web/shared/actions" + actions_model "code.gitea.io/gitea/models/actions" +) + +const ( + // let start with org WIP + tplOrgRequireAction base.TplName = "org/settings/actions" +) + +type requireActionsCtx struct { + OrgID int64 + IsOrg bool + RequireActionTemplate base.TplName + RedirectLink string +} + +func getRequireActionCtx(ctx *context.Context) (*requireActionsCtx, error) { + if ctx.Data["PageIsOrgSettings"] == true { + return &requireActionsCtx{ + OrgID: ctx.Org.Organization.ID, + IsOrg: true, + RequireActionTemplate: tplOrgRequireAction, + RedirectLink: ctx.Org.OrgLink + "/settings/actions/require_action", + }, nil + } + return nil, errors.New("unable to set Require Actions context") +} + +// Listing all RequireAction +func RequireAction(ctx *context.Context) { + ctx.Data["ActionsTitle"] = ctx.Tr("actions.requires") + ctx.Data["PageType"] = "require_action" + ctx.Data["PageIsSharedSettingsRequireAction"] = true + + vCtx, err := getRequireActionCtx(ctx) + if err != nil { + ctx.ServerError("getRequireActionCtx", err) + return + } + + page := ctx.FormInt("page") + if page <= 1 { page = 1 } + opts := actions_model.FindRequireActionOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: 10, + }, + } + shared.SetRequireActionContext(ctx, opts) + ctx.Data["Link"] = vCtx.RedirectLink + shared.GlobalEnableWorkflow(ctx, ctx.Org.Organization.ID) + ctx.HTML(http.StatusOK, vCtx.RequireActionTemplate) +} + +func RequireActionCreate(ctx *context.Context) { + vCtx, err := getRequireActionCtx(ctx) + if err != nil { + ctx.ServerError("getRequireActionCtx", err) + return + } + shared.CreateRequireAction(ctx, vCtx.OrgID, vCtx.RedirectLink) +} diff --git a/routers/web/shared/actions/require_action.go b/routers/web/shared/actions/require_action.go new file mode 100644 index 000000000000..fbaab43f3600 --- /dev/null +++ b/routers/web/shared/actions/require_action.go @@ -0,0 +1,74 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +// WIP RequireAction + +package actions + +import ( + + actions_model "code.gitea.io/gitea/models/actions" + org_model "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/log" + //"code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/forms" + actions_service "code.gitea.io/gitea/services/actions" + + "code.gitea.io/gitea/services/context" +) + +// SetRequireActionDeletePost response for deleting a require action workflow +func SetRequireActionContext(ctx *context.Context, opts actions_model.FindRequireActionOptions) { + require_actions, count, err := db.FindAndCount[actions_model.RequireAction](ctx, opts) + if err != nil { + ctx.ServerError("CountRequireActions", err) + return + } + ctx.Data["RequireActions"] = require_actions + ctx.Data["Total"] = count + ctx.Data["OrgID"] = ctx.Org.Organization.ID + ctx.Data["OrgName"] = ctx.Org.Organization.Name + pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) + ctx.Data["Page"] = pager +} + +// get all the available enable global workflow in the org's repo +func GlobalEnableWorkflow(ctx *context.Context, orgID int64){ + var gwfList []actions_model.GlobalWorkflow + orgRepos, err := org_model.GetOrgRepositories(ctx, orgID) + if err != nil { + ctx.ServerError("GlobalEnableWorkflows get org repos: ", err) + return + } + for _, repo := range orgRepos { + repo.LoadUnits(ctx) + actionsConfig := repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() + enabledWorkflows := actionsConfig.GetGlobalWorkflow() + for _, workflow := range enabledWorkflows { + gwf := actions_model.GlobalWorkflow{ + RepoName: repo.Name, + Filename: workflow, + } + gwfList = append(gwfList, gwf) + } + } + ctx.Data["GlobalEnableWorkflows"] = gwfList +} + +func CreateRequireAction(ctx *context.Context, orgID int64, redirectURL string){ + ctx.Data["OrgID"] = ctx.Org.Organization.ID + form := web.GetForm(ctx).(*forms.RequireActionForm) + // log.Error("org %d, repo_name: %s, workflow_name %s", orgID, form.RepoName, form.WorkflowName) + log.Error("org %d, repo_name: %+v", orgID, form) + v, err := actions_service.CreateRequireAction(ctx, orgID, form.RepoName, form.WorkflowName) + if err != nil { + log.Error("CreateRequireAction: %v", err) + ctx.JSONError(ctx.Tr("actions.require_action.creation.failed")) + return + } + ctx.Flash.Success(ctx.Tr("actions.require_action.creation.success", v.WorkflowName)) + ctx.JSONRedirect(redirectURL) +} diff --git a/routers/web/web.go b/routers/web/web.go index 4fff994e4247..5f701eba9cc1 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -458,6 +458,14 @@ func registerRoutes(m *web.Route) { }) } + // WIP RequireAction + addSettingsRequireActionRoutes := func() { + m.Group("/require_action", func() { + m.Get("", repo_setting.RequireAction) + m.Post("/add", web.Bind(forms.RequireActionForm{}), repo_setting.RequireActionCreate) + }) + } + // FIXME: not all routes need go through same middleware. // Especially some AJAX requests, we can reduce middleware number to improve performance. @@ -628,6 +636,7 @@ func registerRoutes(m *web.Route) { m.Group("/actions", func() { m.Get("", user_setting.RedirectToDefaultSetting) + addSettingsRequireActionRoutes() addSettingsRunnersRoutes() addSettingsSecretsRoutes() addSettingsVariablesRoutes() @@ -925,6 +934,7 @@ func registerRoutes(m *web.Route) { m.Group("/actions", func() { m.Get("", org_setting.RedirectToDefaultSetting) + addSettingsRequireActionRoutes() addSettingsRunnersRoutes() addSettingsSecretsRoutes() addSettingsVariablesRoutes() @@ -1358,6 +1368,8 @@ func registerRoutes(m *web.Route) { m.Get("", actions.List) m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) + m.Post("/global_disable", reqRepoAdmin, actions.DisableGlobalWorkflowFile) + m.Post("/global_enable", reqRepoAdmin, actions.EnableGlobalWorkflowFile) m.Group("/runs/{run}", func() { m.Combo(""). diff --git a/services/actions/require_action.go b/services/actions/require_action.go new file mode 100644 index 000000000000..6ba8c84f3d15 --- /dev/null +++ b/services/actions/require_action.go @@ -0,0 +1,18 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "context" + + actions_model "code.gitea.io/gitea/models/actions" +) + +func CreateRequireAction(ctx context.Context, orgID int64, repoName string, workflowName string) (*actions_model.RequireAction, error) { + v, err := actions_model.AddRequireAction(ctx, orgID, repoName, workflowName) + if err != nil { + return nil, err + } + return v, nil +} diff --git a/services/forms/user_form.go b/services/forms/user_form.go index e2e6c208f7da..b81661222d0e 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -359,6 +359,13 @@ func (f *EditVariableForm) Validate(req *http.Request, errs binding.Errors) bind return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } +//WIP RequireAction create form + +type RequireActionForm struct { + RepoName string `binding:"Required;MaxSize(255)"` + WorkflowName string `binding:"Required;MaxSize(255)"` +} + // NewAccessTokenForm form for creating access token type NewAccessTokenForm struct { Name string `binding:"Required;MaxSize(255)" locale:"settings.token_name"` diff --git a/templates/org/settings/actions.tmpl b/templates/org/settings/actions.tmpl index abb9c98435f4..d89a4c860a91 100644 --- a/templates/org/settings/actions.tmpl +++ b/templates/org/settings/actions.tmpl @@ -1,6 +1,8 @@ {{template "org/settings/layout_head" (dict "ctxData" . "pageClass" "organization settings actions")}}
- {{if eq .PageType "runners"}} + {{if eq .PageType "require_action"}} + {{template "shared/actions/require_action_list" .}} + {{else if eq .PageType "runners"}} {{template "shared/actions/runner_list" .}} {{else if eq .PageType "secrets"}} {{template "shared/secrets/add_list" .}} diff --git a/templates/org/settings/navbar.tmpl b/templates/org/settings/navbar.tmpl index ce792f667c4f..7ee058dbeeb0 100644 --- a/templates/org/settings/navbar.tmpl +++ b/templates/org/settings/navbar.tmpl @@ -29,6 +29,9 @@
{{ctx.Locale.Tr "actions.actions"}} @@ -65,6 +68,10 @@
+ + {{if .AllowDisableOrEnableWorkflow}} {{end}} diff --git a/templates/shared/actions/require_action_list.tmpl b/templates/shared/actions/require_action_list.tmpl new file mode 100644 index 000000000000..8f670686340c --- /dev/null +++ b/templates/shared/actions/require_action_list.tmpl @@ -0,0 +1,143 @@ +
+

+ {{ctx.Locale.Tr "actions.require_action.require_action_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}}) +
+
+ +
+ +
+

+
+
+ +
+ {{template "shared/search/combo" dict "Value" .Keyword}} + +
+
+
+
+ + + + + + + + + + + + {{if .RequireActions}} + {{range .RequireActions}} + + + + + + + + {{end}} + {{else}} + + + + {{end}} + +
+ {{ctx.Locale.Tr "actions.require_action.id"}} + + {{ctx.Locale.Tr "actions.require_action.workflow"}} + {{ctx.Locale.Tr "actions.require_action.repo"}}{{ctx.Locale.Tr "actions.require_action.link"}}{{ctx.Locale.Tr "actions.require_action.remove"}}
{{.ID}}

{{.WorkflowName}}

{{.RepoName}}Workflow Link + {{if .Removable $.OrgID }} + {{svg "octicon-x-circle-fill"}} + {{end}} +
{{ctx.Locale.Tr "actions.require_action.none"}}
+
+ {{template "base/paginate" .}} +
+ + + +{{/* Add RequireAction dialog */}} + + From 1fc998984fef5301d65fc143dba8dd6de6ea241f Mon Sep 17 00:00:00 2001 From: "Alex Lau(AvengerMoJo)" Date: Wed, 10 Apr 2024 17:07:46 +0800 Subject: [PATCH 2/7] Fix all the format of the commit Signed-off-by: Alex Lau(AvengerMoJo) --- models/actions/require_action.go | 88 +++++++------- models/migrations/v1_23/v295.go | 16 +-- models/repo/repo_unit.go | 14 +-- routers/web/org/setting/require_action.go | 4 +- routers/web/repo/actions/actions.go | 12 +- routers/web/repo/actions/view.go | 52 ++++---- routers/web/repo/setting/require_action.go | 102 ++++++++-------- routers/web/shared/actions/require_action.go | 111 +++++++++--------- routers/web/web.go | 18 +-- services/actions/require_action.go | 16 +-- services/forms/user_form.go | 3 +- .../shared/actions/require_action_list.tmpl | 23 ++-- 12 files changed, 227 insertions(+), 232 deletions(-) diff --git a/models/actions/require_action.go b/models/actions/require_action.go index 990bd2a6ed01..b7f55f074148 100644 --- a/models/actions/require_action.go +++ b/models/actions/require_action.go @@ -6,77 +6,73 @@ package actions import ( - "context" + "context" - "code.gitea.io/gitea/models/db" - //"code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/models/db" + //"code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/timeutil" - "xorm.io/builder" + "xorm.io/builder" ) type RequireAction struct { - ID int64 `xorm:"pk autoincr"` - OrgID int64 `xorm:"index"` - RepoName string `xorm:"VARCHAR(255)"` - WorkflowName string `xorm:"VARCHAR(255) UNIQUE(require_action) NOT NULL"` - //Description string `xorm:"LONGTEXT NOT NULL"` - CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` - UpdatedUnix timeutil.TimeStamp `xorm:"updated"` - // RepoRange string // glob match which repositories could use this runner + ID int64 `xorm:"pk autoincr"` + OrgID int64 `xorm:"index"` + RepoName string `xorm:"VARCHAR(255)"` + WorkflowName string `xorm:"VARCHAR(255) UNIQUE(require_action) NOT NULL"` + // Description string `xorm:"LONGTEXT NOT NULL"` + CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + // RepoRange string // glob match which repositories could use this runner } type GlobalWorkflow struct { - RepoName string - Filename string + RepoName string + Filename string } func init() { - db.RegisterModel(new(RequireAction)) + db.RegisterModel(new(RequireAction)) } type FindRequireActionOptions struct { - db.ListOptions - RequireActionID int64 - OrgID int64 - RepoName string + db.ListOptions + RequireActionID int64 + OrgID int64 + RepoName string } func (opts FindRequireActionOptions) ToConds() builder.Cond { - cond := builder.NewCond() - if opts.OrgID > 0 { - cond = cond.And(builder.Eq{"org_id": opts.OrgID}) - } - if opts.RequireActionID > 0 { - cond = cond.And(builder.Eq{"id": opts.RequireActionID}) - } - if opts.RepoName != "" { - cond = cond.And(builder.Eq{"repo_name": opts.RepoName}) - } - return cond + cond := builder.NewCond() + if opts.OrgID > 0 { + cond = cond.And(builder.Eq{"org_id": opts.OrgID}) + } + if opts.RequireActionID > 0 { + cond = cond.And(builder.Eq{"id": opts.RequireActionID}) + } + if opts.RepoName != "" { + cond = cond.And(builder.Eq{"repo_name": opts.RepoName}) + } + return cond } // LoadAttributes loads the attributes of the require action func (r *RequireAction) LoadAttributes(ctx context.Context) error { - // place holder for now. - return nil + // place holder for now. + return nil } // if the workflow is removable func (r *RequireAction) Removable(orgID int64) bool { - // everyone can remove for now - if r.OrgID == orgID { - return true - } - return false + // everyone can remove for now + return r.OrgID == orgID } - -func AddRequireAction(ctx context.Context, orgID int64, repoName string, workflowName string) (*RequireAction, error) { - ra := &RequireAction{ - OrgID: orgID, - RepoName: repoName, - WorkflowName: workflowName, - } - return ra, db.Insert(ctx, ra) +func AddRequireAction(ctx context.Context, orgID int64, repoName, workflowName string) (*RequireAction, error) { + ra := &RequireAction{ + OrgID: orgID, + RepoName: repoName, + WorkflowName: workflowName, + } + return ra, db.Insert(ctx, ra) } diff --git a/models/migrations/v1_23/v295.go b/models/migrations/v1_23/v295.go index 20656bf6dbe7..3e835f288679 100644 --- a/models/migrations/v1_23/v295.go +++ b/models/migrations/v1_23/v295.go @@ -9,13 +9,13 @@ import ( ) func AddRequireActionTable(x *xorm.Engine) error { - type RequireAction struct { - ID int64 `xorm:"pk autoincr"` - OrgID int64 `xorm:"index"` - RepoName string `xorm:"VARCHAR(255)"` - WorkflowName string `xorm:"VARCHAR(255) UNIQUE(require_action) NOT NULL"` - CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` - UpdatedUnix timeutil.TimeStamp `xorm:"updated"` - } + type RequireAction struct { + ID int64 `xorm:"pk autoincr"` + OrgID int64 `xorm:"index"` + RepoName string `xorm:"VARCHAR(255)"` + WorkflowName string `xorm:"VARCHAR(255) UNIQUE(require_action) NOT NULL"` + CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + } return x.Sync(new(RequireAction)) } diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index 86286394c383..416bf6f89b02 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -167,28 +167,28 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle { } type ActionsConfig struct { - DisabledWorkflows []string - EnabledGlobalWorkflows []string + DisabledWorkflows []string + EnabledGlobalWorkflows []string } func (cfg *ActionsConfig) EnableWorkflow(file string) { cfg.DisabledWorkflows = util.SliceRemoveAll(cfg.DisabledWorkflows, file) -} +} func (cfg *ActionsConfig) DisableGlobalWorkflow(file string) { - cfg.EnabledGlobalWorkflows = util.SliceRemoveAll(cfg.EnabledGlobalWorkflows, file) + cfg.EnabledGlobalWorkflows = util.SliceRemoveAll(cfg.EnabledGlobalWorkflows, file) } func (cfg *ActionsConfig) IsGlobalWorkflowEnabled(file string) bool { - return slices.Contains(cfg.EnabledGlobalWorkflows, file) + return slices.Contains(cfg.EnabledGlobalWorkflows, file) } func (cfg *ActionsConfig) EnableGlobalWorkflow(file string) { - cfg.EnabledGlobalWorkflows = append(cfg.EnabledGlobalWorkflows, file) + cfg.EnabledGlobalWorkflows = append(cfg.EnabledGlobalWorkflows, file) } func (cfg *ActionsConfig) GetGlobalWorkflow() []string { - return cfg.EnabledGlobalWorkflows + return cfg.EnabledGlobalWorkflows } func (cfg *ActionsConfig) ToString() string { diff --git a/routers/web/org/setting/require_action.go b/routers/web/org/setting/require_action.go index 37e2daa7623d..53549932743c 100644 --- a/routers/web/org/setting/require_action.go +++ b/routers/web/org/setting/require_action.go @@ -6,9 +6,9 @@ package setting import ( - "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" ) func RedirectToRepoSetting(ctx *context.Context) { - ctx.Redirect(ctx.Org.OrgLink + "/settings/actions/require_action") + ctx.Redirect(ctx.Org.OrgLink + "/settings/actions/require_action") } diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index 698c6c9cb2e8..c792edff643b 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -145,7 +145,7 @@ func List(ctx *context.Context) { workflow := ctx.FormString("workflow") actorID := ctx.FormInt64("actor") status := ctx.FormInt("status") - isGlobal := false + isGlobal := false ctx.Data["CurWorkflow"] = workflow actionsConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() @@ -154,8 +154,8 @@ func List(ctx *context.Context) { if len(workflow) > 0 && ctx.Repo.IsAdmin() { ctx.Data["AllowDisableOrEnableWorkflow"] = true ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflow) - ctx.Data["CurGlobalWorkflowEnable"] = actionsConfig.IsGlobalWorkflowEnabled(workflow) - isGlobal = actionsConfig.IsGlobalWorkflowEnabled(workflow) + ctx.Data["CurGlobalWorkflowEnable"] = actionsConfig.IsGlobalWorkflowEnabled(workflow) + isGlobal = actionsConfig.IsGlobalWorkflowEnabled(workflow) } // if status or actor query param is not given to frontend href, (href="//actions") @@ -212,9 +212,9 @@ func List(ctx *context.Context) { pager.AddParamString("workflow", workflow) pager.AddParamString("actor", fmt.Sprint(actorID)) pager.AddParamString("status", fmt.Sprint(status)) - if isGlobal { - pager.AddParamString("global", fmt.Sprint(isGlobal)) - } + if isGlobal { + pager.AddParamString("global", fmt.Sprint(isGlobal)) + } ctx.Data["Page"] = pager ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0 diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index ff679e4b8fa3..59054fc986f3 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -716,36 +716,36 @@ func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable bool) { } func DisableGlobalWorkflowFile(ctx *context_module.Context) { - disableOrEnableGlobalWorkflowFile(ctx, true) + disableOrEnableGlobalWorkflowFile(ctx, true) } func EnableGlobalWorkflowFile(ctx *context_module.Context) { - disableOrEnableGlobalWorkflowFile(ctx, false) + disableOrEnableGlobalWorkflowFile(ctx, false) } func disableOrEnableGlobalWorkflowFile(ctx *context_module.Context, isGlobalEnable bool) { - workflow := ctx.FormString("workflow") - if len(workflow) == 0 { - ctx.ServerError("workflow", nil) - return - } - cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) - cfg := cfgUnit.ActionsConfig() - if isGlobalEnable { - cfg.DisableGlobalWorkflow(workflow) - } else { - cfg.EnableGlobalWorkflow(workflow) - } - if err := repo_model.UpdateRepoUnit(ctx, cfgUnit); err != nil { - ctx.ServerError("UpdateRepoUnit", err) - return - } - if isGlobalEnable { - ctx.Flash.Success(ctx.Tr("actions.workflow.global_disable_success", workflow)) - } else { - ctx.Flash.Success(ctx.Tr("actions.workflow.global_enable_success", workflow)) - } - redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(workflow), - url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) - ctx.JSONRedirect(redirectURL) + workflow := ctx.FormString("workflow") + if len(workflow) == 0 { + ctx.ServerError("workflow", nil) + return + } + cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) + cfg := cfgUnit.ActionsConfig() + if isGlobalEnable { + cfg.DisableGlobalWorkflow(workflow) + } else { + cfg.EnableGlobalWorkflow(workflow) + } + if err := repo_model.UpdateRepoUnit(ctx, cfgUnit); err != nil { + ctx.ServerError("UpdateRepoUnit", err) + return + } + if isGlobalEnable { + ctx.Flash.Success(ctx.Tr("actions.workflow.global_disable_success", workflow)) + } else { + ctx.Flash.Success(ctx.Tr("actions.workflow.global_enable_success", workflow)) + } + redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(workflow), + url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) + ctx.JSONRedirect(redirectURL) } diff --git a/routers/web/repo/setting/require_action.go b/routers/web/repo/setting/require_action.go index 7ea54d571750..cad3fe151267 100644 --- a/routers/web/repo/setting/require_action.go +++ b/routers/web/repo/setting/require_action.go @@ -6,75 +6,77 @@ package setting import ( - "errors" - "net/http" + "errors" + "net/http" - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/base" - // "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/base" + // "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" - //"code.gitea.io/gitea/modules/setting" - shared "code.gitea.io/gitea/routers/web/shared/actions" - actions_model "code.gitea.io/gitea/models/actions" + //"code.gitea.io/gitea/modules/setting" + actions_model "code.gitea.io/gitea/models/actions" + shared "code.gitea.io/gitea/routers/web/shared/actions" ) const ( - // let start with org WIP - tplOrgRequireAction base.TplName = "org/settings/actions" + // let start with org WIP + tplOrgRequireAction base.TplName = "org/settings/actions" ) type requireActionsCtx struct { - OrgID int64 - IsOrg bool - RequireActionTemplate base.TplName - RedirectLink string + OrgID int64 + IsOrg bool + RequireActionTemplate base.TplName + RedirectLink string } func getRequireActionCtx(ctx *context.Context) (*requireActionsCtx, error) { - if ctx.Data["PageIsOrgSettings"] == true { - return &requireActionsCtx{ - OrgID: ctx.Org.Organization.ID, - IsOrg: true, - RequireActionTemplate: tplOrgRequireAction, - RedirectLink: ctx.Org.OrgLink + "/settings/actions/require_action", - }, nil - } - return nil, errors.New("unable to set Require Actions context") + if ctx.Data["PageIsOrgSettings"] == true { + return &requireActionsCtx{ + OrgID: ctx.Org.Organization.ID, + IsOrg: true, + RequireActionTemplate: tplOrgRequireAction, + RedirectLink: ctx.Org.OrgLink + "/settings/actions/require_action", + }, nil + } + return nil, errors.New("unable to set Require Actions context") } // Listing all RequireAction func RequireAction(ctx *context.Context) { - ctx.Data["ActionsTitle"] = ctx.Tr("actions.requires") - ctx.Data["PageType"] = "require_action" - ctx.Data["PageIsSharedSettingsRequireAction"] = true + ctx.Data["ActionsTitle"] = ctx.Tr("actions.requires") + ctx.Data["PageType"] = "require_action" + ctx.Data["PageIsSharedSettingsRequireAction"] = true - vCtx, err := getRequireActionCtx(ctx) - if err != nil { - ctx.ServerError("getRequireActionCtx", err) - return - } + vCtx, err := getRequireActionCtx(ctx) + if err != nil { + ctx.ServerError("getRequireActionCtx", err) + return + } - page := ctx.FormInt("page") - if page <= 1 { page = 1 } - opts := actions_model.FindRequireActionOptions{ - ListOptions: db.ListOptions{ - Page: page, - PageSize: 10, - }, - } - shared.SetRequireActionContext(ctx, opts) - ctx.Data["Link"] = vCtx.RedirectLink - shared.GlobalEnableWorkflow(ctx, ctx.Org.Organization.ID) - ctx.HTML(http.StatusOK, vCtx.RequireActionTemplate) + page := ctx.FormInt("page") + if page <= 1 { + page = 1 + } + opts := actions_model.FindRequireActionOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: 10, + }, + } + shared.SetRequireActionContext(ctx, opts) + ctx.Data["Link"] = vCtx.RedirectLink + shared.GlobalEnableWorkflow(ctx, ctx.Org.Organization.ID) + ctx.HTML(http.StatusOK, vCtx.RequireActionTemplate) } func RequireActionCreate(ctx *context.Context) { - vCtx, err := getRequireActionCtx(ctx) - if err != nil { - ctx.ServerError("getRequireActionCtx", err) - return - } - shared.CreateRequireAction(ctx, vCtx.OrgID, vCtx.RedirectLink) + vCtx, err := getRequireActionCtx(ctx) + if err != nil { + ctx.ServerError("getRequireActionCtx", err) + return + } + shared.CreateRequireAction(ctx, vCtx.OrgID, vCtx.RedirectLink) } diff --git a/routers/web/shared/actions/require_action.go b/routers/web/shared/actions/require_action.go index fbaab43f3600..cdeaf1b83c0a 100644 --- a/routers/web/shared/actions/require_action.go +++ b/routers/web/shared/actions/require_action.go @@ -6,69 +6,70 @@ package actions import ( + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" + org_model "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/web" + actions_service "code.gitea.io/gitea/services/actions" + "code.gitea.io/gitea/services/forms" - actions_model "code.gitea.io/gitea/models/actions" - org_model "code.gitea.io/gitea/models/organization" - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/log" - //"code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/services/forms" - actions_service "code.gitea.io/gitea/services/actions" - - "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" ) // SetRequireActionDeletePost response for deleting a require action workflow func SetRequireActionContext(ctx *context.Context, opts actions_model.FindRequireActionOptions) { - require_actions, count, err := db.FindAndCount[actions_model.RequireAction](ctx, opts) - if err != nil { - ctx.ServerError("CountRequireActions", err) - return - } - ctx.Data["RequireActions"] = require_actions - ctx.Data["Total"] = count - ctx.Data["OrgID"] = ctx.Org.Organization.ID - ctx.Data["OrgName"] = ctx.Org.Organization.Name - pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) - ctx.Data["Page"] = pager + requireActions, count, err := db.FindAndCount[actions_model.RequireAction](ctx, opts) + if err != nil { + ctx.ServerError("CountRequireActions", err) + return + } + ctx.Data["RequireActions"] = requireActions + ctx.Data["Total"] = count + ctx.Data["OrgID"] = ctx.Org.Organization.ID + ctx.Data["OrgName"] = ctx.Org.Organization.Name + pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) + ctx.Data["Page"] = pager } // get all the available enable global workflow in the org's repo -func GlobalEnableWorkflow(ctx *context.Context, orgID int64){ - var gwfList []actions_model.GlobalWorkflow - orgRepos, err := org_model.GetOrgRepositories(ctx, orgID) - if err != nil { - ctx.ServerError("GlobalEnableWorkflows get org repos: ", err) - return - } - for _, repo := range orgRepos { - repo.LoadUnits(ctx) - actionsConfig := repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() - enabledWorkflows := actionsConfig.GetGlobalWorkflow() - for _, workflow := range enabledWorkflows { - gwf := actions_model.GlobalWorkflow{ - RepoName: repo.Name, - Filename: workflow, - } - gwfList = append(gwfList, gwf) - } - } - ctx.Data["GlobalEnableWorkflows"] = gwfList +func GlobalEnableWorkflow(ctx *context.Context, orgID int64) { + var gwfList []actions_model.GlobalWorkflow + orgRepos, err := org_model.GetOrgRepositories(ctx, orgID) + if err != nil { + ctx.ServerError("GlobalEnableWorkflows get org repos: ", err) + return + } + for _, repo := range orgRepos { + err := repo.LoadUnits(ctx) + if err != nil { + ctx.ServerError("GlobalEnableWorkflows LoadUnits : ", err) + } + actionsConfig := repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() + enabledWorkflows := actionsConfig.GetGlobalWorkflow() + for _, workflow := range enabledWorkflows { + gwf := actions_model.GlobalWorkflow{ + RepoName: repo.Name, + Filename: workflow, + } + gwfList = append(gwfList, gwf) + } + } + ctx.Data["GlobalEnableWorkflows"] = gwfList } -func CreateRequireAction(ctx *context.Context, orgID int64, redirectURL string){ - ctx.Data["OrgID"] = ctx.Org.Organization.ID - form := web.GetForm(ctx).(*forms.RequireActionForm) - // log.Error("org %d, repo_name: %s, workflow_name %s", orgID, form.RepoName, form.WorkflowName) - log.Error("org %d, repo_name: %+v", orgID, form) - v, err := actions_service.CreateRequireAction(ctx, orgID, form.RepoName, form.WorkflowName) - if err != nil { - log.Error("CreateRequireAction: %v", err) - ctx.JSONError(ctx.Tr("actions.require_action.creation.failed")) - return - } - ctx.Flash.Success(ctx.Tr("actions.require_action.creation.success", v.WorkflowName)) - ctx.JSONRedirect(redirectURL) +func CreateRequireAction(ctx *context.Context, orgID int64, redirectURL string) { + ctx.Data["OrgID"] = ctx.Org.Organization.ID + form := web.GetForm(ctx).(*forms.RequireActionForm) + // log.Error("org %d, repo_name: %s, workflow_name %s", orgID, form.RepoName, form.WorkflowName) + log.Error("org %d, repo_name: %+v", orgID, form) + v, err := actions_service.CreateRequireAction(ctx, orgID, form.RepoName, form.WorkflowName) + if err != nil { + log.Error("CreateRequireAction: %v", err) + ctx.JSONError(ctx.Tr("actions.require_action.creation.failed")) + return + } + ctx.Flash.Success(ctx.Tr("actions.require_action.creation.success", v.WorkflowName)) + ctx.JSONRedirect(redirectURL) } diff --git a/routers/web/web.go b/routers/web/web.go index 5f701eba9cc1..57f02a1a1819 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -458,13 +458,13 @@ func registerRoutes(m *web.Route) { }) } - // WIP RequireAction - addSettingsRequireActionRoutes := func() { - m.Group("/require_action", func() { - m.Get("", repo_setting.RequireAction) - m.Post("/add", web.Bind(forms.RequireActionForm{}), repo_setting.RequireActionCreate) - }) - } + // WIP RequireAction + addSettingsRequireActionRoutes := func() { + m.Group("/require_action", func() { + m.Get("", repo_setting.RequireAction) + m.Post("/add", web.Bind(forms.RequireActionForm{}), repo_setting.RequireActionCreate) + }) + } // FIXME: not all routes need go through same middleware. // Especially some AJAX requests, we can reduce middleware number to improve performance. @@ -1368,8 +1368,8 @@ func registerRoutes(m *web.Route) { m.Get("", actions.List) m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) - m.Post("/global_disable", reqRepoAdmin, actions.DisableGlobalWorkflowFile) - m.Post("/global_enable", reqRepoAdmin, actions.EnableGlobalWorkflowFile) + m.Post("/global_disable", reqRepoAdmin, actions.DisableGlobalWorkflowFile) + m.Post("/global_enable", reqRepoAdmin, actions.EnableGlobalWorkflowFile) m.Group("/runs/{run}", func() { m.Combo(""). diff --git a/services/actions/require_action.go b/services/actions/require_action.go index 6ba8c84f3d15..f70b79bfb092 100644 --- a/services/actions/require_action.go +++ b/services/actions/require_action.go @@ -4,15 +4,15 @@ package actions import ( - "context" + "context" - actions_model "code.gitea.io/gitea/models/actions" + actions_model "code.gitea.io/gitea/models/actions" ) -func CreateRequireAction(ctx context.Context, orgID int64, repoName string, workflowName string) (*actions_model.RequireAction, error) { - v, err := actions_model.AddRequireAction(ctx, orgID, repoName, workflowName) - if err != nil { - return nil, err - } - return v, nil +func CreateRequireAction(ctx context.Context, orgID int64, repoName, workflowName string) (*actions_model.RequireAction, error) { + v, err := actions_model.AddRequireAction(ctx, orgID, repoName, workflowName) + if err != nil { + return nil, err + } + return v, nil } diff --git a/services/forms/user_form.go b/services/forms/user_form.go index b81661222d0e..0befb4306853 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -359,8 +359,7 @@ func (f *EditVariableForm) Validate(req *http.Request, errs binding.Errors) bind return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -//WIP RequireAction create form - +// WIP RequireAction create form type RequireActionForm struct { RepoName string `binding:"Required;MaxSize(255)"` WorkflowName string `binding:"Required;MaxSize(255)"` diff --git a/templates/shared/actions/require_action_list.tmpl b/templates/shared/actions/require_action_list.tmpl index 8f670686340c..1c18d1760984 100644 --- a/templates/shared/actions/require_action_list.tmpl +++ b/templates/shared/actions/require_action_list.tmpl @@ -1,18 +1,16 @@

- {{ctx.Locale.Tr "actions.require_action.require_action_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}}) -
-
- -
- +
+

@@ -61,7 +59,7 @@
- {{template "base/paginate" .}} + {{template "base/paginate"}} @@ -69,7 +67,7 @@ {{/* Add RequireAction dialog */}} - - + + {{if .AllowDisableOrEnableWorkflow}} {{end}} diff --git a/templates/shared/actions/require_action_list.tmpl b/templates/shared/actions/require_action_list.tmpl index e845d7fd3929..99642eb62d72 100644 --- a/templates/shared/actions/require_action_list.tmpl +++ b/templates/shared/actions/require_action_list.tmpl @@ -1,145 +1,145 @@
-

- {{ctx.Locale.Tr "actions.require_action.require_action_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}}) -
-
- -
-
-

-
-
- - {{template "shared/search/combo" dict "Value" .Keyword}} - -
-
-
- - - - - - - - - - - - {{if .RequireActions}} - {{range .RequireActions}} - - - - - - - - {{end}} - {{else}} - - - - {{end}} - -
- {{ctx.Locale.Tr "actions.require_action.id"}} - - {{ctx.Locale.Tr "actions.require_action.workflow"}} - {{ctx.Locale.Tr "actions.require_action.repo"}}{{ctx.Locale.Tr "actions.require_action.link"}}{{ctx.Locale.Tr "actions.require_action.remove"}}
{{.ID}}

{{.WorkflowName}}

{{.RepoName}}Workflow Link - {{if .Removable $.OrgID}} - - - {{end}} -
{{ctx.Locale.Tr "actions.require_action.none"}}
-
- {{template "base/paginate"}} +

+ {{ctx.Locale.Tr "actions.require_action.require_action_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}}) +
+
+ +
+
+

+
+
+ + {{template "shared/search/combo" dict "Value" .Keyword}} + +
+
+
+ + + + + + + + + + + + {{if .RequireActions}} + {{range .RequireActions}} + + + + + + + + {{end}} + {{else}} + + + + {{end}} + +
+ {{ctx.Locale.Tr "actions.require_action.id"}} + + {{ctx.Locale.Tr "actions.require_action.workflow"}} + {{ctx.Locale.Tr "actions.require_action.repo"}}{{ctx.Locale.Tr "actions.require_action.link"}}{{ctx.Locale.Tr "actions.require_action.remove"}}
{{.ID}}

{{.WorkflowName}}

{{.RepoName}}Workflow Link + {{if .Removable $.OrgID}} + + + {{end}} +
{{ctx.Locale.Tr "actions.require_action.none"}}
+
+ {{template "base/paginate"}}
{{/* Add RequireAction dialog */}} From c4b923886cfc852bd621732d12d014a689ad999e Mon Sep 17 00:00:00 2001 From: "Alex Lau(AvengerMoJo)" Date: Mon, 22 Apr 2024 13:40:37 +0800 Subject: [PATCH 6/7] moving the js to a seperated file in web_src/js/features/ Signed-off-by: Alex Lau(AvengerMoJo) --- .../shared/actions/require_action_list.tmpl | 2 ++ web_src/js/features/require-actions-select.js | 19 +++++++++++++++++++ web_src/js/index.js | 2 ++ 3 files changed, 23 insertions(+) create mode 100644 web_src/js/features/require-actions-select.js diff --git a/templates/shared/actions/require_action_list.tmpl b/templates/shared/actions/require_action_list.tmpl index 99642eb62d72..e04e551dfcd1 100644 --- a/templates/shared/actions/require_action_list.tmpl +++ b/templates/shared/actions/require_action_list.tmpl @@ -124,6 +124,7 @@ {{template "base/modal_actions_confirm" (dict "ModalButtonTypes" "confirm")}} + diff --git a/web_src/js/features/require-actions-select.js b/web_src/js/features/require-actions-select.js new file mode 100644 index 000000000000..e18e8d42c423 --- /dev/null +++ b/web_src/js/features/require-actions-select.js @@ -0,0 +1,19 @@ +export function initRequireActionsSelect() { + const raselect = document.getElementById('add-require-actions-modal'); + if (!raselect) return; + const checkboxes = document.querySelectorAll('.ui.radio.checkbox'); + checkboxes.forEach(function(checkbox) { + checkbox.addEventListener('change', function() { + var hiddenInput = this.nextElementSibling; + var isChecked = this.querySelector('input[type="radio"]').checked; + hiddenInput.disabled = !isChecked; + // Disable other hidden inputs + checkboxes.forEach(function(otherCheckbox) { + var otherHiddenInput = otherCheckbox.nextElementSibling; + if (otherCheckbox !== checkbox) { + otherHiddenInput.disabled = isChecked; + } + }); + }); + }); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index fc2f6b9b0b91..05bfb46258ad 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -54,6 +54,7 @@ import {initRepoCodeView} from './features/repo-code.js'; import {initSshKeyFormParser} from './features/sshkey-helper.js'; import {initUserSettings} from './features/user-settings.js'; import {initRepoArchiveLinks} from './features/repo-common.js'; +import {initRequireActionsSelect} from './features/require-actions-select.js'; import {initRepoMigrationStatusChecker} from './features/repo-migrate.js'; import { initRepoSettingGitHook, @@ -143,6 +144,7 @@ onDomReady(() => { initRepoActivityTopAuthorsChart(); initRepoArchiveLinks(); + initRequireActionsSelect(); initRepoBranchButton(); initRepoCodeView(); initRepoCommentForm(); From d68a8214556b761e8f144b2c106d05cb4f0ba3b6 Mon Sep 17 00:00:00 2001 From: "Alex Lau(AvengerMoJo)" Date: Mon, 29 Apr 2024 15:03:35 +0800 Subject: [PATCH 7/7] Fix the format Signed-off-by: Alex Lau(AvengerMoJo) --- routers/web/web.go | 12 ++++++------ web_src/js/features/require-actions-select.js | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/routers/web/web.go b/routers/web/web.go index 0150be718b7b..0cf0ac4213df 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1382,12 +1382,12 @@ func registerRoutes(m *web.Route) { }, ignSignIn, context.RepoAssignment, reqRepoProjectsReader, repo.MustEnableRepoProjects) // end "/{username}/{reponame}/projects" - m.Group("/actions", func() { - m.Get("", actions.List) - m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) - m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) - m.Post("/global_disable", reqRepoAdmin, actions.DisableGlobalWorkflowFile) - m.Post("/global_enable", reqRepoAdmin, actions.EnableGlobalWorkflowFile) + m.Group("/actions", func() { + m.Get("", actions.List) + m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) + m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) + m.Post("/global_disable", reqRepoAdmin, actions.DisableGlobalWorkflowFile) + m.Post("/global_enable", reqRepoAdmin, actions.EnableGlobalWorkflowFile) m.Group("/runs/{run}", func() { m.Combo(""). diff --git a/web_src/js/features/require-actions-select.js b/web_src/js/features/require-actions-select.js index e18e8d42c423..fa8c7f967b81 100644 --- a/web_src/js/features/require-actions-select.js +++ b/web_src/js/features/require-actions-select.js @@ -2,18 +2,18 @@ export function initRequireActionsSelect() { const raselect = document.getElementById('add-require-actions-modal'); if (!raselect) return; const checkboxes = document.querySelectorAll('.ui.radio.checkbox'); - checkboxes.forEach(function(checkbox) { - checkbox.addEventListener('change', function() { - var hiddenInput = this.nextElementSibling; - var isChecked = this.querySelector('input[type="radio"]').checked; + for (const box of checkboxes) { + box.addEventListener('change', function() { + const hiddenInput = this.nextElementSibling; + const isChecked = this.querySelector('input[type="radio"]').checked; hiddenInput.disabled = !isChecked; // Disable other hidden inputs - checkboxes.forEach(function(otherCheckbox) { - var otherHiddenInput = otherCheckbox.nextElementSibling; - if (otherCheckbox !== checkbox) { + for (const otherbox of checkboxes) { + const otherHiddenInput = otherbox.nextElementSibling; + if (otherbox !== box) { otherHiddenInput.disabled = isChecked; } - }); + } }); - }); + } }