feat(actions): implement adaptive auto-refresh for workflow runs list (#38329)

### Description
This PR implements an optimized, adaptive client-side auto-refresh
mechanism for the Gitea Actions workflow runs list page. It allows users
to see workflow progress updates dynamically without having to reload
the page.

Fixes https://github.com/go-gitea/gitea/issues/37457
---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Shudhanshu Singh
2026-07-12 12:14:37 +00:00
committed by GitHub
co-authored by wxiaoguang
parent 65c5a5ff7b
commit b998c3c1aa
9 changed files with 282 additions and 107 deletions
+4 -2
View File
@@ -1,7 +1,9 @@
{{$paginationParams := .Page.GetParams}}
{{$page := or $.Page ctx.RootData.Page}}
{{$paginationLink := $.Link}}
{{if eq $paginationLink nil}}{{$paginationLink = ctx.RootData.Link}}{{end}}
{{if eq $paginationLink AppSubUrl}}{{$paginationLink = print $paginationLink "/"}}{{end}}
{{with .Page.Paginater}}
{{$paginationParams := $page.GetParams}}
{{with $page.Paginater}}
{{if or (eq .TotalPages -1) (gt .TotalPages 1)}}
{{$showFirstLast := gt .TotalPages 1}}
<div class="center page buttons">
+4 -3
View File
@@ -14,14 +14,14 @@
<div class="ui fluid vertical menu">
<a class="item {{if not $.CurWorkflow}}active{{end}}" href="?actor={{$.CurActor}}&status={{$.CurStatus}}&branch={{$.CurBranch}}">{{ctx.Locale.Tr "actions.runs.all_workflows"}}</a>
{{range .workflows}}
<a class="item flex-text-block {{if and (eq .Entry.Name $.CurWorkflow) (not $.CurWorkflowScopedRepoID)}}active{{end}}" href="?workflow={{.Entry.Name}}&actor={{$.CurActor}}&status={{$.CurStatus}}&branch={{$.CurBranch}}">
<a class="item flex-text-block {{if and (eq .EntryName $.CurWorkflow) (not $.CurWorkflowScopedRepoID)}}active{{end}}" href="?workflow={{.EntryName}}&actor={{$.CurActor}}&status={{$.CurStatus}}&branch={{$.CurBranch}}">
<span class="gt-ellipsis" data-tooltip-content="{{.DisplayName}}">{{.DisplayName}}</span>
{{if .ErrMsg}}
<span class="flex-text-inline tw-shrink-0" data-tooltip-content="{{.ErrMsg}}">{{svg "octicon-alert" 16 "tw-text-red"}}</span>
{{end}}
{{if $.ActionsConfig.IsWorkflowDisabled .Entry.Name}}
{{if $.ActionsConfig.IsWorkflowDisabled .EntryName}}
<div class="ui red label tw-shrink-0">{{ctx.Locale.Tr "disabled"}}</div>
{{end}}
</a>
@@ -153,7 +153,8 @@
{{end}}
<div class="ui attached segment">
{{template "repo/actions/runs_list" .}}
{{template "repo/actions/runs_list" dict "ActionRunListData" $.ActionRunListData}}
{{template "base/paginate" dict "Page" $.Page}}
</div>
</div>
</div>
+16 -13
View File
@@ -1,12 +1,16 @@
<div class="flex-divided-list items-with-main run-list">
{{if not .Runs}}
{{$data := .ActionRunListData}}
<div class="flex-divided-list items-with-main run-list" data-global-init="initActionRunsList"
data-action-runs-refresh-link="{{$data.RefreshLink}}"
data-action-runs-refresh-interval="{{$data.RefreshIntervalMs}}"
>
{{if not $data.ActionRuns}}
<div class="empty-placeholder">
{{svg "octicon-no-entry" 48}}
<h2>{{if $.IsFiltered}}{{ctx.Locale.Tr "actions.runs.no_results"}}{{else}}{{ctx.Locale.Tr "actions.runs.no_runs"}}{{end}}</h2>
<h2>{{if $data.IsFiltered}}{{ctx.Locale.Tr "actions.runs.no_results"}}{{else}}{{ctx.Locale.Tr "actions.runs.no_runs"}}{{end}}</h2>
</div>
{{end}}
{{range $run := .Runs}}
<div class="item tw-items-center">
{{range $run := $data.ActionRuns}}
<div id="action-run-item-{{$run.ID}}" class="item tw-items-center" data-status="{{$run.Status.String}}">
<div class="item-leading">
<span data-tooltip-content="{{ctx.Locale.Tr (printf "actions.status.%s" $run.Status.String)}}">
{{template "repo/icons/action_status" (dict "Status" $run.Status.String "IconVariant" "circle-fill")}}
@@ -15,22 +19,22 @@
<div class="item-main">
<div class="item-title">
{{$title := or $run.Title (ctx.Locale.Tr "actions.runs.empty_commit_message")}}
{{ctx.RenderUtils.RenderCommitMessageLinkSubject $title $run.Link $.Repository}}
{{ctx.RenderUtils.RenderCommitMessageLinkSubject $title $run.Link $run.Repo}}
</div>
<div class="item-body">
{{$workflowName := index $.WorkflowNames $run.WorkflowID}}
<span><b>{{if not $.CurWorkflow}}{{if $workflowName}}{{$workflowName}}{{else}}{{$run.WorkflowID}}{{end}} {{end}}#{{$run.Index}}</b>:</span>
{{$workflowName := index $data.WorkflowNames $run.WorkflowID}}
<span><b>{{if not $data.CurWorkflow}}{{if $workflowName}}{{$workflowName}}{{else}}{{$run.WorkflowID}}{{end}} {{end}}#{{$run.Index}}</b>:</span>
{{- if $run.ScheduleID -}}
{{ctx.Locale.Tr "actions.runs.scheduled"}}
{{- else -}}
{{ctx.Locale.Tr "actions.runs.commit"}}
<a href="{{$.RepoLink}}/commit/{{$run.CommitSHA}}">{{ShortSha $run.CommitSHA}}</a>
<a href="{{$run.Repo.Link}}/commit/{{$run.CommitSHA}}">{{ShortSha $run.CommitSHA}}</a>
{{ctx.Locale.Tr "actions.runs.pushed_by"}}
<a href="{{$run.TriggerUser.HomeLink}}">{{$run.TriggerUser.GetDisplayName}}</a>
{{- end -}}
{{$errMsg := index $.RunErrors $run.ID}}
{{$errMsg := index $data.RunErrors $run.ID}}
{{if $errMsg}}
<span class="flex-text-inline" data-tooltip-content="{{$errMsg}}">
{{svg "octicon-alert" 16 "tw-text-red"}}
@@ -52,12 +56,12 @@
{{svg "octicon-kebab-horizontal"}}
<div class="menu flex-items-menu">
<a class="item" href="{{$run.Link}}/workflow">{{svg "octicon-play"}}{{ctx.Locale.Tr "actions.runs.view_workflow_file"}}</a>
{{if and $.CanWriteRepoUnitActions (not $run.Status.IsDone)}}
{{if and $data.CanWriteRepoUnitActions (not $run.Status.IsDone)}}
<a class="item link-action" data-url="{{$run.Link}}/cancel">
{{svg "octicon-x"}}{{ctx.Locale.Tr "actions.runs.cancel"}}
</a>
{{end}}
{{if and $.CanWriteRepoUnitActions $run.Status.IsDone}}
{{if and $data.CanWriteRepoUnitActions $run.Status.IsDone}}
<a class="item link-action"
data-url="{{$run.Link}}/delete"
data-modal-confirm="{{ctx.Locale.Tr "actions.runs.delete.description"}}"
@@ -71,4 +75,3 @@
</div>
{{end}}
</div>
{{template "base/paginate" .}}
@@ -37,7 +37,7 @@
</div>
{{end}}
{{range .workflows}}
{{if and .ErrMsg (eq .Entry.Name $.CurWorkflow)}}
{{if and .ErrMsg (eq .EntryName $.CurWorkflow)}}
<div class="ui field">
<div>{{svg "octicon-alert" 16 "tw-text-red"}} {{.ErrMsg}}</div>
</div>