Skip to content

Commit 48af0ff

Browse files
committed
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
1 parent 3d544a3 commit 48af0ff

File tree

5 files changed

+126
-84
lines changed

5 files changed

+126
-84
lines changed

routers/web/repo/actions/actions.go

Lines changed: 89 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ import (
3232
)
3333

3434
const (
35-
tplListActions templates.TplName = "repo/actions/list"
36-
tplViewActions templates.TplName = "repo/actions/view"
35+
tplListActions templates.TplName = "repo/actions/list"
36+
tplDispatchInputsActions templates.TplName = "repo/actions/workflow_dispatch_inputs"
37+
tplViewActions templates.TplName = "repo/actions/view"
3738
)
3839

3940
type Workflow struct {
@@ -62,6 +63,14 @@ func MustEnableActions(ctx *context.Context) {
6263
}
6364

6465
func List(ctx *context.Context) {
66+
renderListAndWorkflowDispatchTemplate(ctx, tplListActions, false)
67+
}
68+
69+
func WorkflowDispatchInputs(ctx *context.Context) {
70+
renderListAndWorkflowDispatchTemplate(ctx, tplDispatchInputsActions, true)
71+
}
72+
73+
func renderListAndWorkflowDispatchTemplate(ctx *context.Context, tplName templates.TplName, inputsOnly bool) {
6574
ctx.Data["Title"] = ctx.Tr("actions.actions")
6675
ctx.Data["PageIsActions"] = true
6776
workflowID := ctx.FormString("workflow")
@@ -75,10 +84,34 @@ func List(ctx *context.Context) {
7584
ctx.ServerError("IsEmpty", err)
7685
return
7786
} else if !empty {
78-
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
79-
if err != nil {
80-
ctx.ServerError("GetBranchCommit", err)
81-
return
87+
var commit *git.Commit
88+
if inputsOnly {
89+
ref := ctx.FormString("ref")
90+
if len(ref) == 0 {
91+
ctx.ServerError("ref", nil)
92+
return
93+
}
94+
// get target commit of run from specified ref
95+
refName := git.RefName(ref)
96+
var err error
97+
if refName.IsTag() {
98+
commit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName())
99+
} else if refName.IsBranch() {
100+
commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName())
101+
} else {
102+
ctx.ServerError("git_ref_name_error", nil)
103+
return
104+
}
105+
if err != nil {
106+
ctx.ServerError("target_ref_not_exist", err)
107+
return
108+
}
109+
} else {
110+
commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
111+
if err != nil {
112+
ctx.ServerError("GetBranchCommit", err)
113+
return
114+
}
82115
}
83116
entries, err := actions.ListWorkflows(commit)
84117
if err != nil {
@@ -207,65 +240,67 @@ func List(ctx *context.Context) {
207240
}
208241
}
209242

210-
// if status or actor query param is not given to frontend href, (href="/<repoLink>/actions")
211-
// they will be 0 by default, which indicates get all status or actors
212-
ctx.Data["CurActor"] = actorID
213-
ctx.Data["CurStatus"] = status
214-
if actorID > 0 || status > int(actions_model.StatusUnknown) {
215-
ctx.Data["IsFiltered"] = true
216-
}
243+
if !inputsOnly {
244+
// if status or actor query param is not given to frontend href, (href="/<repoLink>/actions")
245+
// they will be 0 by default, which indicates get all status or actors
246+
ctx.Data["CurActor"] = actorID
247+
ctx.Data["CurStatus"] = status
248+
if actorID > 0 || status > int(actions_model.StatusUnknown) {
249+
ctx.Data["IsFiltered"] = true
250+
}
217251

218-
opts := actions_model.FindRunOptions{
219-
ListOptions: db.ListOptions{
220-
Page: page,
221-
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
222-
},
223-
RepoID: ctx.Repo.Repository.ID,
224-
WorkflowID: workflowID,
225-
TriggerUserID: actorID,
226-
}
252+
opts := actions_model.FindRunOptions{
253+
ListOptions: db.ListOptions{
254+
Page: page,
255+
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
256+
},
257+
RepoID: ctx.Repo.Repository.ID,
258+
WorkflowID: workflowID,
259+
TriggerUserID: actorID,
260+
}
227261

228-
// if status is not StatusUnknown, it means user has selected a status filter
229-
if actions_model.Status(status) != actions_model.StatusUnknown {
230-
opts.Status = []actions_model.Status{actions_model.Status(status)}
231-
}
262+
// if status is not StatusUnknown, it means user has selected a status filter
263+
if actions_model.Status(status) != actions_model.StatusUnknown {
264+
opts.Status = []actions_model.Status{actions_model.Status(status)}
265+
}
232266

233-
runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts)
234-
if err != nil {
235-
ctx.ServerError("FindAndCount", err)
236-
return
237-
}
267+
runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts)
268+
if err != nil {
269+
ctx.ServerError("FindAndCount", err)
270+
return
271+
}
238272

239-
for _, run := range runs {
240-
run.Repo = ctx.Repo.Repository
241-
}
273+
for _, run := range runs {
274+
run.Repo = ctx.Repo.Repository
275+
}
242276

243-
if err := actions_model.RunList(runs).LoadTriggerUser(ctx); err != nil {
244-
ctx.ServerError("LoadTriggerUser", err)
245-
return
246-
}
277+
if err := actions_model.RunList(runs).LoadTriggerUser(ctx); err != nil {
278+
ctx.ServerError("LoadTriggerUser", err)
279+
return
280+
}
247281

248-
if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil {
249-
log.Error("LoadIsRefDeleted", err)
250-
}
282+
if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil {
283+
log.Error("LoadIsRefDeleted", err)
284+
}
251285

252-
ctx.Data["Runs"] = runs
286+
ctx.Data["Runs"] = runs
253287

254-
actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID)
255-
if err != nil {
256-
ctx.ServerError("GetActors", err)
257-
return
258-
}
259-
ctx.Data["Actors"] = shared_user.MakeSelfOnTop(ctx.Doer, actors)
288+
actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID)
289+
if err != nil {
290+
ctx.ServerError("GetActors", err)
291+
return
292+
}
293+
ctx.Data["Actors"] = shared_user.MakeSelfOnTop(ctx.Doer, actors)
260294

261-
ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
295+
ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
262296

263-
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
264-
pager.AddParamFromRequest(ctx.Req)
265-
ctx.Data["Page"] = pager
266-
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
297+
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
298+
pager.AddParamFromRequest(ctx.Req)
299+
ctx.Data["Page"] = pager
300+
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
301+
}
267302

268-
ctx.HTML(http.StatusOK, tplListActions)
303+
ctx.HTML(http.StatusOK, tplName)
269304
}
270305

271306
// loadIsRefDeleted loads the IsRefDeleted field for each run in the list.

routers/web/repo/actions/view.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -812,13 +812,8 @@ func Run(ctx *context_module.Context) {
812812
return
813813
}
814814

815-
// get workflow entry from default branch commit
816-
defaultBranchCommit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
817-
if err != nil {
818-
ctx.Error(http.StatusInternalServerError, err.Error())
819-
return
820-
}
821-
entries, err := actions.ListWorkflows(defaultBranchCommit)
815+
// get workflow entry from runTargetCommit
816+
entries, err := actions.ListWorkflows(runTargetCommit)
822817
if err != nil {
823818
ctx.Error(http.StatusInternalServerError, err.Error())
824819
return

routers/web/web.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,7 @@ func registerRoutes(m *web.Router) {
14121412
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
14131413
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
14141414
m.Post("/run", reqRepoActionsWriter, actions.Run)
1415+
m.Get("/dispatch-inputs", reqRepoActionsWriter, actions.WorkflowDispatchInputs)
14151416

14161417
m.Group("/runs/{run}", func() {
14171418
m.Combo("").

templates/repo/actions/workflow_dispatch.tmpl

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<label>{{ctx.Locale.Tr "actions.workflow.from_ref"}}:</label>
1212
</span>
1313
<div class="ui inline field dropdown button select-branch branch-selector-dropdown ellipsis-items-nowrap">
14-
<input type="hidden" name="ref" value="refs/heads/{{index .Branches 0}}">
14+
<input type="hidden" name="ref" hx-sync="this:replace" hx-target="#runWorkflowDispatchModalInputs" hx-swap="innerHTML" hx-get="{{$.Link}}/dispatch-inputs?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}" hx-trigger="change" value="refs/heads/{{index .Branches 0}}">
1515
{{svg "octicon-git-branch" 14}}
1616
<div class="default text">{{index .Branches 0}}</div>
1717
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
@@ -49,29 +49,10 @@
4949

5050
<div class="divider"></div>
5151

52-
{{range $item := .WorkflowDispatchConfig.Inputs}}
53-
<div class="ui field {{if .Required}}required{{end}}">
54-
{{if eq .Type "choice"}}
55-
<label>{{.Description}}:</label>
56-
<select class="ui selection type dropdown" name="{{.Name}}">
57-
{{range .Options}}
58-
<option value="{{.}}" {{if eq $item.Default .}}selected{{end}} >{{.}}</option>
59-
{{end}}
60-
</select>
61-
{{else if eq .Type "boolean"}}
62-
<div class="ui inline checkbox">
63-
<label>{{.Description}}</label>
64-
<input type="checkbox" name="{{.Name}}" {{if eq .Default "true"}}checked{{end}}>
65-
</div>
66-
{{else if eq .Type "number"}}
67-
<label>{{.Description}}:</label>
68-
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
69-
{{else}}
70-
<label>{{.Description}}:</label>
71-
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
72-
{{end}}
52+
<div id="runWorkflowDispatchModalInputs">
53+
{{template "repo/actions/workflow_dispatch_inputs" .}}
7354
</div>
74-
{{end}}
55+
7556
<button class="ui tiny primary button" type="submit">Submit</button>
7657
</form>
7758
</div>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{{range .workflows}}
2+
{{if and .ErrMsg (eq .Entry.Name $.CurWorkflow)}}
3+
<span data-tooltip-content="{{.ErrMsg}}">
4+
{{svg "octicon-alert" 16 "text red"}}
5+
</span>
6+
{{end}}
7+
{{end}}
8+
{{range $item := .WorkflowDispatchConfig.Inputs}}
9+
<div class="ui field {{if .Required}}required{{end}}">
10+
{{if eq .Type "choice"}}
11+
<label>{{Iif .Description .Description .Name}}:</label>
12+
<select class="ui selection type dropdown" name="{{.Name}}">
13+
{{range .Options}}
14+
<option value="{{.}}" {{if eq $item.Default .}}selected{{end}} >{{.}}</option>
15+
{{end}}
16+
</select>
17+
{{else if eq .Type "boolean"}}
18+
<div class="ui inline checkbox">
19+
<label>{{Iif .Description .Description .Name}}</label>
20+
<input type="checkbox" name="{{.Name}}" {{if eq .Default "true"}}checked{{end}}>
21+
</div>
22+
{{else if eq .Type "number"}}
23+
<label>{{Iif .Description .Description .Name}}:</label>
24+
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
25+
{{else}}
26+
<label>{{Iif .Description .Description .Name}}:</label>
27+
<input name="{{.Name}}" value="{{.Default}}" {{if .Required}}required{{end}}>
28+
{{end}}
29+
</div>
30+
{{end}}

0 commit comments

Comments
 (0)