Add jobs field for run view --json (#6507)

Co-authored-by: Mislav Marohnić <mislav@github.com>
This commit is contained in:
Natthakit Susanthitanon 2022-11-03 19:59:35 +07:00 committed by GitHub
parent b94d07347f
commit 8617eb7df9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 12 deletions

View file

@ -62,6 +62,8 @@ var RunFields = []string{
"url",
}
var SingleRunFields = append(RunFields, "jobs")
type Run struct {
Name string `json:"name"` // the semantics of this field are unclear
DisplayTitle string `json:"display_title"`
@ -82,6 +84,7 @@ type Run struct {
HeadSha string `json:"head_sha"`
URL string `json:"html_url"`
HeadRepository Repo `json:"head_repository"`
Jobs []Job `json:"-"` // populated by GetJobs
}
func (r *Run) StartedTime() time.Time {
@ -151,6 +154,34 @@ func (r *Run) ExportData(fields []string) map[string]interface{} {
data[f] = r.WorkflowID
case "workflowName":
data[f] = r.WorkflowName()
case "jobs":
jobs := make([]interface{}, 0, len(r.Jobs))
for _, j := range r.Jobs {
steps := make([]interface{}, 0, len(j.Steps))
for _, s := range j.Steps {
steps = append(steps, map[string]interface{}{
"name": s.Name,
"status": s.Status,
"conclusion": s.Conclusion,
"number": s.Number,
})
}
var completedAt *time.Time
if !j.CompletedAt.IsZero() {
completedAt = &j.CompletedAt
}
jobs = append(jobs, map[string]interface{}{
"databaseId": j.ID,
"status": j.Status,
"conclusion": j.Conclusion,
"name": j.Name,
"steps": steps,
"startedAt": j.StartedAt,
"completedAt": completedAt,
"url": j.URL,
})
data[f] = jobs
}
default:
sf := fieldByName(v, f)
data[f] = sf.Interface()
@ -286,6 +317,7 @@ func GetRuns(client *api.Client, repo ghrepo.Interface, opts *FilterOptions, lim
perPage = 100
}
path += fmt.Sprintf("?per_page=%d", perPage)
path += "&exclude_pull_requests=true" // significantly reduces payload size
if opts != nil {
if opts.Branch != "" {
@ -364,11 +396,15 @@ type JobsPayload struct {
Jobs []Job
}
func GetJobs(client *api.Client, repo ghrepo.Interface, run Run) ([]Job, error) {
func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run) ([]Job, error) {
if run.Jobs != nil {
return run.Jobs, nil
}
var result JobsPayload
if err := client.REST(repo.RepoHost(), "GET", run.JobsURL, nil, &result); err != nil {
return nil, err
}
run.Jobs = result.Jobs
return result.Jobs, nil
}
@ -416,7 +452,7 @@ func PromptForRun(cs *iostreams.ColorScheme, runs []Run) (string, error) {
func GetRun(client *api.Client, repo ghrepo.Interface, runID string) (*Run, error) {
var result Run
path := fmt.Sprintf("repos/%s/actions/runs/%s", ghrepo.FullName(repo), runID)
path := fmt.Sprintf("repos/%s/actions/runs/%s?exclude_pull_requests=true", ghrepo.FullName(repo), runID)
err := client.REST(repo.RepoHost(), "GET", path, nil, &result)
if err != nil {

View file

@ -153,7 +153,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)
cmdutil.AddJSONFlags(cmd, &opts.Exporter, shared.SingleRunFields)
return cmd
}
@ -212,18 +212,19 @@ func runView(opts *ViewOptions) error {
return fmt.Errorf("failed to get run: %w", err)
}
if opts.Prompt {
if shouldFetchJobs(opts) {
opts.IO.StartProgressIndicator()
jobs, err = shared.GetJobs(client, repo, *run)
jobs, err = shared.GetJobs(client, repo, run)
opts.IO.StopProgressIndicator()
if err != nil {
return err
}
if len(jobs) > 1 {
selectedJob, err = promptForJob(cs, jobs)
if err != nil {
return err
}
}
if opts.Prompt && len(jobs) > 1 {
selectedJob, err = promptForJob(cs, jobs)
if err != nil {
return err
}
}
@ -251,7 +252,7 @@ func runView(opts *ViewOptions) error {
if selectedJob == nil && len(jobs) == 0 {
opts.IO.StartProgressIndicator()
jobs, err = shared.GetJobs(client, repo, *run)
jobs, err = shared.GetJobs(client, repo, run)
opts.IO.StopProgressIndicator()
if err != nil {
return fmt.Errorf("failed to get jobs: %w", err)
@ -390,6 +391,20 @@ func runView(opts *ViewOptions) error {
return nil
}
func shouldFetchJobs(opts *ViewOptions) bool {
if opts.Prompt {
return true
}
if opts.Exporter != nil {
for _, f := range opts.Exporter.Fields() {
if f == "jobs" {
return true
}
}
}
return false
}
func getLog(httpClient *http.Client, logURL string) (io.ReadCloser, error) {
req, err := http.NewRequest("GET", logURL, nil)
if err != nil {

View file

@ -206,7 +206,7 @@ func renderRun(out io.Writer, opts WatchOptions, client *api.Client, repo ghrepo
return nil, fmt.Errorf("failed to get run: %w", err)
}
jobs, err := shared.GetJobs(client, repo, *run)
jobs, err := shared.GetJobs(client, repo, run)
if err != nil {
return nil, fmt.Errorf("failed to get jobs: %w", err)
}