Skip to content

Commit 39f8227

Browse files
authored
Merge pull request #431 from depot/luke/jj-tqurkrplwmqz
feat: `status` and `logs` commands
2 parents 16863ed + c120a5e commit 39f8227

File tree

7 files changed

+1412
-0
lines changed

7 files changed

+1412
-0
lines changed

pkg/api/ci.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,43 @@ import (
1111

1212
var baseURLFunc = getBaseURL
1313

14+
func newCIServiceClient() civ1connect.CIServiceClient {
15+
baseURL := baseURLFunc()
16+
return civ1connect.NewCIServiceClient(getHTTPClient(baseURL), baseURL, WithUserAgent())
17+
}
18+
19+
// CIGetRunStatus returns the current status of a CI run including its workflows, jobs, and attempts.
20+
func CIGetRunStatus(ctx context.Context, token, runID string) (*civ1.GetRunStatusResponse, error) {
21+
client := newCIServiceClient()
22+
resp, err := client.GetRunStatus(ctx, WithAuthentication(connect.NewRequest(&civ1.GetRunStatusRequest{RunId: runID}), token))
23+
if err != nil {
24+
return nil, err
25+
}
26+
return resp.Msg, nil
27+
}
28+
29+
// CIGetJobAttemptLogs returns all log lines for a job attempt, paginating through all pages.
30+
func CIGetJobAttemptLogs(ctx context.Context, token, attemptID string) ([]*civ1.LogLine, error) {
31+
client := newCIServiceClient()
32+
var allLines []*civ1.LogLine
33+
var pageToken string
34+
35+
for {
36+
req := &civ1.GetJobAttemptLogsRequest{AttemptId: attemptID, PageToken: pageToken}
37+
resp, err := client.GetJobAttemptLogs(ctx, WithAuthentication(connect.NewRequest(req), token))
38+
if err != nil {
39+
return nil, err
40+
}
41+
allLines = append(allLines, resp.Msg.Lines...)
42+
if resp.Msg.NextPageToken == "" {
43+
break
44+
}
45+
pageToken = resp.Msg.NextPageToken
46+
}
47+
48+
return allLines, nil
49+
}
50+
1451
func newCISecretServiceClient() civ1connect.SecretServiceClient {
1552
baseURL := baseURLFunc()
1653
return civ1connect.NewSecretServiceClient(getHTTPClient(baseURL), baseURL, WithUserAgent())

pkg/cmd/ci/ci.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ func NewCmdCI() *cobra.Command {
1212
},
1313
}
1414

15+
cmd.AddCommand(NewCmdLogs())
1516
cmd.AddCommand(NewCmdMigrate())
1617
cmd.AddCommand(NewCmdSecrets())
18+
cmd.AddCommand(NewCmdStatus())
1719
cmd.AddCommand(NewCmdVars())
1820

1921
return cmd

pkg/cmd/ci/logs.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package ci
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/depot/cli/pkg/api"
7+
"github.com/depot/cli/pkg/helpers"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
func NewCmdLogs() *cobra.Command {
12+
var token string
13+
14+
cmd := &cobra.Command{
15+
Use: "logs <attempt-id>",
16+
Short: "Fetch logs for a CI job attempt [beta]",
17+
Long: "Fetch and display log output for a CI job attempt.\n\nThis command is in beta and subject to change.",
18+
RunE: func(cmd *cobra.Command, args []string) error {
19+
if len(args) == 0 {
20+
return cmd.Help()
21+
}
22+
23+
ctx := cmd.Context()
24+
attemptID := args[0]
25+
26+
tokenVal, err := helpers.ResolveOrgAuth(ctx, token)
27+
if err != nil {
28+
return err
29+
}
30+
if tokenVal == "" {
31+
return fmt.Errorf("missing API token, please run `depot login`")
32+
}
33+
34+
lines, err := api.CIGetJobAttemptLogs(ctx, tokenVal, attemptID)
35+
if err != nil {
36+
return fmt.Errorf("failed to get job attempt logs: %w", err)
37+
}
38+
39+
for _, line := range lines {
40+
fmt.Println(line.Body)
41+
}
42+
43+
return nil
44+
},
45+
}
46+
47+
cmd.Flags().StringVar(&token, "token", "", "Depot API token")
48+
49+
return cmd
50+
}

pkg/cmd/ci/status.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package ci
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/depot/cli/pkg/api"
7+
"github.com/depot/cli/pkg/helpers"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
func NewCmdStatus() *cobra.Command {
12+
var token string
13+
14+
cmd := &cobra.Command{
15+
Use: "status <run-id>",
16+
Short: "Look up the status of a CI run [beta]",
17+
Long: "Look up the status of a CI run, including its workflows, jobs, and attempts.\n\nThis command is in beta and subject to change.",
18+
RunE: func(cmd *cobra.Command, args []string) error {
19+
if len(args) == 0 {
20+
return cmd.Help()
21+
}
22+
23+
ctx := cmd.Context()
24+
runID := args[0]
25+
26+
tokenVal, err := helpers.ResolveOrgAuth(ctx, token)
27+
if err != nil {
28+
return err
29+
}
30+
if tokenVal == "" {
31+
return fmt.Errorf("missing API token, please run `depot login`")
32+
}
33+
34+
resp, err := api.CIGetRunStatus(ctx, tokenVal, runID)
35+
if err != nil {
36+
return fmt.Errorf("failed to get run status: %w", err)
37+
}
38+
39+
fmt.Printf("Org: %s\n", resp.OrgId)
40+
fmt.Printf("Run: %s (%s)\n", resp.RunId, resp.Status)
41+
42+
for _, workflow := range resp.Workflows {
43+
fmt.Println()
44+
fmt.Printf(" Workflow: %s (%s)\n", workflow.WorkflowId, workflow.Status)
45+
if workflow.WorkflowPath != "" {
46+
fmt.Printf(" Path: %s\n", workflow.WorkflowPath)
47+
}
48+
49+
for _, job := range workflow.Jobs {
50+
fmt.Printf(" Job: %s [%s] (%s)\n", job.JobId, job.JobKey, job.Status)
51+
52+
for _, attempt := range job.Attempts {
53+
fmt.Printf(" Attempt: %s #%d (%s)\n", attempt.AttemptId, attempt.Attempt, attempt.Status)
54+
}
55+
}
56+
}
57+
58+
return nil
59+
},
60+
}
61+
62+
cmd.Flags().StringVar(&token, "token", "", "Depot API token")
63+
64+
return cmd
65+
}

0 commit comments

Comments
 (0)