diff --git a/modules/actions/log.go b/modules/actions/log.go
index 36bed931fadf..cdf18646aaf0 100644
--- a/modules/actions/log.go
+++ b/modules/actions/log.go
@@ -73,7 +73,7 @@ func WriteLogs(ctx context.Context, filename string, offset int64, rows []*runne
}
func ReadLogs(ctx context.Context, inStorage bool, filename string, offset, limit int64) ([]*runnerv1.LogRow, error) {
- f, err := openLogs(ctx, inStorage, filename)
+ f, err := OpenLogs(ctx, inStorage, filename)
if err != nil {
return nil, err
}
@@ -141,7 +141,7 @@ func RemoveLogs(ctx context.Context, inStorage bool, filename string) error {
return nil
}
-func openLogs(ctx context.Context, inStorage bool, filename string) (io.ReadSeekCloser, error) {
+func OpenLogs(ctx context.Context, inStorage bool, filename string) (io.ReadSeekCloser, error) {
if !inStorage {
name := DBFSPrefix + filename
f, err := dbfs.Open(ctx, name)
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 6de025805115..be90e5366cc9 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -129,6 +129,7 @@ concept_user_organization = Organization
show_timestamps = Show timestamps
show_log_seconds = Show seconds
show_full_screen = Show full screen
+download_logs = Download logs
confirm_delete_selected = Confirm to delete all selected items?
diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go
index 7c2e9d63d6d3..537bc618075c 100644
--- a/routers/web/repo/actions/view.go
+++ b/routers/web/repo/actions/view.go
@@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"net/http"
+ "strings"
"time"
actions_model "code.gitea.io/gitea/models/actions"
@@ -310,6 +311,55 @@ func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob) erro
return nil
}
+func Logs(ctx *context_module.Context) {
+ runIndex := ctx.ParamsInt64("run")
+ jobIndex := ctx.ParamsInt64("job")
+
+ job, _ := getRunJobs(ctx, runIndex, jobIndex)
+ if ctx.Written() {
+ return
+ }
+ if job.TaskID == 0 {
+ ctx.Error(http.StatusNotFound, "job is not started")
+ return
+ }
+
+ err := job.LoadRun(ctx)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
+
+ task, err := actions_model.GetTaskByID(ctx, job.TaskID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
+ if task.LogExpired {
+ ctx.Error(http.StatusNotFound, "logs have been cleaned up")
+ return
+ }
+
+ reader, err := actions.OpenLogs(ctx, task.LogInStorage, task.LogFilename)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
+ defer reader.Close()
+
+ workflowName := job.Run.WorkflowID
+ if p := strings.Index(workflowName, "."); p > 0 {
+ workflowName = workflowName[0:p]
+ }
+ ctx.ServeContent(reader, &context_module.ServeHeaderOptions{
+ Filename: fmt.Sprintf("%v-%v-%v.log", workflowName, job.Name, task.ID),
+ ContentLength: &task.LogSize,
+ ContentType: "text/plain",
+ ContentTypeCharset: "utf-8",
+ Disposition: "attachment",
+ })
+}
+
func Cancel(ctx *context_module.Context) {
runIndex := ctx.ParamsInt64("run")
diff --git a/routers/web/web.go b/routers/web/web.go
index 26ad2d54c3a3..a5465eb0419f 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1207,6 +1207,7 @@ func registerRoutes(m *web.Route) {
Get(actions.View).
Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
m.Post("/rerun", reqRepoActionsWriter, actions.RerunOne)
+ m.Get("/logs", actions.Logs)
})
m.Post("/cancel", reqRepoActionsWriter, actions.Cancel)
m.Post("/approve", reqRepoActionsWriter, actions.Approve)
diff --git a/templates/repo/actions/view.tmpl b/templates/repo/actions/view.tmpl
index 297232fca0c5..7b07aa155b57 100644
--- a/templates/repo/actions/view.tmpl
+++ b/templates/repo/actions/view.tmpl
@@ -22,6 +22,7 @@
data-locale-show-timestamps="{{.locale.Tr "show_timestamps"}}"
data-locale-show-log-seconds="{{.locale.Tr "show_log_seconds"}}"
data-locale-show-full-screen="{{.locale.Tr "show_full_screen"}}"
+ data-locale-download-logs="{{.locale.Tr "download_logs"}}"
>
diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue
index dcbb59805285..7c65d5a131c2 100644
--- a/web_src/js/components/RepoActionView.vue
+++ b/web_src/js/components/RepoActionView.vue
@@ -74,6 +74,10 @@