loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add disable workflow feature (#26413)

As title, that's simmilar with github.


![image](https://github.com/go-gitea/gitea/assets/25342410/9e8b2444-63e0-4e87-80da-730c1e4d09d6)



![image](https://github.com/go-gitea/gitea/assets/25342410/6c3a3345-3ba7-48c9-9acd-3e621632491b)

---------

Signed-off-by: a1012112796 <1012112796@qq.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Jason Song <i@wolfogre.com>

authored by

a1012112796
silverwind
Jason Song
and committed by
GitHub
19872063 253737eb

+180 -2
+6
models/repo/repo.go
··· 391 391 Type: tp, 392 392 Config: new(IssuesConfig), 393 393 } 394 + } else if tp == unit.TypeActions { 395 + return &RepoUnit{ 396 + Type: tp, 397 + Config: new(ActionsConfig), 398 + } 394 399 } 400 + 395 401 return &RepoUnit{ 396 402 Type: tp, 397 403 Config: new(UnitConfig),
+45 -1
models/repo/repo_unit.go
··· 6 6 import ( 7 7 "context" 8 8 "fmt" 9 + "strings" 9 10 10 11 "code.gitea.io/gitea/models/db" 11 12 "code.gitea.io/gitea/models/unit" ··· 162 163 return MergeStyleMerge 163 164 } 164 165 166 + type ActionsConfig struct { 167 + DisabledWorkflows []string 168 + } 169 + 170 + func (cfg *ActionsConfig) EnableWorkflow(file string) { 171 + cfg.DisabledWorkflows = util.SliceRemoveAll(cfg.DisabledWorkflows, file) 172 + } 173 + 174 + func (cfg *ActionsConfig) ToString() string { 175 + return strings.Join(cfg.DisabledWorkflows, ",") 176 + } 177 + 178 + func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool { 179 + return util.SliceContains(cfg.DisabledWorkflows, file) 180 + } 181 + 182 + func (cfg *ActionsConfig) DisableWorkflow(file string) { 183 + for _, workflow := range cfg.DisabledWorkflows { 184 + if file == workflow { 185 + return 186 + } 187 + } 188 + 189 + cfg.DisabledWorkflows = append(cfg.DisabledWorkflows, file) 190 + } 191 + 192 + // FromDB fills up a ActionsConfig from serialized format. 193 + func (cfg *ActionsConfig) FromDB(bs []byte) error { 194 + return json.UnmarshalHandleDoubleEncode(bs, &cfg) 195 + } 196 + 197 + // ToDB exports a ActionsConfig to a serialized format. 198 + func (cfg *ActionsConfig) ToDB() ([]byte, error) { 199 + return json.Marshal(cfg) 200 + } 201 + 165 202 // BeforeSet is invoked from XORM before setting the value of a field of this object. 166 203 func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { 167 204 switch colName { ··· 175 212 r.Config = new(PullRequestsConfig) 176 213 case unit.TypeIssues: 177 214 r.Config = new(IssuesConfig) 178 - case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages, unit.TypeActions: 215 + case unit.TypeActions: 216 + r.Config = new(ActionsConfig) 217 + case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages: 179 218 fallthrough 180 219 default: 181 220 r.Config = new(UnitConfig) ··· 216 255 // ExternalTrackerConfig returns config for unit.TypeExternalTracker 217 256 func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig { 218 257 return r.Config.(*ExternalTrackerConfig) 258 + } 259 + 260 + // ActionsConfig returns config for unit.ActionsConfig 261 + func (r *RepoUnit) ActionsConfig() *ActionsConfig { 262 + return r.Config.(*ActionsConfig) 219 263 } 220 264 221 265 func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
+30
models/repo/repo_unit_test.go
··· 1 + // Copyright 2023 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package repo 5 + 6 + import ( 7 + "testing" 8 + 9 + "github.com/stretchr/testify/assert" 10 + ) 11 + 12 + func TestActionsConfig(t *testing.T) { 13 + cfg := &ActionsConfig{} 14 + cfg.DisableWorkflow("test1.yaml") 15 + assert.EqualValues(t, []string{"test1.yaml"}, cfg.DisabledWorkflows) 16 + 17 + cfg.DisableWorkflow("test1.yaml") 18 + assert.EqualValues(t, []string{"test1.yaml"}, cfg.DisabledWorkflows) 19 + 20 + cfg.EnableWorkflow("test1.yaml") 21 + assert.EqualValues(t, []string{}, cfg.DisabledWorkflows) 22 + 23 + cfg.EnableWorkflow("test1.yaml") 24 + assert.EqualValues(t, []string{}, cfg.DisabledWorkflows) 25 + 26 + cfg.DisableWorkflow("test1.yaml") 27 + cfg.DisableWorkflow("test2.yaml") 28 + cfg.DisableWorkflow("test3.yaml") 29 + assert.EqualValues(t, "test1.yaml,test2.yaml,test3.yaml", cfg.ToString()) 30 + }
+5
options/locale/locale_en-US.ini
··· 3491 3491 runs.no_results = No results matched. 3492 3492 runs.no_runs = The workflow has no runs yet. 3493 3493 3494 + workflow.disable = Disable Workflow 3495 + workflow.disable_success = Workflow '%s' disabled successfully. 3496 + workflow.enable = Enable Workflow 3497 + workflow.enable_success = Workflow '%s' enabled successfully. 3498 + 3494 3499 need_approval_desc = Need approval to run workflows for fork pull request. 3495 3500 3496 3501 variables = Variables
+9
routers/web/repo/actions/actions.go
··· 137 137 actorID := ctx.FormInt64("actor") 138 138 status := ctx.FormInt("status") 139 139 ctx.Data["CurWorkflow"] = workflow 140 + 141 + actionsConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() 142 + ctx.Data["ActionsConfig"] = actionsConfig 143 + 144 + if len(workflow) > 0 && ctx.Repo.IsAdmin() { 145 + ctx.Data["AllowDisableOrEnableWorkflow"] = true 146 + ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflow) 147 + } 148 + 140 149 // if status or actor query param is not given to frontend href, (href="/<repoLink>/actions") 141 150 // they will be 0 by default, which indicates get all status or actors 142 151 ctx.Data["CurActor"] = actorID
+41
routers/web/repo/actions/view.go
··· 17 17 18 18 actions_model "code.gitea.io/gitea/models/actions" 19 19 "code.gitea.io/gitea/models/db" 20 + repo_model "code.gitea.io/gitea/models/repo" 20 21 "code.gitea.io/gitea/models/unit" 21 22 "code.gitea.io/gitea/modules/actions" 22 23 "code.gitea.io/gitea/modules/base" ··· 572 573 } 573 574 } 574 575 } 576 + 577 + func DisableWorkflowFile(ctx *context_module.Context) { 578 + disableOrEnableWorkflowFile(ctx, false) 579 + } 580 + 581 + func EnableWorkflowFile(ctx *context_module.Context) { 582 + disableOrEnableWorkflowFile(ctx, true) 583 + } 584 + 585 + func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable bool) { 586 + workflow := ctx.FormString("workflow") 587 + if len(workflow) == 0 { 588 + ctx.ServerError("workflow", nil) 589 + return 590 + } 591 + 592 + cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) 593 + cfg := cfgUnit.ActionsConfig() 594 + 595 + if isEnable { 596 + cfg.EnableWorkflow(workflow) 597 + } else { 598 + cfg.DisableWorkflow(workflow) 599 + } 600 + 601 + if err := repo_model.UpdateRepoUnit(cfgUnit); err != nil { 602 + ctx.ServerError("UpdateRepoUnit", err) 603 + return 604 + } 605 + 606 + if isEnable { 607 + ctx.Flash.Success(ctx.Tr("actions.workflow.enable_success", workflow)) 608 + } else { 609 + ctx.Flash.Success(ctx.Tr("actions.workflow.disable_success", workflow)) 610 + } 611 + 612 + redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(workflow), 613 + url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) 614 + ctx.JSONRedirect(redirectURL) 615 + }
+2
routers/web/web.go
··· 1200 1200 1201 1201 m.Group("/actions", func() { 1202 1202 m.Get("", actions.List) 1203 + m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) 1204 + m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) 1203 1205 1204 1206 m.Group("/runs/{run}", func() { 1205 1207 m.Combo("").
+7
services/actions/notifier_helper.go
··· 150 150 if len(workflows) == 0 { 151 151 log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RepoPath(), commit.ID) 152 152 } else { 153 + actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig() 154 + 153 155 for _, wf := range workflows { 156 + if actionsConfig.IsWorkflowDisabled(wf.EntryName) { 157 + log.Trace("repo %s has disable workflows %s", input.Repo.RepoPath(), wf.EntryName) 158 + continue 159 + } 160 + 154 161 if wf.TriggerEvent != actions_module.GithubEventPullRequestTarget { 155 162 detectedWorkflows = append(detectedWorkflows, wf) 156 163 }
+18 -1
templates/repo/actions/list.tmpl
··· 2 2 <div class="page-content repository actions"> 3 3 {{template "repo/header" .}} 4 4 <div class="ui container"> 5 + {{template "base/alert" .}} 6 + 5 7 <div class="ui stackable grid"> 6 8 <div class="four wide column"> 7 9 <div class="ui fluid vertical menu"> ··· 13 15 {{svg "octicon-alert" 16 "text red"}} 14 16 </span> 15 17 {{end}} 18 + 19 + {{if $.ActionsConfig.IsWorkflowDisabled .Entry.Name}} 20 + <div class="ui red label">{{$.locale.Tr "disabled"}}</div> 21 + {{end}} 16 22 </a> 17 23 {{end}} 18 24 </div> 19 25 </div> 20 26 <div class="twelve wide column content"> 21 - <div class="ui secondary filter stackable menu gt-je"> 27 + <div class="ui secondary filter menu gt-je gt-df gt-ac"> 22 28 <!-- Actor --> 23 29 <div class="ui{{if not .Actors}} disabled{{end}} dropdown jump item"> 24 30 <span class="text">{{.locale.Tr "actions.runs.actor"}}</span> ··· 57 63 {{end}} 58 64 </div> 59 65 </div> 66 + 67 + {{if .AllowDisableOrEnableWorkflow}} 68 + <button class="ui jump dropdown btn interact-bg gt-p-3"> 69 + {{svg "octicon-kebab-horizontal"}} 70 + <div class="menu"> 71 + <a class="item link-action" data-url="{{$.Link}}/{{if .CurWorkflowDisabled}}enable{{else}}disable{{end}}?workflow={{$.CurWorkflow}}&actor={{.CurActor}}&status={{$.CurStatus}}"> 72 + {{if .CurWorkflowDisabled}}{{.locale.Tr "actions.workflow.enable"}}{{else}}{{.locale.Tr "actions.workflow.disable"}}{{end}} 73 + </a> 74 + </div> 75 + </button> 76 + {{end}} 60 77 </div> 61 78 {{template "repo/actions/runs_list" .}} 62 79 </div>
+17
web_src/css/base.css
··· 653 653 color: var(--color-text); 654 654 } 655 655 656 + /* replace item margin on secondary menu items with gap and remove both the 657 + negative margins on the menu as well as margin on the items */ 658 + .ui.secondary.menu { 659 + margin-left: 0; 660 + margin-right: 0; 661 + gap: .35714286em; 662 + } 663 + .ui.secondary.menu .item { 664 + margin-left: 0; 665 + margin-right: 0; 666 + } 667 + 656 668 .ui.secondary.menu .dropdown.item:hover, 657 669 .ui.secondary.menu a.item:hover { 658 670 color: var(--color-text); ··· 668 680 .ui.secondary.menu.tight .item { 669 681 padding-left: 0.85714286em; 670 682 padding-right: 0.85714286em; 683 + } 684 + 685 + /* remove the menu clearfix so that it won't add undesired gaps when using "gap" */ 686 + .ui.menu::after { 687 + content: normal; 671 688 } 672 689 673 690 .ui.menu .dropdown.item .menu {