diff --git a/README.md b/README.md index 21cd81f..dd25d93 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/internal/i18n/locales/en-US.json b/internal/i18n/locales/en-US.json index e255878..8a6510e 100644 --- a/internal/i18n/locales/en-US.json +++ b/internal/i18n/locales/en-US.json @@ -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", diff --git a/internal/i18n/locales/zh-CN.json b/internal/i18n/locales/zh-CN.json index e3c7a5b..328db62 100644 --- a/internal/i18n/locales/zh-CN.json +++ b/internal/i18n/locales/zh-CN.json @@ -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": "列出工作流的运行记录", diff --git a/shortcuts/action/action.go b/shortcuts/action/action.go index 53dfc21..9b8b26a 100644 --- a/shortcuts/action/action.go +++ b/shortcuts/action/action.go @@ -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"), diff --git a/shortcuts/action/action_test.go b/shortcuts/action/action_test.go index 1d5813d..a17032b 100644 --- a/shortcuts/action/action_test.go +++ b/shortcuts/action/action_test.go @@ -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") + } +}