Skip to content

Improve workflow count display #28278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions models/actions/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,34 @@ func UpdateRun(ctx context.Context, run *ActionRun, cols ...string) error {
}

type ActionRunIndex db.ResourceIndex

type WorkflowRunsStatus struct {
NumRuns int64
NumOpenRuns int64
NumClosedRuns int64
}

func GetRepoWorkflowRunsStatus(ctx context.Context, repoID int64, workflowID string) (wrs WorkflowRunsStatus, err error) {
wrs.NumRuns, err = db.Count[ActionRun](ctx, FindRunOptions{
RepoID: repoID,
WorkflowID: workflowID,
})
if err != nil {
return wrs, err
}
wrs.NumClosedRuns, err = db.Count[ActionRun](ctx, FindRunOptions{
RepoID: repoID,
WorkflowID: workflowID,
Status: []Status{
StatusSuccess,
StatusFailure,
StatusCancelled,
StatusSkipped,
},
})
if err != nil {
return wrs, err
}
wrs.NumOpenRuns = wrs.NumRuns - wrs.NumClosedRuns
return wrs, err
}
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3534,6 +3534,7 @@ runs.no_workflows.quick_start = Don't know how to start with Gitea Action? See <
runs.no_workflows.documentation = For more information on the Gitea Action, see <a target="_blank" rel="noopener noreferrer" href="%s">the documentation</a>.
runs.no_runs = The workflow has no runs yet.
runs.empty_commit_message = (empty commit message)
runs.status_count = %d workflow runs (%d open runs, %d closed runs)

workflow.disable = Disable Workflow
workflow.disable_success = Workflow '%s' disabled successfully.
Expand Down
50 changes: 43 additions & 7 deletions routers/web/repo/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,34 @@ const (
)

type Workflow struct {
Entry git.TreeEntry
ErrMsg string
Entry git.TreeEntry
RunsStatus actions_model.WorkflowRunsStatus
ErrMsg string
}
type WorkflowMap map[string]Workflow

func (wfs WorkflowMap) TotalRuns() int64 {
var total int64
for _, wf := range wfs {
total += wf.RunsStatus.NumRuns
}
return total
}

func (wfs WorkflowMap) TotalOpenRuns() int64 {
var total int64
for _, wf := range wfs {
total += wf.RunsStatus.NumOpenRuns
}
return total
}

func (wfs WorkflowMap) TotalClosedRuns() int64 {
var total int64
for _, wf := range wfs {
total += wf.RunsStatus.NumClosedRuns
}
return total
}

// MustEnableActions check if actions are enabled in settings
Expand All @@ -58,7 +84,7 @@ func List(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("actions.actions")
ctx.Data["PageIsActions"] = true

var workflows []Workflow
var workflows WorkflowMap
if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
Expand Down Expand Up @@ -88,9 +114,18 @@ func List(ctx *context.Context) {
allRunnerLabels.AddMultiple(r.AgentLabels...)
}

workflows = make([]Workflow, 0, len(entries))
workflows = make(WorkflowMap, 0)
for _, entry := range entries {
workflow := Workflow{Entry: *entry}
workflowID := entry.Name()

// Get workflow runs status
workflow.RunsStatus, err = actions_model.GetRepoWorkflowRunsStatus(ctx, ctx.Repo.Repository.ID, entry.Name())
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}

content, err := actions.GetContentFromEntry(entry)
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
Expand All @@ -99,9 +134,10 @@ func List(ctx *context.Context) {
wf, err := model.ReadWorkflow(bytes.NewReader(content))
if err != nil {
workflow.ErrMsg = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", err.Error())
workflows = append(workflows, workflow)
workflows[workflowID] = workflow
continue
}

// Check whether have matching runner
for _, j := range wf.Jobs {
runsOnList := j.RunsOn()
Expand All @@ -121,10 +157,10 @@ func List(ctx *context.Context) {
break
}
}
workflows = append(workflows, workflow)
workflows[workflowID] = workflow
}
}
ctx.Data["workflows"] = workflows
ctx.Data["Workflows"] = workflows
ctx.Data["RepoLink"] = ctx.Repo.Repository.Link()

page := ctx.FormInt("page")
Expand Down
118 changes: 68 additions & 50 deletions templates/repo/actions/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,95 @@
<div class="ui container">
{{template "base/alert" .}}

{{if .workflows}}
{{if .Workflows}}
<div class="ui stackable grid">
<div class="four wide column">
<div class="ui fluid vertical menu">
<a class="item{{if not $.CurWorkflow}} active{{end}}" href="{{$.Link}}?actor={{$.CurActor}}&status={{$.CurStatus}}">{{ctx.Locale.Tr "actions.runs.all_workflows"}}</a>
{{range .workflows}}
<a class="item{{if eq .Entry.Name $.CurWorkflow}} active{{end}}" href="{{$.Link}}?workflow={{.Entry.Name}}&actor={{$.CurActor}}&status={{$.CurStatus}}">{{.Entry.Name}}
<a class="item{{if not $.CurWorkflow}} active{{end}}" href="{{$.Link}}?actor={{$.CurActor}}&status={{$.CurStatus}}">{{ctx.Locale.Tr "actions.runs.all_workflows"}}
<span class="ui label">{{.Workflows.TotalOpenRuns}}</span>
</a>
{{range $workflowID, $workflow := .Workflows}}
<a class="item{{if eq $workflowID $.CurWorkflow}} active{{end}}" href="{{$.Link}}?workflow={{$workflowID}}&actor={{$.CurActor}}&status={{$.CurStatus}}">{{$workflowID}}
{{if .ErrMsg}}
<span data-tooltip-content="{{.ErrMsg}}">
{{svg "octicon-alert" 16 "text red"}}
</span>
{{end}}

{{if $.ActionsConfig.IsWorkflowDisabled .Entry.Name}}
{{if $.ActionsConfig.IsWorkflowDisabled $workflowID}}
<div class="ui red label">{{ctx.Locale.Tr "disabled"}}</div>
{{end}}

{{if $workflow.RunsStatus.NumOpenRuns}}
<span class="ui label">{{$workflow.RunsStatus.NumOpenRuns}}</span>
{{end}}
</a>
{{end}}
</div>
</div>
<div class="twelve wide column content">
<div class="ui secondary filter menu gt-je gt-df gt-ac">
<!-- Actor -->
<div class="ui{{if not .Actors}} disabled{{end}} dropdown jump item">
<span class="text">{{ctx.Locale.Tr "actions.runs.actor"}}</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-search"}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "actions.runs.actor"}}">
</div>
<a class="item{{if not $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&status={{$.CurStatus}}&actor=0">
{{ctx.Locale.Tr "actions.runs.actors_no_select"}}
</a>
{{range .Actors}}
<a class="item{{if eq .ID $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{.ID}}&status={{$.CurStatus}}">
{{ctx.AvatarUtils.Avatar . 20}} {{.GetDisplayName}}
</a>
{{end}}
</div>
<div class="issue-list-toolbar gt-mt-0 gt-mb-4">
<div class="issue-list-toolbar-left">
{{if .CurWorkflow}}
{{$curWorkflow := index .Workflows .CurWorkflow}}
{{ctx.Locale.Tr "actions.runs.status_count" $curWorkflow.RunsStatus.NumRuns $curWorkflow.RunsStatus.NumOpenRuns $curWorkflow.RunsStatus.NumClosedRuns}}
{{else}}
{{ctx.Locale.Tr "actions.runs.status_count" .Workflows.TotalRuns .Workflows.TotalOpenRuns .Workflows.TotalClosedRuns}}
{{end}}
</div>
<!-- Status -->
<div class="ui dropdown jump item">
<span class="text">{{ctx.Locale.Tr "actions.runs.status"}}</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-search"}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "actions.runs.status"}}">
<div class="issue-list-toolbar-right">
<div class="ui secondary filter menu labels">
<!-- Actor -->
<div class="ui{{if not .Actors}} disabled{{end}} dropdown jump item">
<span class="text">{{ctx.Locale.Tr "actions.runs.actor"}}</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-search"}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "actions.runs.actor"}}">
</div>
<a class="item{{if not $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&status={{$.CurStatus}}&actor=0">
{{ctx.Locale.Tr "actions.runs.actors_no_select"}}
</a>
{{range .Actors}}
<a class="item{{if eq .ID $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{.ID}}&status={{$.CurStatus}}">
{{ctx.AvatarUtils.Avatar . 20}} {{.GetDisplayName}}
</a>
{{end}}
</div>
</div>
<a class="item{{if not $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status=0">
{{ctx.Locale.Tr "actions.runs.status_no_select"}}
</a>
{{range .StatusInfoList}}
<a class="item{{if eq .Status $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}">
{{.DisplayedStatus}}
</a>
<!-- Status -->
<div class="ui dropdown jump item">
<span class="text">{{ctx.Locale.Tr "actions.runs.status"}}</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-search"}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "actions.runs.status"}}">
</div>
<a class="item{{if not $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status=0">
{{ctx.Locale.Tr "actions.runs.status_no_select"}}
</a>
{{range .StatusInfoList}}
<a class="item{{if eq .Status $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}">
{{.DisplayedStatus}}
</a>
{{end}}
</div>
</div>

{{if .AllowDisableOrEnableWorkflow}}
<button class="ui jump dropdown btn interact-bg gt-p-3">
{{svg "octicon-kebab-horizontal"}}
<div class="menu">
<a class="item link-action" data-url="{{$.Link}}/{{if .CurWorkflowDisabled}}enable{{else}}disable{{end}}?workflow={{$.CurWorkflow}}&actor={{.CurActor}}&status={{$.CurStatus}}">
{{if .CurWorkflowDisabled}}{{ctx.Locale.Tr "actions.workflow.enable"}}{{else}}{{ctx.Locale.Tr "actions.workflow.disable"}}{{end}}
</a>
</div>
</button>
{{end}}
</div>
</div>

{{if .AllowDisableOrEnableWorkflow}}
<button class="ui jump dropdown btn interact-bg gt-p-3">
{{svg "octicon-kebab-horizontal"}}
<div class="menu">
<a class="item link-action" data-url="{{$.Link}}/{{if .CurWorkflowDisabled}}enable{{else}}disable{{end}}?workflow={{$.CurWorkflow}}&actor={{.CurActor}}&status={{$.CurStatus}}">
{{if .CurWorkflowDisabled}}{{ctx.Locale.Tr "actions.workflow.enable"}}{{else}}{{ctx.Locale.Tr "actions.workflow.disable"}}{{end}}
</a>
</div>
</button>
{{end}}
</div>
{{template "repo/actions/runs_list" .}}
</div>
Expand Down