mirror of
https://github.com/go-gitea/gitea.git
synced 2025-02-20 11:43:57 +08:00
workflow_dispatch use workflow from trigger branch (#33098)
* htmx updates the input form on branch switch * add workflow warning to dispatch modal * use name if description of input is empty * show error if workflow_dispatch not available on branch Closes #33073 Closes #33099 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
3078826d01
commit
4237736029
@ -3765,6 +3765,7 @@ workflow.not_found = Workflow '%s' not found.
|
|||||||
workflow.run_success = Workflow '%s' run successfully.
|
workflow.run_success = Workflow '%s' run successfully.
|
||||||
workflow.from_ref = Use workflow from
|
workflow.from_ref = Use workflow from
|
||||||
workflow.has_workflow_dispatch = This workflow has a workflow_dispatch event trigger.
|
workflow.has_workflow_dispatch = This workflow has a workflow_dispatch event trigger.
|
||||||
|
workflow.has_no_workflow_dispatch = Workflow '%s' has no workflow_dispatch event trigger.
|
||||||
|
|
||||||
need_approval_desc = Need approval to run workflows for fork pull request.
|
need_approval_desc = Need approval to run workflows for fork pull request.
|
||||||
|
|
||||||
|
@ -32,8 +32,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tplListActions templates.TplName = "repo/actions/list"
|
tplListActions templates.TplName = "repo/actions/list"
|
||||||
tplViewActions templates.TplName = "repo/actions/view"
|
tplDispatchInputsActions templates.TplName = "repo/actions/workflow_dispatch_inputs"
|
||||||
|
tplViewActions templates.TplName = "repo/actions/view"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Workflow struct {
|
type Workflow struct {
|
||||||
@ -64,107 +65,143 @@ func MustEnableActions(ctx *context.Context) {
|
|||||||
func List(ctx *context.Context) {
|
func List(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("actions.actions")
|
ctx.Data["Title"] = ctx.Tr("actions.actions")
|
||||||
ctx.Data["PageIsActions"] = true
|
ctx.Data["PageIsActions"] = true
|
||||||
workflowID := ctx.FormString("workflow")
|
|
||||||
actorID := ctx.FormInt64("actor")
|
|
||||||
status := ctx.FormInt("status")
|
|
||||||
ctx.Data["CurWorkflow"] = workflowID
|
|
||||||
|
|
||||||
var workflows []Workflow
|
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
|
||||||
var curWorkflow *model.Workflow
|
if err != nil {
|
||||||
if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil {
|
ctx.ServerError("GetBranchCommit", err)
|
||||||
ctx.ServerError("IsEmpty", err)
|
|
||||||
return
|
return
|
||||||
} else if !empty {
|
}
|
||||||
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
|
workflows := prepareWorkflowDispatchTemplate(ctx, commit)
|
||||||
runners, err := db.Find[actions_model.ActionRunner](ctx, actions_model.FindRunnerOptions{
|
if ctx.Written() {
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
return
|
||||||
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))
|
prepareWorkflowList(ctx, workflows)
|
||||||
for _, entry := range entries {
|
if ctx.Written() {
|
||||||
workflow := Workflow{Entry: *entry}
|
return
|
||||||
content, err := actions.GetContentFromEntry(entry)
|
}
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetContentFromEntry", err)
|
ctx.HTML(http.StatusOK, tplListActions)
|
||||||
return
|
}
|
||||||
}
|
|
||||||
wf, err := model.ReadWorkflow(bytes.NewReader(content))
|
func WorkflowDispatchInputs(ctx *context.Context) {
|
||||||
if err != nil {
|
ref := ctx.FormString("ref")
|
||||||
workflow.ErrMsg = ctx.Locale.TrString("actions.runs.invalid_workflow_helper", err.Error())
|
if ref == "" {
|
||||||
workflows = append(workflows, workflow)
|
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
|
||||||
|
}
|
||||||
|
prepareWorkflowDispatchTemplate(ctx, commit)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.HTML(http.StatusOK, tplDispatchInputsActions)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
entries, err := actions.ListWorkflows(commit)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("ListWorkflows", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 nil
|
||||||
|
}
|
||||||
|
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("GetContentFromEntry", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
// The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run.
|
if !hasJobWithoutNeeds && len(j.Needs()) == 0 {
|
||||||
hasJobWithoutNeeds := false
|
hasJobWithoutNeeds = true
|
||||||
// Check whether have matching runner and a job without "needs"
|
}
|
||||||
emptyJobsNumber := 0
|
runsOnList := j.RunsOn()
|
||||||
for _, j := range wf.Jobs {
|
for _, ro := range runsOnList {
|
||||||
if j == nil {
|
if strings.Contains(ro, "${{") {
|
||||||
emptyJobsNumber++
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
if !hasJobWithoutNeeds && len(j.Needs()) == 0 {
|
if !allRunnerLabels.Contains(ro) {
|
||||||
hasJobWithoutNeeds = true
|
workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_matching_online_runner_helper", ro)
|
||||||
}
|
|
||||||
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 != "" {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !hasJobWithoutNeeds {
|
if workflow.ErrMsg != "" {
|
||||||
workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job_without_needs")
|
break
|
||||||
}
|
|
||||||
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 !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
|
||||||
|
ctx.Data["CurWorkflowExists"] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["workflows"] = workflows
|
ctx.Data["workflows"] = workflows
|
||||||
ctx.Data["RepoLink"] = ctx.Repo.Repository.Link()
|
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()
|
actionsConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions).ActionsConfig()
|
||||||
ctx.Data["ActionsConfig"] = actionsConfig
|
ctx.Data["ActionsConfig"] = actionsConfig
|
||||||
|
|
||||||
@ -188,7 +225,7 @@ func List(ctx *context.Context) {
|
|||||||
branches, err := git_model.FindBranchNames(ctx, branchOpts)
|
branches, err := git_model.FindBranchNames(ctx, branchOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("FindBranchNames", err)
|
ctx.ServerError("FindBranchNames", err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
// always put default branch on the top if it exists
|
// always put default branch on the top if it exists
|
||||||
if slices.Contains(branches, ctx.Repo.Repository.DefaultBranch) {
|
if slices.Contains(branches, ctx.Repo.Repository.DefaultBranch) {
|
||||||
@ -200,12 +237,23 @@ func List(ctx *context.Context) {
|
|||||||
tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID)
|
tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetTagNamesByRepoID", err)
|
ctx.ServerError("GetTagNamesByRepoID", err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
ctx.Data["Tags"] = tags
|
ctx.Data["Tags"] = tags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return workflows
|
||||||
|
}
|
||||||
|
|
||||||
|
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 or actor query param is not given to frontend href, (href="/<repoLink>/actions")
|
// 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
|
// they will be 0 by default, which indicates get all status or actors
|
||||||
@ -264,8 +312,6 @@ func List(ctx *context.Context) {
|
|||||||
pager.AddParamFromRequest(ctx.Req)
|
pager.AddParamFromRequest(ctx.Req)
|
||||||
ctx.Data["Page"] = pager
|
ctx.Data["Page"] = pager
|
||||||
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
|
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplListActions)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadIsRefDeleted loads the IsRefDeleted field for each run in the list.
|
// loadIsRefDeleted loads the IsRefDeleted field for each run in the list.
|
||||||
|
@ -812,13 +812,8 @@ func Run(ctx *context_module.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get workflow entry from default branch commit
|
// get workflow entry from runTargetCommit
|
||||||
defaultBranchCommit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
|
entries, err := actions.ListWorkflows(runTargetCommit)
|
||||||
if err != nil {
|
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
entries, err := actions.ListWorkflows(defaultBranchCommit)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -1412,6 +1412,7 @@ func registerRoutes(m *web.Router) {
|
|||||||
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
|
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
|
||||||
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
|
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
|
||||||
m.Post("/run", reqRepoActionsWriter, actions.Run)
|
m.Post("/run", reqRepoActionsWriter, actions.Run)
|
||||||
|
m.Get("/workflow-dispatch-inputs", reqRepoActionsWriter, actions.WorkflowDispatchInputs)
|
||||||
|
|
||||||
m.Group("/runs/{run}", func() {
|
m.Group("/runs/{run}", func() {
|
||||||
m.Combo("").
|
m.Combo("").
|
||||||
@ -1433,7 +1434,7 @@ func registerRoutes(m *web.Router) {
|
|||||||
m.Group("/workflows/{workflow_name}", func() {
|
m.Group("/workflows/{workflow_name}", func() {
|
||||||
m.Get("/badge.svg", actions.GetWorkflowBadge)
|
m.Get("/badge.svg", actions.GetWorkflowBadge)
|
||||||
})
|
})
|
||||||
}, optSignIn, context.RepoAssignment, reqRepoActionsReader, actions.MustEnableActions)
|
}, optSignIn, context.RepoAssignment, repo.MustBeNotEmpty, reqRepoActionsReader, actions.MustEnableActions)
|
||||||
// end "/{username}/{reponame}/actions"
|
// end "/{username}/{reponame}/actions"
|
||||||
|
|
||||||
m.Group("/{username}/{reponame}/wiki", func() {
|
m.Group("/{username}/{reponame}/wiki", func() {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<label>{{ctx.Locale.Tr "actions.workflow.from_ref"}}:</label>
|
<label>{{ctx.Locale.Tr "actions.workflow.from_ref"}}:</label>
|
||||||
</span>
|
</span>
|
||||||
<div class="ui inline field dropdown button select-branch branch-selector-dropdown ellipsis-items-nowrap">
|
<div class="ui inline field dropdown button select-branch branch-selector-dropdown ellipsis-items-nowrap">
|
||||||
<input type="hidden" name="ref" value="refs/heads/{{index .Branches 0}}">
|
<input type="hidden" name="ref" hx-sync="this:replace" hx-target="#runWorkflowDispatchModalInputs" hx-swap="innerHTML" hx-get="{{$.Link}}/workflow-dispatch-inputs?workflow={{$.CurWorkflow}}" hx-trigger="change" value="refs/heads/{{index .Branches 0}}">
|
||||||
{{svg "octicon-git-branch" 14}}
|
{{svg "octicon-git-branch" 14}}
|
||||||
<div class="default text">{{index .Branches 0}}</div>
|
<div class="default text">{{index .Branches 0}}</div>
|
||||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
@ -49,30 +49,9 @@
|
|||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
|
||||||
{{range $item := .WorkflowDispatchConfig.Inputs}}
|
<div id="runWorkflowDispatchModalInputs">
|
||||||
<div class="ui field {{if .Required}}required{{end}}">
|
{{template "repo/actions/workflow_dispatch_inputs" .}}
|
||||||
{{if eq .Type "choice"}}
|
|
||||||
<label>{{.Description}}:</label>
|
|
||||||
<select class="ui selection type dropdown" name="{{.Name}}">
|
|
||||||
{{range .Options}}
|
|
||||||
<option value="{{.}}" {{if eq $item.Default .}}selected{{end}} >{{.}}</option>
|
|
||||||
{{end}}
|
|
||||||
</select>
|
|
||||||
{{else if eq .Type "boolean"}}
|
|
||||||
<div class="ui inline checkbox">
|
|
||||||
<label>{{.Description}}</label>
|
|
||||||
<input type="checkbox" name="{{.Name}}" {{if eq .Default "true"}}checked{{end}}>
|
|
||||||
</div>
|
|
||||||
{{else if eq .Type "number"}}
|
|
||||||
<label>{{.Description}}:</label>
|
|
||||||
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
|
|
||||||
{{else}}
|
|
||||||
<label>{{.Description}}:</label>
|
|
||||||
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
|
||||||
<button class="ui tiny primary button" type="submit">Submit</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
45
templates/repo/actions/workflow_dispatch_inputs.tmpl
Normal file
45
templates/repo/actions/workflow_dispatch_inputs.tmpl
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{{if not .WorkflowDispatchConfig}}
|
||||||
|
<div class="ui error message tw-block">{{/* using "ui message" in "ui form" needs to force to display */}}
|
||||||
|
{{if not .CurWorkflowExists}}
|
||||||
|
{{ctx.Locale.Tr "actions.workflow.not_found" $.CurWorkflow}}
|
||||||
|
{{else}}
|
||||||
|
{{ctx.Locale.Tr "actions.workflow.has_no_workflow_dispatch" $.CurWorkflow}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{range $item := .WorkflowDispatchConfig.Inputs}}
|
||||||
|
<div class="ui field {{if .Required}}required{{end}}">
|
||||||
|
{{if eq .Type "choice"}}
|
||||||
|
<label>{{or .Description .Name}}:</label>
|
||||||
|
{{/* htmx won't initialize the fomantic dropdown, so it is a standard "select" input */}}
|
||||||
|
<select class="ui selection dropdown" name="{{.Name}}">
|
||||||
|
{{range .Options}}
|
||||||
|
<option value="{{.}}" {{if eq $item.Default .}}selected{{end}}>{{.}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
{{else if eq .Type "boolean"}}
|
||||||
|
{{/* htmx doesn't trigger our JS code to attach fomantic label to checkbox, so here we use standard checkbox */}}
|
||||||
|
<label class="tw-flex flex-text-inline">
|
||||||
|
<input type="checkbox" name="{{.Name}}" {{if eq .Default "true"}}checked{{end}}>
|
||||||
|
{{or .Description .Name}}
|
||||||
|
</label>
|
||||||
|
{{else if eq .Type "number"}}
|
||||||
|
<label>{{or .Description .Name}}:</label>
|
||||||
|
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
|
||||||
|
{{else}}
|
||||||
|
<label>{{or .Description .Name}}:</label>
|
||||||
|
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
<div class="ui field">
|
||||||
|
<button class="ui tiny primary button" type="submit">{{ctx.Locale.Tr "actions.workflow.run"}}</button>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{range .workflows}}
|
||||||
|
{{if and .ErrMsg (eq .Entry.Name $.CurWorkflow)}}
|
||||||
|
<div class="ui field">
|
||||||
|
<div>{{svg "octicon-alert" 16 "text red"}} {{.ErrMsg}}</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
Loading…
x
Reference in New Issue
Block a user