feat(action): add +logs for raw workflow job logs
Wraps GET /actions/runs/:run_id/jobs/:job/logs (runs#job_logs, which redirects to the log file). Non-JSON body is printed as-is so the output pipes cleanly into grep/less. Production-verified on gitlink.org.cn (real run's job log streamed). Unit test covers the nested path and the --run-id integer guard. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
05a1859c63
commit
a31c53484e
|
|
@ -502,6 +502,9 @@ gitlink-cli action +run --owner Gitlink --repo forgeplus -w ci.yml -r master
|
|||
gitlink-cli action +rerun --owner Gitlink --repo forgeplus -i 6
|
||||
gitlink-cli action +job-rerun --owner Gitlink --repo forgeplus -i 6 -j build
|
||||
|
||||
# Raw logs of a workflow job
|
||||
gitlink-cli action +logs --owner Gitlink --repo forgeplus -i 6 -j 0
|
||||
|
||||
# Enable or disable a workflow
|
||||
gitlink-cli action +disable --owner Gitlink --repo forgeplus -w ci.yml
|
||||
gitlink-cli action +enable --owner Gitlink --repo forgeplus -w ci.yml
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"cmd.action.enable.short": "Enable Actions for the repository",
|
||||
"cmd.action.job_rerun.short": "Rerun a single job of a run",
|
||||
"cmd.action.list.short": "List workflow files (.gitea/workflows)",
|
||||
"cmd.action.logs.short": "Fetch the raw logs of a workflow job",
|
||||
"cmd.action.rerun.short": "Rerun all jobs of a run",
|
||||
"cmd.action.run.short": "Trigger a workflow run",
|
||||
"cmd.action.runs.short": "List runs of a workflow",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"cmd.action.enable.short": "为仓库启用 Actions",
|
||||
"cmd.action.job_rerun.short": "重跑运行中的单个任务",
|
||||
"cmd.action.list.short": "列出工作流文件(.gitea/workflows)",
|
||||
"cmd.action.logs.short": "获取流水线任务的原始日志",
|
||||
"cmd.action.rerun.short": "重跑一次运行的全部任务",
|
||||
"cmd.action.run.short": "触发一次工作流运行",
|
||||
"cmd.action.runs.short": "列出工作流的运行记录",
|
||||
|
|
|
|||
|
|
@ -146,6 +146,36 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut {
|
|||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "logs",
|
||||
Description: tr.T("cmd.action.logs.short"),
|
||||
Flags: []common.Flag{
|
||||
{Name: "run-id", Short: "i", Usage: tr.T("flag.action.run_id"), Required: true},
|
||||
{Name: "job", Short: "j", Usage: tr.T("flag.action.job"), Required: true},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
runID, err := requireIntArg(ctx, "run-id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
job, err := ctx.RequireArg("job")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env, err := ctx.CallAPI("GET", fmt.Sprintf("%s/runs/%s/jobs/%s/logs", actionsPath(ctx), runID, url.PathEscape(job)), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if text, ok := env.Data.(string); ok {
|
||||
fmt.Print(text)
|
||||
return nil
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "enable",
|
||||
Description: tr.T("cmd.action.enable.short"),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package action
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
|
|
@ -157,3 +158,22 @@ func TestActionEnableDisableEndpoints(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionLogsBuildsNestedLogsPath(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" || r.URL.Path != "/v1/owner/repo/actions/runs/6/jobs/0/logs.json" {
|
||||
t.Fatalf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
fmt.Fprint(w, "log line 1\nlog line 2\n")
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
if err := runShortcut(t, server, "logs", map[string]string{"run-id": "6", "job": "0"}); err != nil {
|
||||
t.Fatalf("logs failed: %v", err)
|
||||
}
|
||||
|
||||
if err := runShortcut(t, server, "logs", map[string]string{"run-id": "abc", "job": "0"}); err == nil {
|
||||
t.Fatal("expected error for non-integer --run-id")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue