新增:重新运行及查看日志接口

This commit is contained in:
yystopf 2024-05-28 09:02:01 +08:00
parent 8ad0cd1cf0
commit 8964eff31b
2 changed files with 117 additions and 1 deletions

View File

@ -128,7 +128,10 @@ func Routers() *web.Route {
m.Post("/disable", reqAdmin(), actions.DisableWorkflowFile)
m.Post("/enable", reqAdmin(), actions.EnableWorkflowFile)
m.Post("/runs/{run}/jobs/{job}", context.ReferencesGitRepo(), bind(actions.ViewRequest{}), actions.ListJobs)
})
m.Post("/runs/{run}/jobs/{job}/rerun", reqRepoWriter(unit_model.TypeActions), actions.Rerun)
m.Get("/runs/{run}/jobs/{job}/logs", actions.Logs)
m.Post("/runs/{run}/rerun", reqRepoWriter(unit_model.TypeActions), actions.Rerun)
}, reqRepoReader(unit_model.TypeActions))
m.Post("/transfer", reqOwner(), bind(gitea_api.TransferRepoOption{}), repo.Transfer)
m.Get("/branch_name_set", context.ReferencesGitRepo(), repo.BranchNameSet)
m.Get("/tag_name_set", context.ReferencesGitRepo(), repo.TagNameSet)

View File

@ -8,6 +8,8 @@ import (
"strings"
"time"
stdCtx "context"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
@ -16,12 +18,15 @@ import (
"code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/web/repo"
actions_service "code.gitea.io/gitea/services/actions"
"code.gitea.io/gitea/services/convert"
"github.com/nektos/act/pkg/model"
"xorm.io/builder"
)
type Workflow struct {
@ -394,6 +399,114 @@ func ListJobs(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, resp)
}
func Rerun(ctx *context.APIContext) {
runIndex := ctx.ParamsInt64("run")
jobIndex := ctx.ParamsInt64("job")
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetRunByIndex", err.Error())
return
}
// can not rerun job when workflow is disabled
cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions)
cfg := cfgUnit.ActionsConfig()
if cfg.IsWorkflowDisabled(run.WorkflowID) {
ctx.Error(http.StatusInternalServerError, "IsWorkflowDisabled", ctx.Locale.Tr("actions.workflow.disabled"))
return
}
job, jobs := getRunJobs(ctx, runIndex, jobIndex)
if ctx.Written() {
return
}
if jobIndex != 0 {
jobs = []*actions_model.ActionRunJob{job}
}
for _, j := range jobs {
if err := rerunJob(ctx, j); err != nil {
ctx.Error(http.StatusInternalServerError, "rerunJob", err.Error())
return
}
}
ctx.Status(http.StatusNoContent)
}
func rerunJob(ctx *context.APIContext, job *actions_model.ActionRunJob) error {
status := job.Status
if !status.IsDone() {
return nil
}
job.TaskID = 0
job.Status = actions_model.StatusWaiting
job.Started = 0
job.Stopped = 0
if err := db.WithTx(ctx, func(ctx stdCtx.Context) error {
_, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
return err
}); err != nil {
return err
}
actions_service.CreateCommitStatus(ctx, job)
return nil
}
func Logs(ctx *context.APIContext) {
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, "LoadRun", err.Error())
return
}
task, err := actions_model.GetTaskByID(ctx, job.TaskID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetTaskByID", 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, "OpenLogs", 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.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 getRunJobs(ctx *context.APIContext, runIndex, jobIndex int64) (*actions_model.ActionRunJob, []*actions_model.ActionRunJob) {
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
if err != nil {