Skip to content
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

add disable workflow feature #26413

Merged
merged 23 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
95841b7
add disable workflow feature
a1012112796 Aug 9, 2023
c0cfb1a
Merge branch 'main' into zzc/dev/disable_workflow
silverwind Aug 10, 2023
5951e46
Apply suggestions from code review
a1012112796 Aug 10, 2023
19f0a9d
fix build
a1012112796 Aug 10, 2023
7300fae
Merge remote-tracking branch 'origin/main' into zzc/dev/disable_workflow
a1012112796 Aug 10, 2023
c176633
vertically center button
silverwind Aug 11, 2023
d22cfc1
ui enhancements
silverwind Aug 11, 2023
7522147
classname cleanup
silverwind Aug 11, 2023
9538f45
fix template lint
silverwind Aug 11, 2023
665f1c0
Apply suggestions from code review
a1012112796 Aug 11, 2023
00df673
use a instead of div for menu item
silverwind Aug 11, 2023
1fd8b6d
remove unused translations
silverwind Aug 11, 2023
3e758a8
fix typo
a1012112796 Aug 11, 2023
2d0bbe4
Merge remote-tracking branch 'origin/main' into zzc/dev/disable_workflow
a1012112796 Aug 11, 2023
f0cfff2
remove useless async
silverwind Aug 11, 2023
b2a5c22
remove unnecessary button classes
silverwind Aug 12, 2023
a76819d
fix mobile view, remove negative margin from .ui.secondary.menu
silverwind Aug 12, 2023
70d758b
Apply suggestions from code review
a1012112796 Aug 13, 2023
3d97409
Merge remote-tracking branch 'origin/main' into zzc/dev/disable_workflow
a1012112796 Aug 13, 2023
0ac99a2
use gap for item spacing in secondary menu, remove clearfix
silverwind Aug 14, 2023
6abdd1a
fix whitespace
silverwind Aug 14, 2023
952b509
Merge branch 'main' into zzc/dev/disable_workflow
GiteaBot Aug 14, 2023
3728333
Merge branch 'main' into zzc/dev/disable_workflow
GiteaBot Aug 14, 2023
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
6 changes: 6 additions & 0 deletions models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,13 @@ func (repo *Repository) MustGetUnit(ctx context.Context, tp unit.Type) *RepoUnit
Type: tp,
Config: new(IssuesConfig),
}
} else if tp == unit.TypeActions {
return &RepoUnit{
Type: tp,
Config: new(ActionsConfig),
}
}

return &RepoUnit{
Type: tp,
Config: new(UnitConfig),
Expand Down
57 changes: 56 additions & 1 deletion models/repo/repo_unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package repo
import (
"context"
"fmt"
"strings"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unit"
Expand Down Expand Up @@ -162,6 +163,53 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
return MergeStyleMerge
}

type ActionsConfig struct {
DisabledWorkflows []string
}

func (cfg *ActionsConfig) EnableWorkflow(file string) {
for i, workflow := range cfg.DisabledWorkflows {
if file == workflow {
cfg.DisabledWorkflows = append(cfg.DisabledWorkflows[:i], cfg.DisabledWorkflows[i+1:]...)
break
}
}
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
}

func (cfg *ActionsConfig) ToString() string {
return strings.Join(cfg.DisabledWorkflows, ",")
}

func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool {
for _, workflow := range cfg.DisabledWorkflows {
if file == workflow {
return true
}
}

return false
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
}

func (cfg *ActionsConfig) DisableWorkflow(file string) {
for _, workflow := range cfg.DisabledWorkflows {
if file == workflow {
return
}
}

cfg.DisabledWorkflows = append(cfg.DisabledWorkflows, file)
}

// FromDB fills up a ActionsConfig from serialized format.
func (cfg *ActionsConfig) FromDB(bs []byte) error {
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}

// ToDB exports a ActionsConfig to a serialized format.
func (cfg *ActionsConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}

// BeforeSet is invoked from XORM before setting the value of a field of this object.
func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
switch colName {
Expand All @@ -175,7 +223,9 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
r.Config = new(PullRequestsConfig)
case unit.TypeIssues:
r.Config = new(IssuesConfig)
case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages, unit.TypeActions:
case unit.TypeActions:
r.Config = new(ActionsConfig)
case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages:
fallthrough
default:
r.Config = new(UnitConfig)
Expand Down Expand Up @@ -218,6 +268,11 @@ func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
return r.Config.(*ExternalTrackerConfig)
}

// ActionsConfig returns config for unit.ActionsConfig
func (r *RepoUnit) ActionsConfig() *ActionsConfig {
return r.Config.(*ActionsConfig)
}

func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
var tmpUnits []*RepoUnit
if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil {
Expand Down
30 changes: 30 additions & 0 deletions models/repo/repo_unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package repo

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestActionsConfig(t *testing.T) {
cfg := &ActionsConfig{}
cfg.DisableWorkflow("test1.yaml")
assert.EqualValues(t, []string{"test1.yaml"}, cfg.DisabledWorkflows)

cfg.DisableWorkflow("test1.yaml")
assert.EqualValues(t, []string{"test1.yaml"}, cfg.DisabledWorkflows)

cfg.EnableWorkflow("test1.yaml")
assert.EqualValues(t, []string{}, cfg.DisabledWorkflows)

cfg.EnableWorkflow("test1.yaml")
assert.EqualValues(t, []string{}, cfg.DisabledWorkflows)

cfg.DisableWorkflow("test1.yaml")
cfg.DisableWorkflow("test2.yaml")
cfg.DisableWorkflow("test3.yaml")
assert.EqualValues(t, "test1.yaml,test2.yaml,test3.yaml", cfg.ToString())
}
5 changes: 5 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3488,6 +3488,11 @@ runs.status_no_select = All status
runs.no_results = No results matched.
runs.no_runs = The workflow has no runs yet.

workflow.disable = Disable Workflow
workflow.disable_success = Workflow '%s' disabled successfully.
workflow.enable = Enable Workflow
workflow.enable_success = Workflow '%s' enabled successfully.

need_approval_desc = Need approval to run workflows for fork pull request.

variables = Variables
Expand Down
9 changes: 9 additions & 0 deletions routers/web/repo/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ func List(ctx *context.Context) {
actorID := ctx.FormInt64("actor")
status := ctx.FormInt("status")
ctx.Data["CurWorkflow"] = workflow

actionsConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions).ActionsConfig()
ctx.Data["ActionsConfig"] = actionsConfig

if len(workflow) > 0 && ctx.Repo.IsAdmin() {
ctx.Data["AllowDisableOrEnableWorkflow"] = true
ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflow)
}

// if status or actor query param is not given to frontend href, (href="/<repoLink>/actions")
// they will be 0 by default, which indicates get all status or actors
ctx.Data["CurActor"] = actorID
Expand Down
41 changes: 41 additions & 0 deletions routers/web/repo/actions/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/base"
Expand Down Expand Up @@ -572,3 +573,43 @@ func ArtifactsDownloadView(ctx *context_module.Context) {
}
}
}

func DisableWorkflowFile(ctx *context_module.Context) {
disableOrEnableWorkflowFile(ctx, false)
}

func EnableWorkflowFile(ctx *context_module.Context) {
disableOrEnableWorkflowFile(ctx, true)
}

func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable 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 isEnable {
cfg.EnableWorkflow(workflow)
} else {
cfg.DisableWorkflow(workflow)
}

if err := repo_model.UpdateRepoUnit(cfgUnit); err != nil {
ctx.ServerError("UpdateRepoUnit", err)
return
}

if isEnable {
ctx.Flash.Success(ctx.Tr("actions.workflow.enable_success", workflow))
} else {
ctx.Flash.Success(ctx.Tr("actions.workflow.disable_success", workflow))
}

redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, workflow,
ctx.FormString("actor"), ctx.FormString("status"))
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
ctx.Redirect(redirectURL)
}
2 changes: 2 additions & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,8 @@ func registerRoutes(m *web.Route) {

m.Group("/actions", func() {
m.Get("", actions.List)
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)

m.Group("/runs/{run}", func() {
m.Combo("").
Expand Down
7 changes: 7 additions & 0 deletions services/actions/notifier_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,14 @@ func notify(ctx context.Context, input *notifyInput) error {
if len(workflows) == 0 {
log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RepoPath(), commit.ID)
} else {
actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig()

for _, wf := range workflows {
if actionsConfig.IsWorkflowDisabled(wf.EntryName) {
log.Trace("repo %s has disable workflows %s", input.Repo.RepoPath(), wf.EntryName)
continue
}

if wf.TriggerEvent != actions_module.GithubEventPullRequestTarget {
detectedWorkflows = append(detectedWorkflows, wf)
}
Expand Down
18 changes: 17 additions & 1 deletion templates/repo/actions/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
{{svg "octicon-alert" 16 "text red"}}
</span>
{{end}}

{{if $.ActionsConfig.IsWorkflowDisabled .Entry.Name}}
<div class="ui red label">{{$.locale.Tr "disabled"}}</div>
{{end}}
</a>
{{end}}
</div>
</div>
<div class="twelve wide column content">
<div class="ui secondary filter stackable menu gt-je">
<div class="ui secondary filter stackable menu gt-je gt-df gt-ac">
silverwind marked this conversation as resolved.
Show resolved Hide resolved
<!-- Actor -->
<div class="ui{{if not .Actors}} disabled{{end}} dropdown jump item">
<span class="text">{{.locale.Tr "actions.runs.actor"}}</span>
Expand Down Expand Up @@ -57,6 +61,18 @@
{{end}}
</div>
</div>

{{if .AllowDisableOrEnableWorkflow}}
<button class="ui small compact jump dropdown icon btn interact-bg gt-p-3">
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
{{svg "octicon-kebab-horizontal"}}
<div class="menu">
<a class="item" id="disable-workflow-btn">{{if .CurWorkflowDisabled}}{{.locale.Tr "actions.workflow.enable"}}{{else}}{{.locale.Tr "actions.workflow.disable"}}{{end}}</a>
</div>
</button>
<form id="disable-workflow-form" class="gt-hidden ignore-dirty" action="{{$.Link}}/{{if .CurWorkflowDisabled}}enable{{else}}disable{{end}}?workflow={{$.CurWorkflow}}&actor={{.CurActor}}&status={{$.CurStatus}}" method="post">
{{.CsrfTokenHtml}}
</form>
{{end}}
</div>
{{template "repo/actions/runs_list" .}}
</div>
Expand Down
8 changes: 8 additions & 0 deletions web_src/js/features/repo-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function initRepoActionList() {
const disableWorkflowBtn = document.getElementById('disable-workflow-btn');
if (disableWorkflowBtn) {
disableWorkflowBtn.addEventListener('click', () => {
document.getElementById('disable-workflow-form').submit();
});
}
silverwind marked this conversation as resolved.
Show resolved Hide resolved
}
2 changes: 2 additions & 0 deletions web_src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {initSshKeyFormParser} from './features/sshkey-helper.js';
import {initUserSettings} from './features/user-settings.js';
import {initRepoArchiveLinks} from './features/repo-common.js';
import {initRepoMigrationStatusChecker} from './features/repo-migrate.js';
import {initRepoActionList} from './features/repo-actions.js';
import {
initRepoSettingGitHook,
initRepoSettingsCollaboration,
Expand Down Expand Up @@ -166,6 +167,7 @@ onDomReady(() => {
initRepoSettingsCollaboration();
initRepoTemplateSearch();
initRepoTopicBar();
initRepoActionList();
initRepoWikiForm();
initRepository();
initRepositoryActionView();
Expand Down