From fbadf6f79ef52f6aa9f4cb46647ba11c7c1ad87a Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Wed, 22 Nov 2023 10:38:22 +0800 Subject: [PATCH 01/48] Actions support workflow dispatch event --- routers/web/repo/actions/actions.go | 34 +++++++--- routers/web/repo/actions/view.go | 100 ++++++++++++++++++++++++++++ routers/web/web.go | 1 + templates/repo/actions/list.tmpl | 4 ++ 4 files changed, 130 insertions(+), 9 deletions(-) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index e784912377..dec9785153 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -5,6 +5,8 @@ package actions import ( "bytes" + "code.gitea.io/gitea/modules/log" + webhook_module "code.gitea.io/gitea/modules/webhook" "fmt" "net/http" "strings" @@ -58,6 +60,10 @@ func MustEnableActions(ctx *context.Context) { func List(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("actions.actions") ctx.Data["PageIsActions"] = true + workflowID := ctx.FormString("workflow") + actorID := ctx.FormInt64("actor") + status := ctx.FormInt("status") + ctx.Data["CurWorkflow"] = workflowID var workflows []Workflow if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil { @@ -124,6 +130,21 @@ func List(ctx *context.Context) { } } workflows = append(workflows, workflow) + + if len(workflowID) > 0 && ctx.Repo.IsAdmin() && workflow.Entry.Name() == workflowID { + events, err := actions.GetEventsFromContent(content) + if err != nil { + log.Warn("ignore check invalid workflow events %q: %v", workflow.Entry.Name(), err) + } else { + for _, event := range events { + if event.Name == webhook_module.HookEventWorkflowDispatch.Event() { + ctx.Data["AllowTriggerWorkflowDispatchEvent"] = true + break + } + } + } + } + } } ctx.Data["workflows"] = workflows @@ -134,17 +155,12 @@ func List(ctx *context.Context) { page = 1 } - workflow := ctx.FormString("workflow") - 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() { + if len(workflowID) > 0 && ctx.Repo.IsAdmin() { ctx.Data["AllowDisableOrEnableWorkflow"] = true - ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflow) + ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflowID) } // if status or actor query param is not given to frontend href, (href="//actions") @@ -161,7 +177,7 @@ func List(ctx *context.Context) { PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), }, RepoID: ctx.Repo.Repository.ID, - WorkflowID: workflow, + WorkflowID: workflowID, TriggerUserID: actorID, } @@ -198,7 +214,7 @@ func List(ctx *context.Context) { pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5) pager.SetDefaultParams(ctx) - pager.AddParamString("workflow", workflow) + pager.AddParamString("workflow", workflowID) pager.AddParamString("actor", fmt.Sprint(actorID)) pager.AddParamString("status", fmt.Sprint(status)) ctx.Data["Page"] = pager diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 52c3cf1d07..230fe844dc 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -5,10 +5,12 @@ package actions import ( "archive/zip" + "code.gitea.io/gitea/modules/log" "compress/gzip" "context" "errors" "fmt" + "github.com/nektos/act/pkg/jobparser" "io" "net/http" "net/url" @@ -26,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + webhook_module "code.gitea.io/gitea/modules/webhook" actions_service "code.gitea.io/gitea/services/actions" context_module "code.gitea.io/gitea/services/context" @@ -675,3 +678,100 @@ func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable bool) { url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) ctx.JSONRedirect(redirectURL) } + +func Run(ctx *context_module.Context) { + workflow := ctx.FormString("workflow") + if len(workflow) == 0 { + ctx.ServerError("workflow", nil) + return + } + + // can not rerun job when workflow is disabled + cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) + cfg := cfgUnit.ActionsConfig() + if cfg.IsWorkflowDisabled(workflow) { + ctx.JSONError(ctx.Locale.Tr("actions.workflow.disabled")) + return + } + + commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) + if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + + entries, err := actions.ListWorkflows(commit) + if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + + var dwf *actions.DetectedWorkflow = nil + for _, entry := range entries { + if entry.Name() == workflow { + content, err := actions.GetContentFromEntry(entry) + if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + dwf = &actions.DetectedWorkflow{ + EntryName: entry.Name(), + TriggerEvent: webhook_module.HookEventWorkflowDispatch.Event(), + Content: content, + } + break + } + } + + if dwf == nil { + ctx.JSONError(ctx.Locale.Tr("actions.workflow.not_found")) + return + } + + run := &actions_model.ActionRun{ + Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], + RepoID: ctx.Repo.Repository.ID, + OwnerID: ctx.Repo.Repository.OwnerID, + WorkflowID: workflow, + TriggerUserID: ctx.Doer.ID, + Ref: ctx.Repo.Repository.DefaultBranch, + CommitSHA: commit.ID.String(), + IsForkPullRequest: false, + Event: webhook_module.HookEventWorkflowDispatch, + TriggerEvent: webhook_module.HookEventWorkflowDispatch.Event(), + Status: actions_model.StatusWaiting, + } + + // cancel running jobs of the same workflow + if err := actions_model.CancelRunningJobs( + ctx, + run.RepoID, + run.Ref, + run.WorkflowID, + ); err != nil { + log.Error("CancelRunningJobs: %v", err) + } + + // Parse the workflow specification from the cron schedule + workflows, err := jobparser.Parse(dwf.Content) + if err != nil { + ctx.ServerError("workflow", err) + return + } + + // Insert the action run and its associated jobs into the database + if err := actions_model.InsertRun(ctx, run, workflows); err != nil { + ctx.ServerError("workflow", err) + return + } + + alljobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: run.ID}) + if err != nil { + log.Error("FindRunJobs: %v", err) + } + actions_service.CreateCommitStatus(ctx, alljobs...) + + 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/web.go b/routers/web/web.go index b6dd9500c8..e61bf86796 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1352,6 +1352,7 @@ func registerRoutes(m *web.Route) { m.Get("", actions.List) m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) + m.Post("/run", reqRepoActionsWriter, actions.Run) m.Group("/runs/{run}", func() { m.Combo(""). diff --git a/templates/repo/actions/list.tmpl b/templates/repo/actions/list.tmpl index 62d30305b3..19b1978568 100644 --- a/templates/repo/actions/list.tmpl +++ b/templates/repo/actions/list.tmpl @@ -75,6 +75,10 @@ {{end}} + + {{if .AllowTriggerWorkflowDispatchEvent}} + + {{end}} {{template "repo/actions/runs_list" .}} From 8eb79f3741d80f3336110b98dcfcd24c3b497fa6 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 23 Nov 2023 12:24:49 +0800 Subject: [PATCH 02/48] fix lint check, /actions/run use isAdmin permission --- routers/web/repo/actions/view.go | 2 +- routers/web/web.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 230fe844dc..17ee49fdb9 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -706,7 +706,7 @@ func Run(ctx *context_module.Context) { return } - var dwf *actions.DetectedWorkflow = nil + var dwf *actions.DetectedWorkflow for _, entry := range entries { if entry.Name() == workflow { content, err := actions.GetContentFromEntry(entry) diff --git a/routers/web/web.go b/routers/web/web.go index e61bf86796..8826a8c56b 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1352,7 +1352,7 @@ func registerRoutes(m *web.Route) { m.Get("", actions.List) m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) - m.Post("/run", reqRepoActionsWriter, actions.Run) + m.Post("/run", reqRepoAdmin, actions.Run) m.Group("/runs/{run}", func() { m.Combo(""). From d973fc1765b5fe2ea50d43e7540bb49bbf48b866 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 30 Nov 2023 00:34:08 +0800 Subject: [PATCH 03/48] workflow_dispatch support inputs config --- go.mod | 2 +- go.sum | 2 ++ options/locale/locale_en-US.ini | 3 ++ options/locale/locale_zh-CN.ini | 3 ++ routers/web/repo/actions/actions.go | 1 + routers/web/repo/actions/view.go | 26 +++++++++++--- templates/repo/actions/list.tmpl | 9 ++--- templates/repo/actions/workflow_dispatch.tmpl | 35 +++++++++++++++++++ 8 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 templates/repo/actions/workflow_dispatch.tmpl diff --git a/go.mod b/go.mod index 03f6ad1215..40eb103dda 100644 --- a/go.mod +++ b/go.mod @@ -302,7 +302,7 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 -replace github.com/nektos/act => gitea.com/gitea/act v0.2.51 +replace github.com/nektos/act => gitea.com/pangliang/act v0.251.2-0.20231129053409-6a00b5cb3ceb replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5 diff --git a/go.sum b/go.sum index b3b8ad8ce4..950fbc611c 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:+wWBi6Qfr gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:VyMQP6ue6MKHM8UsOXfNfuMKD0oSAWZdXVcpHIN2yaY= gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHqdhS7keYWioqfmxdnfblFDTGoOwcZ+o= gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= +gitea.com/pangliang/act v0.251.2-0.20231129053409-6a00b5cb3ceb h1:l1Jlxn7D6J+VfoP3R4F1IjxojZ7GEu2+tKeCet5HBkk= +gitea.com/pangliang/act v0.251.2-0.20231129053409-6a00b5cb3ceb/go.mod h1:YthlRq0FUQIzgfJ3ZWvCvVq3I3VsC9s2NYQ9b2Uxccs= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H+XXKmDA1dfFMIN1AislhlA/ps= diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6d4e109e1d..a20c89cdeb 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3594,6 +3594,9 @@ workflow.disable_success = Workflow '%s' disabled successfully. workflow.enable = Enable Workflow workflow.enable_success = Workflow '%s' enabled successfully. workflow.disabled = Workflow is disabled. +workflow.run = Run Workflow +workflow.not_found = Workflow '%s' not found. +workflow.run_success = Workflow '%s' run successfully. need_approval_desc = Need approval to run workflows for fork pull request. diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 89f237a117..ff7cb6cadf 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -3583,6 +3583,9 @@ workflow.disable_success=工作流 '%s' 已成功禁用。 workflow.enable=启用工作流 workflow.enable_success=工作流 '%s' 已成功启用。 workflow.disabled=工作流已禁用。 +workflow.run=运行工作流 +workflow.not_found=工作流 '%s' 不存在。 +workflow.run_success=工作流 '%s' 触发成功。 need_approval_desc=该工作流由派生仓库的合并请求所触发,需要批准方可运行。 diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index dec9785153..812e72c838 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -139,6 +139,7 @@ func List(ctx *context.Context) { for _, event := range events { if event.Name == webhook_module.HookEventWorkflowDispatch.Event() { ctx.Data["AllowTriggerWorkflowDispatchEvent"] = true + ctx.Data["WorkflowDispatchConfig"] = event.WorkflowDispatch() break } } diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 17ee49fdb9..f7d50da10a 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -680,6 +680,9 @@ func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable bool) { } func Run(ctx *context_module.Context) { + redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(ctx.FormString("workflow")), + url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) + workflow := ctx.FormString("workflow") if len(workflow) == 0 { ctx.ServerError("workflow", nil) @@ -690,7 +693,8 @@ func Run(ctx *context_module.Context) { cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) cfg := cfgUnit.ActionsConfig() if cfg.IsWorkflowDisabled(workflow) { - ctx.JSONError(ctx.Locale.Tr("actions.workflow.disabled")) + ctx.Flash.Error(ctx.Tr("actions.workflow.disabled", workflow)) + ctx.Redirect(redirectURL) return } @@ -724,7 +728,8 @@ func Run(ctx *context_module.Context) { } if dwf == nil { - ctx.JSONError(ctx.Locale.Tr("actions.workflow.not_found")) + ctx.Flash.Error(ctx.Tr("actions.workflow.not_found", workflow)) + ctx.Redirect(redirectURL) return } @@ -759,6 +764,18 @@ func Run(ctx *context_module.Context) { return } + for _, wf := range workflows { + if wf.Env == nil { + wf.Env = make(map[string]string) + } + for k, v := range ctx.Req.PostForm { + if k == "_csrf" || len(v) == 0 || v[0] == "" { + continue + } + wf.Env[k] = v[0] + } + } + // Insert the action run and its associated jobs into the database if err := actions_model.InsertRun(ctx, run, workflows); err != nil { ctx.ServerError("workflow", err) @@ -771,7 +788,6 @@ func Run(ctx *context_module.Context) { } actions_service.CreateCommitStatus(ctx, alljobs...) - 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) + ctx.Flash.Success(ctx.Tr("actions.workflow.run_success", workflow)) + ctx.Redirect(redirectURL) } diff --git a/templates/repo/actions/list.tmpl b/templates/repo/actions/list.tmpl index 19b1978568..a955fd6b94 100644 --- a/templates/repo/actions/list.tmpl +++ b/templates/repo/actions/list.tmpl @@ -75,11 +75,12 @@ {{end}} - - {{if .AllowTriggerWorkflowDispatchEvent}} - - {{end}} + + {{if .AllowTriggerWorkflowDispatchEvent}} + {{template "repo/actions/workflow_dispatch" .}} + {{end}} + {{template "repo/actions/runs_list" .}} diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl new file mode 100644 index 0000000000..1f34124f45 --- /dev/null +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -0,0 +1,35 @@ +
+ This workflow has a workflow_dispatch event trigger. + +
+ From e18bbcccd657ceb7db97f4e4a137b8bb4f84d2d6 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 30 Nov 2023 01:08:49 +0800 Subject: [PATCH 04/48] Use db.Find instead of writing methods for every object (#28084) --- routers/web/repo/actions/view.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index f7d50da10a..a8d4b41ff2 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -782,7 +782,7 @@ func Run(ctx *context_module.Context) { return } - alljobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: run.ID}) + alljobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{RunID: run.ID}) if err != nil { log.Error("FindRunJobs: %v", err) } From d0a70d34149cfbb93d16ed0b6490a4673a7c19ea Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Mon, 4 Dec 2023 12:37:45 +0800 Subject: [PATCH 05/48] Use Crowdin to translate them --- options/locale/locale_zh-CN.ini | 3 --- 1 file changed, 3 deletions(-) diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index ff7cb6cadf..89f237a117 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -3583,9 +3583,6 @@ workflow.disable_success=工作流 '%s' 已成功禁用。 workflow.enable=启用工作流 workflow.enable_success=工作流 '%s' 已成功启用。 workflow.disabled=工作流已禁用。 -workflow.run=运行工作流 -workflow.not_found=工作流 '%s' 不存在。 -workflow.run_success=工作流 '%s' 触发成功。 need_approval_desc=该工作流由派生仓库的合并请求所触发,需要批准方可运行。 From 2d2f9218dc775697e34b133bf2fa535cebd1248a Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Tue, 5 Dec 2023 13:16:13 +0800 Subject: [PATCH 06/48] Add ref selector for run workflow from --- options/locale/locale_en-US.ini | 2 + routers/web/repo/actions/actions.go | 28 ++++++++++++++ routers/web/repo/actions/view.go | 38 ++++++++++++++++--- templates/repo/actions/workflow_dispatch.tmpl | 35 ++++++++++++++++- 4 files changed, 96 insertions(+), 7 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index a20c89cdeb..f4bea9ddd0 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -591,6 +591,7 @@ org_still_own_repo = "This organization still owns one or more repositories, del org_still_own_packages = "This organization still owns one or more packages, delete them first." target_branch_not_exist = Target branch does not exist. +target_ref_not_exist = Target ref does not exist %s admin_cannot_delete_self = You cannot delete yourself when you are an admin. Please remove your admin privileges first. @@ -3597,6 +3598,7 @@ workflow.disabled = Workflow is disabled. workflow.run = Run Workflow workflow.not_found = Workflow '%s' not found. workflow.run_success = Workflow '%s' run successfully. +workflow.from_ref = Use workflow from need_approval_desc = Need approval to run workflows for fork pull request. diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index 812e72c838..5cbe26e752 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -5,10 +5,14 @@ package actions import ( "bytes" + git_model "code.gitea.io/gitea/models/git" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" "fmt" "net/http" + "slices" "strings" actions_model "code.gitea.io/gitea/models/actions" @@ -140,6 +144,30 @@ func List(ctx *context.Context) { if event.Name == webhook_module.HookEventWorkflowDispatch.Event() { ctx.Data["AllowTriggerWorkflowDispatchEvent"] = true ctx.Data["WorkflowDispatchConfig"] = event.WorkflowDispatch() + + branchOpts := git_model.FindBranchOptions{ + RepoID: ctx.Repo.Repository.ID, + IsDeletedBranch: util.OptionalBoolFalse, + ListOptions: db.ListOptions{ + ListAll: true, + }, + } + branches, err := git_model.FindBranchNames(ctx, branchOpts) + if err != nil { + ctx.JSON(http.StatusInternalServerError, err) + return + } + // always put default branch on the top if it exists + if slices.Contains(branches, ctx.Repo.Repository.DefaultBranch) { + branches = util.SliceRemoveAll(branches, ctx.Repo.Repository.DefaultBranch) + branches = append([]string{ctx.Repo.Repository.DefaultBranch}, branches...) + } + ctx.Data["Branches"] = branches + + tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID) + if err == nil { + ctx.Data["Tags"] = tags + } break } } diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index a8d4b41ff2..b2f1ae2457 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -5,6 +5,7 @@ package actions import ( "archive/zip" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "compress/gzip" "context" @@ -689,6 +690,12 @@ func Run(ctx *context_module.Context) { return } + ref := ctx.FormString("ref") + if len(ref) == 0 { + ctx.ServerError("workflow", nil) + return + } + // can not rerun job when workflow is disabled cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) cfg := cfgUnit.ActionsConfig() @@ -698,13 +705,32 @@ func Run(ctx *context_module.Context) { return } - commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) + // get target commit of run from specified ref + refName := git.RefName(ref) + var runTargetCommit *git.Commit + var err error + if refName.IsTag() { + runTargetCommit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName()) + } else if refName.IsBranch() { + runTargetCommit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName()) + } else { + ctx.Flash.Error(ctx.Tr("form.git_ref_name_error", ref)) + ctx.Redirect(redirectURL) + return + } + if err != nil { + ctx.Flash.Error(ctx.Tr("form.target_ref_not_exist", ref)) + ctx.Redirect(redirectURL) + return + } + + // get workflow entry from default branch commit + defaultBranchCommit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } - - entries, err := actions.ListWorkflows(commit) + entries, err := actions.ListWorkflows(defaultBranchCommit) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return @@ -734,13 +760,13 @@ func Run(ctx *context_module.Context) { } run := &actions_model.ActionRun{ - Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], + Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0], RepoID: ctx.Repo.Repository.ID, OwnerID: ctx.Repo.Repository.OwnerID, WorkflowID: workflow, TriggerUserID: ctx.Doer.ID, - Ref: ctx.Repo.Repository.DefaultBranch, - CommitSHA: commit.ID.String(), + Ref: ref, + CommitSHA: runTargetCommit.ID.String(), IsForkPullRequest: false, Event: webhook_module.HookEventWorkflowDispatch, TriggerEvent: webhook_module.HookEventWorkflowDispatch.Event(), diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 1f34124f45..55095d85ab 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -6,6 +6,39 @@
{{.CsrfTokenHtml}} +
+ + +
+ +
{{if .WorkflowDispatchConfig}} {{range $key, $item := .WorkflowDispatchConfig.Inputs}}
@@ -29,7 +62,7 @@
{{end}} {{end}} - +
From 660cf18de0d6c24de3584067063748cbc970db34 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Tue, 5 Dec 2023 14:52:26 +0800 Subject: [PATCH 07/48] Follow the behavior of github, only render templates, do not directly fill in env --- routers/web/repo/actions/view.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index b2f1ae2457..d65a69b20c 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -790,18 +790,6 @@ func Run(ctx *context_module.Context) { return } - for _, wf := range workflows { - if wf.Env == nil { - wf.Env = make(map[string]string) - } - for k, v := range ctx.Req.PostForm { - if k == "_csrf" || len(v) == 0 || v[0] == "" { - continue - } - wf.Env[k] = v[0] - } - } - // Insert the action run and its associated jobs into the database if err := actions_model.InsertRun(ctx, run, workflows); err != nil { ctx.ServerError("workflow", err) From 2829a8875b727c6733387ee28d46bf429e5ebd68 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Tue, 5 Dec 2023 15:33:55 +0800 Subject: [PATCH 08/48] Form validate --- templates/repo/actions/workflow_dispatch.tmpl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 55095d85ab..bac4df8ad1 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -1,10 +1,18 @@ + +
This workflow has a workflow_dispatch event trigger.
- {{if .AllowTriggerWorkflowDispatchEvent}} + {{if .WorkflowDispatchConfig}} {{template "repo/actions/workflow_dispatch" .}} {{end}} diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 3ae05b6bcc..67f78c22f7 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -47,7 +47,6 @@
- {{if .WorkflowDispatchConfig}} {{range $key, $item := .WorkflowDispatchConfig.Inputs}}
{{if eq .Type "choice"}} @@ -71,7 +70,6 @@ {{end}}
{{end}} - {{end}} From 44615a52112db94505c88fd40dabfbaeb6407acf Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 7 Dec 2023 16:01:20 +0800 Subject: [PATCH 17/48] support type "number" form validation --- templates/repo/actions/workflow_dispatch.tmpl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 67f78c22f7..d083fe1d8b 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -1,7 +1,9 @@ @@ -63,6 +65,10 @@ {{.Description}} + {{else if eq .Type "number"}} + + + {{.Description}} {{else}} From c24dede6eb2ef9293eacc1283c6807676217bee8 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 7 Dec 2023 16:50:11 +0800 Subject: [PATCH 18/48] Returns nil when workflow_dispatch is not defined --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bfe7e3d75a..69f429eed5 100644 --- a/go.mod +++ b/go.mod @@ -302,7 +302,7 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 -replace github.com/nektos/act => gitea.com/pangliang/act v0.251.2-0.20231207061303-82548746b6e4 +replace github.com/nektos/act => gitea.com/pangliang/act v0.251.2-0.20231207083920-176e5f65fa26 replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5 diff --git a/go.sum b/go.sum index 4a23ace868..c5911c7927 100644 --- a/go.sum +++ b/go.sum @@ -63,8 +63,8 @@ gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:+wWBi6Qfr gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:VyMQP6ue6MKHM8UsOXfNfuMKD0oSAWZdXVcpHIN2yaY= gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHqdhS7keYWioqfmxdnfblFDTGoOwcZ+o= gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= -gitea.com/pangliang/act v0.251.2-0.20231207061303-82548746b6e4 h1:b5jCRaAnUbIrC8aZ8xawYT+ONlMEzZT4JGjQZOdyNjA= -gitea.com/pangliang/act v0.251.2-0.20231207061303-82548746b6e4/go.mod h1:YthlRq0FUQIzgfJ3ZWvCvVq3I3VsC9s2NYQ9b2Uxccs= +gitea.com/pangliang/act v0.251.2-0.20231207083920-176e5f65fa26 h1:TaGFTMmoWIBjQQmMy0nmX50ty/fajUMWFb18v0Eyi+s= +gitea.com/pangliang/act v0.251.2-0.20231207083920-176e5f65fa26/go.mod h1:YthlRq0FUQIzgfJ3ZWvCvVq3I3VsC9s2NYQ9b2Uxccs= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H+XXKmDA1dfFMIN1AislhlA/ps= From 65b03134334c0198bf63d66dcc45d947928564b3 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 7 Dec 2023 23:35:04 +0800 Subject: [PATCH 19/48] Add WorkflowDispatchPayload for pass Webhook event payload to runner --- modules/structs/hook.go | 14 +++++++ routers/web/repo/actions/view.go | 69 +++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/modules/structs/hook.go b/modules/structs/hook.go index 0babe84410..8fb243f578 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -494,3 +494,17 @@ type PackagePayload struct { func (p *PackagePayload) JSONPayload() ([]byte, error) { return json.MarshalIndent(p, "", " ") } + +// WorkflowDispatchPayload represents a workflow dispatch payload +type WorkflowDispatchPayload struct { + Workflow string `json:"workflow"` + Ref string `json:"ref"` + Inputs map[string]interface{} `json:"inputs"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` +} + +// JSONPayload implements Payload +func (p *WorkflowDispatchPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 0868e94a22..adeed613d1 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -5,13 +5,18 @@ package actions import ( "archive/zip" + "code.gitea.io/gitea/models/perm" + access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" "compress/gzip" "context" "errors" "fmt" "github.com/nektos/act/pkg/jobparser" + "github.com/nektos/act/pkg/model" "io" "net/http" "net/url" @@ -683,8 +688,8 @@ func Run(ctx *context_module.Context) { redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(ctx.FormString("workflow")), url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status"))) - workflow := ctx.FormString("workflow") - if len(workflow) == 0 { + workflowID := ctx.FormString("workflow") + if len(workflowID) == 0 { ctx.ServerError("workflow", nil) return } @@ -698,7 +703,7 @@ func Run(ctx *context_module.Context) { // can not rerun job when workflow is disabled cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) cfg := cfgUnit.ActionsConfig() - if cfg.IsWorkflowDisabled(workflow) { + if cfg.IsWorkflowDisabled(workflowID) { ctx.Flash.Error(ctx.Tr("actions.workflow.disabled")) ctx.Redirect(redirectURL) return @@ -737,7 +742,7 @@ func Run(ctx *context_module.Context) { var dwf *actions.DetectedWorkflow for _, entry := range entries { - if entry.Name() == workflow { + if entry.Name() == workflowID { content, err := actions.GetContentFromEntry(entry) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) @@ -753,22 +758,65 @@ func Run(ctx *context_module.Context) { } if dwf == nil { - ctx.Flash.Error(ctx.Tr("actions.workflow.not_found", workflow)) + ctx.Flash.Error(ctx.Tr("actions.workflow.not_found", workflowID)) ctx.Redirect(redirectURL) return } + workflows, err := jobparser.Parse(dwf.Content) + if err != nil || len(workflows) == 0 { + ctx.ServerError("workflow", err) + return + } + + //all workflows have the same RawOn + workflow := &model.Workflow{ + RawOn: workflows[0].RawOn, + } + inputs := make(map[string]interface{}) + if workflowDispatch := workflow.WorkflowDispatchConfig(); workflowDispatch != nil { + for name, config := range workflowDispatch.Inputs { + value := ctx.Req.PostForm.Get(name) + if config.Type == "boolean" { + // https://www.w3.org/TR/html401/interact/forms.html + // https://stackoverflow.com/questions/11424037/do-checkbox-inputs-only-post-data-if-theyre-checked + // Checkboxes (and radio buttons) are on/off switches that may be toggled by the user. + // A switch is "on" when the control element's checked attribute is set. + // When a form is submitted, only "on" checkbox controls can become successful. + inputs[name] = strconv.FormatBool(value == "on") + } else if value != "" { + inputs[name] = value + } else { + inputs[name] = config.Default + } + } + } + + workflowDispatchPayload := &api.WorkflowDispatchPayload{ + Workflow: workflowID, + Ref: ref, + Repository: convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeNone}), + Inputs: inputs, + Sender: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone), + } + var eventPayload []byte + if eventPayload, err = workflowDispatchPayload.JSONPayload(); err != nil { + ctx.ServerError("JSONPayload", err) + return + } + run := &actions_model.ActionRun{ Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0], RepoID: ctx.Repo.Repository.ID, OwnerID: ctx.Repo.Repository.OwnerID, - WorkflowID: workflow, + WorkflowID: workflowID, TriggerUserID: ctx.Doer.ID, Ref: ref, CommitSHA: runTargetCommit.ID.String(), IsForkPullRequest: false, Event: "workflow_dispatch", TriggerEvent: "workflow_dispatch", + EventPayload: string(eventPayload), Status: actions_model.StatusWaiting, } @@ -782,13 +830,6 @@ func Run(ctx *context_module.Context) { log.Error("CancelRunningJobs: %v", err) } - // Parse the workflow specification from the cron schedule - workflows, err := jobparser.Parse(dwf.Content) - if err != nil { - ctx.ServerError("workflow", err) - return - } - // Insert the action run and its associated jobs into the database if err := actions_model.InsertRun(ctx, run, workflows); err != nil { ctx.ServerError("workflow", err) @@ -801,6 +842,6 @@ func Run(ctx *context_module.Context) { } actions_service.CreateCommitStatus(ctx, alljobs...) - ctx.Flash.Success(ctx.Tr("actions.workflow.run_success", workflow)) + ctx.Flash.Success(ctx.Tr("actions.workflow.run_success", workflowID)) ctx.Redirect(redirectURL) } From faf3b087b1a507f33562fcf754d875b6c95371bc Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Fri, 8 Dec 2023 00:20:13 +0800 Subject: [PATCH 20/48] DetectedWorkflow unnecessary --- routers/web/repo/actions/view.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index adeed613d1..2344a8633a 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -740,7 +740,8 @@ func Run(ctx *context_module.Context) { return } - var dwf *actions.DetectedWorkflow + // find workflow from commit + var workflows []*jobparser.SingleWorkflow for _, entry := range entries { if entry.Name() == workflowID { content, err := actions.GetContentFromEntry(entry) @@ -748,28 +749,22 @@ func Run(ctx *context_module.Context) { ctx.Error(http.StatusInternalServerError, err.Error()) return } - dwf = &actions.DetectedWorkflow{ - EntryName: entry.Name(), - TriggerEvent: "workflow_dispatch", - Content: content, + workflows, err = jobparser.Parse(content) + if err != nil { + ctx.ServerError("workflow", err) + return } break } } - if dwf == nil { + if workflows == nil || len(workflows) == 0 { ctx.Flash.Error(ctx.Tr("actions.workflow.not_found", workflowID)) ctx.Redirect(redirectURL) return } - workflows, err := jobparser.Parse(dwf.Content) - if err != nil || len(workflows) == 0 { - ctx.ServerError("workflow", err) - return - } - - //all workflows have the same RawOn + // get inputs from post workflow := &model.Workflow{ RawOn: workflows[0].RawOn, } @@ -792,6 +787,9 @@ func Run(ctx *context_module.Context) { } } + // ctx.Req.PostForm -> WorkflowDispatchPayload.Inputs -> ActionRun.EventPayload -> runner: ghc.Event + // https://docs.github.com/en/actions/learn-github-actions/contexts#github-context + // https://docs.github.com/en/webhooks/webhook-events-and-payloads#workflow_dispatch workflowDispatchPayload := &api.WorkflowDispatchPayload{ Workflow: workflowID, Ref: ref, From 1f64b24f03dc36040b7755ba2aeae4efe1c8627b Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Mon, 11 Dec 2023 09:21:12 +0800 Subject: [PATCH 21/48] only required is enough. --- templates/repo/actions/workflow_dispatch.tmpl | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index d083fe1d8b..29d10c0fe3 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -1,13 +1,3 @@ - -
This workflow has a workflow_dispatch event trigger. @@ -67,11 +57,11 @@
{{else if eq .Type "number"}} - + {{.Description}} {{else}} - + {{.Description}} {{end}} From 5e0a0bca4c58eda186b5592058e87ba6270bfa58 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Mon, 11 Dec 2023 18:32:36 +0800 Subject: [PATCH 22/48] should omit nil check --- routers/web/repo/actions/view.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 2344a8633a..8a71b2f00e 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -758,7 +758,7 @@ func Run(ctx *context_module.Context) { } } - if workflows == nil || len(workflows) == 0 { + if len(workflows) == 0 { ctx.Flash.Error(ctx.Tr("actions.workflow.not_found", workflowID)) ctx.Redirect(redirectURL) return From 5ddf23ac335a329556c80b986fc517d7782389a5 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Mon, 11 Dec 2023 18:39:10 +0800 Subject: [PATCH 23/48] Remove unsupported description section of workflow_dispatch from documentation --- docs/content/usage/actions/comparison.en-us.md | 6 ------ docs/content/usage/actions/comparison.zh-cn.md | 6 ------ 2 files changed, 12 deletions(-) diff --git a/docs/content/usage/actions/comparison.en-us.md b/docs/content/usage/actions/comparison.en-us.md index 1ea3afac5b..afe31d0bbb 100644 --- a/docs/content/usage/actions/comparison.en-us.md +++ b/docs/content/usage/actions/comparison.en-us.md @@ -79,12 +79,6 @@ See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/usin Gitea Actions only supports `runs-on: xyz` or `runs-on: [xyz]` now. -### `workflow_dispatch` - -See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatch). - -It's ignored by Gitea Actions now. - ### `hashFiles` expression See [Expressions](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles) diff --git a/docs/content/usage/actions/comparison.zh-cn.md b/docs/content/usage/actions/comparison.zh-cn.md index 16b2181ba2..5bc6cc548c 100644 --- a/docs/content/usage/actions/comparison.zh-cn.md +++ b/docs/content/usage/actions/comparison.zh-cn.md @@ -79,12 +79,6 @@ Gitea Actions 目前不支持此功能。 Gitea Actions目前只支持`runs-on: xyz`或`runs-on: [xyz]`。 -### `workflow_dispatch` - -请参阅[GitHub Actions的工作流语法](https://docs.github.com/zh/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatch)。 - -Gitea Actions目前不支持此功能。 - ### `hashFiles`表达式 请参阅[表达式](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles)。 From a6db4165775a90581516538a5d9dfb9618178168 Mon Sep 17 00:00:00 2001 From: TKaxv_7S <954067342@qq.com> Date: Mon, 11 Dec 2023 20:49:54 +0800 Subject: [PATCH 24/48] Fix workflow dispatch ui --- templates/repo/actions/workflow_dispatch.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 29d10c0fe3..02f36ec079 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -1,6 +1,6 @@ -
- This workflow has a workflow_dispatch event trigger. - +
+ This workflow has a workflow_dispatch event trigger. +
From 50694f2477c0de04f3985c19a2a600243fc73022 Mon Sep 17 00:00:00 2001 From: pangliang <418094911@qq.com> Date: Thu, 7 Mar 2024 08:13:48 +0800 Subject: [PATCH 35/48] smaller branch dropdown button --- templates/repo/actions/workflow_dispatch.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index e0c1d3cb56..3955db59eb 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -8,7 +8,7 @@ {{.CsrfTokenHtml}}
-