From 48af0ffa4553efa37667a1571d524c553211b8a2 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Fri, 3 Jan 2025 15:56:05 +0100 Subject: [PATCH 01/11] workflow_dispatch use workflow from trigger branch * htmx updates the input form on branch switch * add workflow warning to dispatch modal * use name if description of input is empty --- routers/web/repo/actions/actions.go | 143 +++++++++++------- routers/web/repo/actions/view.go | 9 +- routers/web/web.go | 1 + templates/repo/actions/workflow_dispatch.tmpl | 27 +--- .../actions/workflow_dispatch_inputs.tmpl | 30 ++++ 5 files changed, 126 insertions(+), 84 deletions(-) create mode 100644 templates/repo/actions/workflow_dispatch_inputs.tmpl diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index f0d8d81fee598..a6d6b71e87608 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -32,8 +32,9 @@ import ( ) const ( - tplListActions templates.TplName = "repo/actions/list" - tplViewActions templates.TplName = "repo/actions/view" + tplListActions templates.TplName = "repo/actions/list" + tplDispatchInputsActions templates.TplName = "repo/actions/workflow_dispatch_inputs" + tplViewActions templates.TplName = "repo/actions/view" ) type Workflow struct { @@ -62,6 +63,14 @@ func MustEnableActions(ctx *context.Context) { } func List(ctx *context.Context) { + renderListAndWorkflowDispatchTemplate(ctx, tplListActions, false) +} + +func WorkflowDispatchInputs(ctx *context.Context) { + renderListAndWorkflowDispatchTemplate(ctx, tplDispatchInputsActions, true) +} + +func renderListAndWorkflowDispatchTemplate(ctx *context.Context, tplName templates.TplName, inputsOnly bool) { ctx.Data["Title"] = ctx.Tr("actions.actions") ctx.Data["PageIsActions"] = true workflowID := ctx.FormString("workflow") @@ -75,10 +84,34 @@ func List(ctx *context.Context) { ctx.ServerError("IsEmpty", err) return } else if !empty { - commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) - if err != nil { - ctx.ServerError("GetBranchCommit", err) - return + var commit *git.Commit + if inputsOnly { + ref := ctx.FormString("ref") + if len(ref) == 0 { + ctx.ServerError("ref", nil) + return + } + // get target commit of run from specified ref + refName := git.RefName(ref) + var err error + if refName.IsTag() { + commit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName()) + } else if refName.IsBranch() { + commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName()) + } else { + ctx.ServerError("git_ref_name_error", nil) + return + } + if err != nil { + ctx.ServerError("target_ref_not_exist", err) + return + } + } else { + commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) + if err != nil { + ctx.ServerError("GetBranchCommit", err) + return + } } entries, err := actions.ListWorkflows(commit) if err != nil { @@ -207,65 +240,67 @@ func List(ctx *context.Context) { } } - // if status or actor query param is not given to frontend href, (href="//actions") - // they will be 0 by default, which indicates get all status or actors - ctx.Data["CurActor"] = actorID - ctx.Data["CurStatus"] = status - if actorID > 0 || status > int(actions_model.StatusUnknown) { - ctx.Data["IsFiltered"] = true - } + if !inputsOnly { + // if status or actor query param is not given to frontend href, (href="//actions") + // they will be 0 by default, which indicates get all status or actors + ctx.Data["CurActor"] = actorID + ctx.Data["CurStatus"] = status + if actorID > 0 || status > int(actions_model.StatusUnknown) { + ctx.Data["IsFiltered"] = true + } - opts := actions_model.FindRunOptions{ - ListOptions: db.ListOptions{ - Page: page, - PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), - }, - RepoID: ctx.Repo.Repository.ID, - WorkflowID: workflowID, - TriggerUserID: actorID, - } + opts := actions_model.FindRunOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), + }, + RepoID: ctx.Repo.Repository.ID, + WorkflowID: workflowID, + TriggerUserID: actorID, + } - // if status is not StatusUnknown, it means user has selected a status filter - if actions_model.Status(status) != actions_model.StatusUnknown { - opts.Status = []actions_model.Status{actions_model.Status(status)} - } + // if status is not StatusUnknown, it means user has selected a status filter + if actions_model.Status(status) != actions_model.StatusUnknown { + opts.Status = []actions_model.Status{actions_model.Status(status)} + } - runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts) - if err != nil { - ctx.ServerError("FindAndCount", err) - return - } + runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts) + if err != nil { + ctx.ServerError("FindAndCount", err) + return + } - for _, run := range runs { - run.Repo = ctx.Repo.Repository - } + for _, run := range runs { + run.Repo = ctx.Repo.Repository + } - if err := actions_model.RunList(runs).LoadTriggerUser(ctx); err != nil { - ctx.ServerError("LoadTriggerUser", err) - return - } + if err := actions_model.RunList(runs).LoadTriggerUser(ctx); err != nil { + ctx.ServerError("LoadTriggerUser", err) + return + } - if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil { - log.Error("LoadIsRefDeleted", err) - } + if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil { + log.Error("LoadIsRefDeleted", err) + } - ctx.Data["Runs"] = runs + ctx.Data["Runs"] = runs - actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID) - if err != nil { - ctx.ServerError("GetActors", err) - return - } - ctx.Data["Actors"] = shared_user.MakeSelfOnTop(ctx.Doer, actors) + actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID) + if err != nil { + ctx.ServerError("GetActors", err) + return + } + ctx.Data["Actors"] = shared_user.MakeSelfOnTop(ctx.Doer, actors) - ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx) + ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx) - pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) - ctx.Data["Page"] = pager - ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0 + pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5) + pager.AddParamFromRequest(ctx.Req) + ctx.Data["Page"] = pager + ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0 + } - ctx.HTML(http.StatusOK, tplListActions) + ctx.HTML(http.StatusOK, tplName) } // loadIsRefDeleted loads the IsRefDeleted field for each run in the list. diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index ba17fa427d1a8..9a18ca530582f 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -812,13 +812,8 @@ func Run(ctx *context_module.Context) { 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(defaultBranchCommit) + // get workflow entry from runTargetCommit + entries, err := actions.ListWorkflows(runTargetCommit) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return diff --git a/routers/web/web.go b/routers/web/web.go index 5e0995545e814..bf03bac1d10a2 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1412,6 +1412,7 @@ func registerRoutes(m *web.Router) { m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile) m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile) m.Post("/run", reqRepoActionsWriter, actions.Run) + m.Get("/dispatch-inputs", reqRepoActionsWriter, actions.WorkflowDispatchInputs) m.Group("/runs/{run}", func() { m.Combo(""). diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 21f3ef2077294..fc090fc7343d4 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -11,7 +11,7 @@ diff --git a/templates/repo/actions/workflow_dispatch_inputs.tmpl b/templates/repo/actions/workflow_dispatch_inputs.tmpl index a5a22673f9d09..0647394cbd8b4 100644 --- a/templates/repo/actions/workflow_dispatch_inputs.tmpl +++ b/templates/repo/actions/workflow_dispatch_inputs.tmpl @@ -1,3 +1,33 @@ +{{if not .WorkflowDispatchConfig}} +
+ {{ctx.Locale.Tr "actions.workflow.not_found" $.CurWorkflow}} +
+{{else}} + {{range $item := .WorkflowDispatchConfig.Inputs}} +
+ {{if eq .Type "choice"}} + + + {{else if eq .Type "boolean"}} +
+ + +
+ {{else if eq .Type "number"}} + + + {{else}} + + + {{end}} +
+ {{end}} + +{{end}} {{range .workflows}} {{if and .ErrMsg (eq .Entry.Name $.CurWorkflow)}} @@ -5,26 +35,3 @@ {{end}} {{end}} -{{range $item := .WorkflowDispatchConfig.Inputs}} -
- {{if eq .Type "choice"}} - - - {{else if eq .Type "boolean"}} -
- - -
- {{else if eq .Type "number"}} - - - {{else}} - - - {{end}} -
-{{end}} From c241c6c086e5510ac723475200d02688ae47519a Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jan 2025 06:21:20 +0800 Subject: [PATCH 04/11] refactor --- routers/web/repo/actions/actions.go | 309 ++++++++++++++-------------- routers/web/web.go | 2 +- 2 files changed, 154 insertions(+), 157 deletions(-) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index a6d6b71e87608..de04eaf1f1937 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -63,141 +63,131 @@ func MustEnableActions(ctx *context.Context) { } func List(ctx *context.Context) { - renderListAndWorkflowDispatchTemplate(ctx, tplListActions, false) + ctx.Data["Title"] = ctx.Tr("actions.actions") + ctx.Data["PageIsActions"] = true + + commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) + if err != nil { + ctx.ServerError("GetBranchCommit", err) + return + } + prepareWorkflowDispatchTemplate(ctx, commit) + ctx.HTML(http.StatusOK, tplListActions) } func WorkflowDispatchInputs(ctx *context.Context) { - renderListAndWorkflowDispatchTemplate(ctx, tplDispatchInputsActions, true) + ref := ctx.FormString("ref") + if ref == "" { + ctx.NotFound("WorkflowDispatchInputs: no ref", nil) + return + } + // get target commit of run from specified ref + refName := git.RefName(ref) + var commit *git.Commit + var err error + if refName.IsTag() { + commit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName()) + } else if refName.IsBranch() { + commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName()) + } else { + ctx.ServerError("UnsupportedRefType", nil) + return + } + if err != nil { + ctx.ServerError("GetTagCommit/GetBranchCommit", err) + return + } + workflows := prepareWorkflowDispatchTemplate(ctx, commit) + prepareWorkflowList(ctx, workflows) + ctx.HTML(http.StatusOK, tplDispatchInputsActions) } -func renderListAndWorkflowDispatchTemplate(ctx *context.Context, tplName templates.TplName, inputsOnly bool) { - ctx.Data["Title"] = ctx.Tr("actions.actions") - ctx.Data["PageIsActions"] = true +func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) (workflows []Workflow) { workflowID := ctx.FormString("workflow") - actorID := ctx.FormInt64("actor") - status := ctx.FormInt("status") ctx.Data["CurWorkflow"] = workflowID - var workflows []Workflow var curWorkflow *model.Workflow - if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil { - ctx.ServerError("IsEmpty", err) + + entries, err := actions.ListWorkflows(commit) + if err != nil { + ctx.ServerError("ListWorkflows", err) return - } else if !empty { - var commit *git.Commit - if inputsOnly { - ref := ctx.FormString("ref") - if len(ref) == 0 { - ctx.ServerError("ref", nil) - return - } - // get target commit of run from specified ref - refName := git.RefName(ref) - var err error - if refName.IsTag() { - commit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName()) - } else if refName.IsBranch() { - commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName()) - } else { - ctx.ServerError("git_ref_name_error", nil) - return - } - if err != nil { - ctx.ServerError("target_ref_not_exist", err) - return - } - } else { - commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) - if err != nil { - ctx.ServerError("GetBranchCommit", err) - return - } - } - entries, err := actions.ListWorkflows(commit) - if err != nil { - ctx.ServerError("ListWorkflows", err) - return - } + } - // Get all runner labels - runners, err := db.Find[actions_model.ActionRunner](ctx, actions_model.FindRunnerOptions{ - RepoID: ctx.Repo.Repository.ID, - IsOnline: optional.Some(true), - WithAvailable: true, - }) + // Get all runner labels + runners, err := db.Find[actions_model.ActionRunner](ctx, actions_model.FindRunnerOptions{ + RepoID: ctx.Repo.Repository.ID, + IsOnline: optional.Some(true), + WithAvailable: true, + }) + if err != nil { + ctx.ServerError("FindRunners", err) + return + } + allRunnerLabels := make(container.Set[string]) + for _, r := range runners { + allRunnerLabels.AddMultiple(r.AgentLabels...) + } + + workflows = make([]Workflow, 0, len(entries)) + for _, entry := range entries { + workflow := Workflow{Entry: *entry} + content, err := actions.GetContentFromEntry(entry) if err != nil { - ctx.ServerError("FindRunners", err) + ctx.ServerError("GetContentFromEntry", err) return } - allRunnerLabels := make(container.Set[string]) - for _, r := range runners { - allRunnerLabels.AddMultiple(r.AgentLabels...) + wf, err := model.ReadWorkflow(bytes.NewReader(content)) + if err != nil { + workflow.ErrMsg = ctx.Locale.TrString("actions.runs.invalid_workflow_helper", err.Error()) + workflows = append(workflows, workflow) + continue } - - workflows = make([]Workflow, 0, len(entries)) - for _, entry := range entries { - workflow := Workflow{Entry: *entry} - content, err := actions.GetContentFromEntry(entry) - if err != nil { - ctx.ServerError("GetContentFromEntry", err) - return - } - wf, err := model.ReadWorkflow(bytes.NewReader(content)) - if err != nil { - workflow.ErrMsg = ctx.Locale.TrString("actions.runs.invalid_workflow_helper", err.Error()) - workflows = append(workflows, workflow) + // The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run. + hasJobWithoutNeeds := false + // Check whether you have matching runner and a job without "needs" + emptyJobsNumber := 0 + for _, j := range wf.Jobs { + if j == nil { + emptyJobsNumber++ continue } - // The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run. - hasJobWithoutNeeds := false - // Check whether have matching runner and a job without "needs" - emptyJobsNumber := 0 - for _, j := range wf.Jobs { - if j == nil { - emptyJobsNumber++ + if !hasJobWithoutNeeds && len(j.Needs()) == 0 { + hasJobWithoutNeeds = true + } + runsOnList := j.RunsOn() + for _, ro := range runsOnList { + if strings.Contains(ro, "${{") { + // Skip if it contains expressions. + // The expressions could be very complex and could not be evaluated here, + // so just skip it, it's OK since it's just a tooltip message. continue } - if !hasJobWithoutNeeds && len(j.Needs()) == 0 { - hasJobWithoutNeeds = true - } - runsOnList := j.RunsOn() - for _, ro := range runsOnList { - if strings.Contains(ro, "${{") { - // Skip if it contains expressions. - // The expressions could be very complex and could not be evaluated here, - // so just skip it, it's OK since it's just a tooltip message. - continue - } - if !allRunnerLabels.Contains(ro) { - workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_matching_online_runner_helper", ro) - break - } - } - if workflow.ErrMsg != "" { + if !allRunnerLabels.Contains(ro) { + workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_matching_online_runner_helper", ro) break } } - if !hasJobWithoutNeeds { - workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job_without_needs") - } - if emptyJobsNumber == len(wf.Jobs) { - workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job") + if workflow.ErrMsg != "" { + break } - workflows = append(workflows, workflow) + } + if !hasJobWithoutNeeds { + workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job_without_needs") + } + if emptyJobsNumber == len(wf.Jobs) { + workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job") + } + workflows = append(workflows, workflow) - if workflow.Entry.Name() == workflowID { - curWorkflow = wf - } + if workflow.Entry.Name() == workflowID { + curWorkflow = wf } } + ctx.Data["workflows"] = workflows ctx.Data["RepoLink"] = ctx.Repo.Repository.Link() - page := ctx.FormInt("page") - if page <= 0 { - page = 1 - } - actionsConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() ctx.Data["ActionsConfig"] = actionsConfig @@ -239,68 +229,75 @@ func renderListAndWorkflowDispatchTemplate(ctx *context.Context, tplName templat } } } + return workflows +} - if !inputsOnly { - // if status or actor query param is not given to frontend href, (href="//actions") - // they will be 0 by default, which indicates get all status or actors - ctx.Data["CurActor"] = actorID - ctx.Data["CurStatus"] = status - if actorID > 0 || status > int(actions_model.StatusUnknown) { - ctx.Data["IsFiltered"] = true - } - - opts := actions_model.FindRunOptions{ - ListOptions: db.ListOptions{ - Page: page, - PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), - }, - RepoID: ctx.Repo.Repository.ID, - WorkflowID: workflowID, - TriggerUserID: actorID, - } +func prepareWorkflowList(ctx *context.Context, workflows []Workflow) { + actorID := ctx.FormInt64("actor") + status := ctx.FormInt("status") + workflowID := ctx.FormString("workflow") + page := ctx.FormInt("page") + if page <= 0 { + page = 1 + } - // if status is not StatusUnknown, it means user has selected a status filter - if actions_model.Status(status) != actions_model.StatusUnknown { - opts.Status = []actions_model.Status{actions_model.Status(status)} - } + // if status or actor query param is not given to frontend href, (href="//actions") + // they will be 0 by default, which indicates get all status or actors + ctx.Data["CurActor"] = actorID + ctx.Data["CurStatus"] = status + if actorID > 0 || status > int(actions_model.StatusUnknown) { + ctx.Data["IsFiltered"] = true + } - runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts) - if err != nil { - ctx.ServerError("FindAndCount", err) - return - } + opts := actions_model.FindRunOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), + }, + RepoID: ctx.Repo.Repository.ID, + WorkflowID: workflowID, + TriggerUserID: actorID, + } - for _, run := range runs { - run.Repo = ctx.Repo.Repository - } + // if status is not StatusUnknown, it means user has selected a status filter + if actions_model.Status(status) != actions_model.StatusUnknown { + opts.Status = []actions_model.Status{actions_model.Status(status)} + } - if err := actions_model.RunList(runs).LoadTriggerUser(ctx); err != nil { - ctx.ServerError("LoadTriggerUser", err) - return - } + runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts) + if err != nil { + ctx.ServerError("FindAndCount", err) + return + } - if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil { - log.Error("LoadIsRefDeleted", err) - } + for _, run := range runs { + run.Repo = ctx.Repo.Repository + } - ctx.Data["Runs"] = runs + if err := actions_model.RunList(runs).LoadTriggerUser(ctx); err != nil { + ctx.ServerError("LoadTriggerUser", err) + return + } - actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID) - if err != nil { - ctx.ServerError("GetActors", err) - return - } - ctx.Data["Actors"] = shared_user.MakeSelfOnTop(ctx.Doer, actors) + if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil { + log.Error("LoadIsRefDeleted", err) + } - ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx) + ctx.Data["Runs"] = runs - pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) - ctx.Data["Page"] = pager - ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0 + actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID) + if err != nil { + ctx.ServerError("GetActors", err) + return } + ctx.Data["Actors"] = shared_user.MakeSelfOnTop(ctx.Doer, actors) + + ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx) - ctx.HTML(http.StatusOK, tplName) + pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5) + pager.AddParamFromRequest(ctx.Req) + ctx.Data["Page"] = pager + ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0 } // loadIsRefDeleted loads the IsRefDeleted field for each run in the list. diff --git a/routers/web/web.go b/routers/web/web.go index f8c62f9040e4e..ff91bda3d2e65 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1434,7 +1434,7 @@ func registerRoutes(m *web.Router) { m.Group("/workflows/{workflow_name}", func() { m.Get("/badge.svg", actions.GetWorkflowBadge) }) - }, optSignIn, context.RepoAssignment, reqRepoActionsReader, actions.MustEnableActions) + }, optSignIn, context.RepoAssignment, repo.MustBeNotEmpty, reqRepoActionsReader, actions.MustEnableActions) // end "/{username}/{reponame}/actions" m.Group("/{username}/{reponame}/wiki", func() { From 55248783b720c6aab02a71489074ec2b2eaa69e9 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jan 2025 06:30:57 +0800 Subject: [PATCH 05/11] add CurWorkflowExists, format tmpl --- routers/web/repo/actions/actions.go | 2 + .../actions/workflow_dispatch_inputs.tmpl | 58 ++++++++++--------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index de04eaf1f1937..d34e39332be9b 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -105,6 +105,7 @@ func WorkflowDispatchInputs(ctx *context.Context) { func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) (workflows []Workflow) { workflowID := ctx.FormString("workflow") ctx.Data["CurWorkflow"] = workflowID + ctx.Data["CurWorkflowExists"] = false var curWorkflow *model.Workflow @@ -182,6 +183,7 @@ func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) ( if workflow.Entry.Name() == workflowID { curWorkflow = wf + ctx.Data["CurWorkflowExists"] = true } } diff --git a/templates/repo/actions/workflow_dispatch_inputs.tmpl b/templates/repo/actions/workflow_dispatch_inputs.tmpl index 0647394cbd8b4..c5145e6273a90 100644 --- a/templates/repo/actions/workflow_dispatch_inputs.tmpl +++ b/templates/repo/actions/workflow_dispatch_inputs.tmpl @@ -1,37 +1,41 @@ {{if not .WorkflowDispatchConfig}} -
- {{ctx.Locale.Tr "actions.workflow.not_found" $.CurWorkflow}} +
+ {{/* TODO: Technically this error is also shown if no workflow_dispatch is defined. However we need to know if the workflow exist like in #33098 (comment) to render a different error text. + A: does the newly added "CurWorkflowExists" help? */}} + {{ctx.Locale.Tr "actions.workflow.not_found" $.CurWorkflow}}
{{else}} {{range $item := .WorkflowDispatchConfig.Inputs}} -
- {{if eq .Type "choice"}} - - - {{else if eq .Type "boolean"}} -
- - -
- {{else if eq .Type "number"}} - - - {{else}} - - - {{end}} -
+
+ {{if eq .Type "choice"}} + + + {{else if eq .Type "boolean"}} +
+ + +
+ {{else if eq .Type "number"}} + + + {{else}} + + + {{end}} +
{{end}} - +
+ +
{{end}} {{range .workflows}} {{if and .ErrMsg (eq .Entry.Name $.CurWorkflow)}} - - {{svg "octicon-alert" 16 "text red"}} - +
+
{{svg "octicon-alert" 16 "text red"}} {{.ErrMsg}}
+
{{end}} {{end}} From 12493ff4d39bbdc17ec1c35d9488c9b6f29ac5ac Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jan 2025 06:44:23 +0800 Subject: [PATCH 06/11] fix tmpl call --- routers/web/repo/actions/actions.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index d34e39332be9b..c2b550b9d5f00 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -71,7 +71,8 @@ func List(ctx *context.Context) { ctx.ServerError("GetBranchCommit", err) return } - prepareWorkflowDispatchTemplate(ctx, commit) + workflows := prepareWorkflowDispatchTemplate(ctx, commit) + prepareWorkflowList(ctx, workflows) ctx.HTML(http.StatusOK, tplListActions) } @@ -97,8 +98,7 @@ func WorkflowDispatchInputs(ctx *context.Context) { ctx.ServerError("GetTagCommit/GetBranchCommit", err) return } - workflows := prepareWorkflowDispatchTemplate(ctx, commit) - prepareWorkflowList(ctx, workflows) + prepareWorkflowDispatchTemplate(ctx, commit) ctx.HTML(http.StatusOK, tplDispatchInputsActions) } From 828cc17be280430640bfd0a31d199bcf5a2520ae Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jan 2025 06:53:13 +0800 Subject: [PATCH 07/11] make label text clickable --- templates/repo/actions/workflow_dispatch_inputs.tmpl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/repo/actions/workflow_dispatch_inputs.tmpl b/templates/repo/actions/workflow_dispatch_inputs.tmpl index c5145e6273a90..836a37f377522 100644 --- a/templates/repo/actions/workflow_dispatch_inputs.tmpl +++ b/templates/repo/actions/workflow_dispatch_inputs.tmpl @@ -15,10 +15,11 @@ {{end}} {{else if eq .Type "boolean"}} -
- + {{/* htmx doesn't trigger our JS code to attach fomantic label to checkbox, so here we use standard checkbox */}} +
+ {{or .Description .Name}} + {{else if eq .Type "number"}} From 64346dc4f438eba4c028aa38eba93a3feab9558c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jan 2025 06:55:07 +0800 Subject: [PATCH 08/11] fix lint --- routers/web/repo/actions/actions.go | 22 ++++++++++++++----- .../actions/workflow_dispatch_inputs.tmpl | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index c2b550b9d5f00..539c4b6ed003c 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -71,8 +71,17 @@ func List(ctx *context.Context) { ctx.ServerError("GetBranchCommit", err) return } + workflows := prepareWorkflowDispatchTemplate(ctx, commit) + if ctx.Written() { + return + } + prepareWorkflowList(ctx, workflows) + if ctx.Written() { + return + } + ctx.HTML(http.StatusOK, tplListActions) } @@ -99,6 +108,9 @@ func WorkflowDispatchInputs(ctx *context.Context) { return } prepareWorkflowDispatchTemplate(ctx, commit) + if ctx.Written() { + return + } ctx.HTML(http.StatusOK, tplDispatchInputsActions) } @@ -112,7 +124,7 @@ func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) ( entries, err := actions.ListWorkflows(commit) if err != nil { ctx.ServerError("ListWorkflows", err) - return + return nil } // Get all runner labels @@ -123,7 +135,7 @@ func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) ( }) if err != nil { ctx.ServerError("FindRunners", err) - return + return nil } allRunnerLabels := make(container.Set[string]) for _, r := range runners { @@ -136,7 +148,7 @@ func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) ( content, err := actions.GetContentFromEntry(entry) if err != nil { ctx.ServerError("GetContentFromEntry", err) - return + return nil } wf, err := model.ReadWorkflow(bytes.NewReader(content)) if err != nil { @@ -213,7 +225,7 @@ func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) ( branches, err := git_model.FindBranchNames(ctx, branchOpts) if err != nil { ctx.ServerError("FindBranchNames", err) - return + return nil } // always put default branch on the top if it exists if slices.Contains(branches, ctx.Repo.Repository.DefaultBranch) { @@ -225,7 +237,7 @@ func prepareWorkflowDispatchTemplate(ctx *context.Context, commit *git.Commit) ( tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID) if err != nil { ctx.ServerError("GetTagNamesByRepoID", err) - return + return nil } ctx.Data["Tags"] = tags } diff --git a/templates/repo/actions/workflow_dispatch_inputs.tmpl b/templates/repo/actions/workflow_dispatch_inputs.tmpl index 836a37f377522..fdcc404055b4b 100644 --- a/templates/repo/actions/workflow_dispatch_inputs.tmpl +++ b/templates/repo/actions/workflow_dispatch_inputs.tmpl @@ -1,5 +1,5 @@ {{if not .WorkflowDispatchConfig}} -
+
{{/* TODO: Technically this error is also shown if no workflow_dispatch is defined. However we need to know if the workflow exist like in #33098 (comment) to render a different error text. A: does the newly added "CurWorkflowExists" help? */}} {{ctx.Locale.Tr "actions.workflow.not_found" $.CurWorkflow}} From d6459d05b7964b9652a11939b61d335a86f92d61 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jan 2025 06:59:50 +0800 Subject: [PATCH 09/11] remove unused query parameters --- templates/repo/actions/workflow_dispatch.tmpl | 2 +- templates/repo/actions/workflow_dispatch_inputs.tmpl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index d20e6bfbfddd6..55fe1224194ea 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -11,7 +11,7 @@