diff --git a/pkg/cmd/run/list/list.go b/pkg/cmd/run/list/list.go index cf4e61586..bf9c84623 100644 --- a/pkg/cmd/run/list/list.go +++ b/pkg/cmd/run/list/list.go @@ -25,6 +25,7 @@ type ListOptions struct { BaseRepo func() (ghrepo.Interface, error) PlainOutput bool + Exporter cmdutil.Exporter Limit int WorkflowSelector string @@ -61,6 +62,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman cmd.Flags().IntVarP(&opts.Limit, "limit", "L", defaultLimit, "Maximum number of runs to fetch") cmd.Flags().StringVarP(&opts.WorkflowSelector, "workflow", "w", "", "Filter runs by workflow") + cmdutil.AddJSONFlags(cmd, &opts.Exporter, shared.RunFields) return cmd } @@ -96,6 +98,10 @@ func listRun(opts *ListOptions) error { return fmt.Errorf("failed to get runs: %w", err) } + if opts.Exporter != nil { + return opts.Exporter.Write(opts.IO, runs) + } + tp := utils.NewTablePrinter(opts.IO) cs := opts.IO.ColorScheme() diff --git a/pkg/cmd/run/shared/shared.go b/pkg/cmd/run/shared/shared.go index d58245cd9..4e104e2ce 100644 --- a/pkg/cmd/run/shared/shared.go +++ b/pkg/cmd/run/shared/shared.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "net/url" + "reflect" "strings" "time" @@ -42,6 +43,20 @@ type Status string type Conclusion string type Level string +var RunFields = []string{ + "name", + "headBranch", + "headSha", + "createdAt", + "updatedAt", + "status", + "conclusion", + "event", + "databaseId", + "workflowDatabaseId", + "url", +} + type Run struct { Name string CreatedAt time.Time `json:"created_at"` @@ -50,6 +65,7 @@ type Run struct { Conclusion Conclusion Event string ID int64 + WorkflowID int64 `json:"workflow_id"` HeadBranch string `json:"head_branch"` JobsURL string `json:"jobs_url"` HeadCommit Commit `json:"head_commit"` @@ -78,6 +94,30 @@ func (r Run) CommitMsg() string { } } +func (r *Run) ExportData(fields []string) map[string]interface{} { + v := reflect.ValueOf(r).Elem() + fieldByName := func(v reflect.Value, field string) reflect.Value { + return v.FieldByNameFunc(func(s string) bool { + return strings.EqualFold(field, s) + }) + } + data := map[string]interface{}{} + + for _, f := range fields { + switch f { + case "databaseId": + data[f] = r.ID + case "workflowDatabaseId": + data[f] = r.WorkflowID + default: + sf := fieldByName(v, f) + data[f] = sf.Interface() + } + } + + return data +} + type Job struct { ID int64 Status Status diff --git a/pkg/cmd/run/view/view.go b/pkg/cmd/run/view/view.go index 76191e211..dd8b30165 100644 --- a/pkg/cmd/run/view/view.go +++ b/pkg/cmd/run/view/view.go @@ -78,7 +78,8 @@ type ViewOptions struct { LogFailed bool Web bool - Prompt bool + Prompt bool + Exporter cmdutil.Exporter Now func() time.Time } @@ -155,6 +156,7 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman cmd.Flags().BoolVar(&opts.Log, "log", false, "View full log for either a run or specific job") cmd.Flags().BoolVar(&opts.LogFailed, "log-failed", false, "View the log for any failed steps in a run or specific job") cmd.Flags().BoolVarP(&opts.Web, "web", "w", false, "Open run in the browser") + cmdutil.AddJSONFlags(cmd, &opts.Exporter, shared.RunFields) return cmd } @@ -228,6 +230,10 @@ func runView(opts *ViewOptions) error { } } + if opts.Exporter != nil { + return opts.Exporter.Write(opts.IO, run) + } + if opts.Web { url := run.URL if selectedJob != nil {