Fetch all jobs on a gh view run --json

This commit is contained in:
Harvey Sanders 2023-08-21 10:29:58 -04:00
parent bb42fa07aa
commit 44e1efc221
3 changed files with 81 additions and 4 deletions

View file

@ -424,7 +424,8 @@ func preloadWorkflowNames(client *api.Client, repo ghrepo.Interface, runs []Run)
}
type JobsPayload struct {
Jobs []Job
TotalCount int `json:"total_count"`
Jobs []Job
}
func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run) ([]Job, error) {
@ -432,10 +433,23 @@ func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run) ([]Job, error)
return run.Jobs, nil
}
var result JobsPayload
if err := client.REST(repo.RepoHost(), "GET", run.JobsURL, nil, &result); err != nil {
return nil, err
perPage := 100
v := url.Values{}
v.Set("per_page", fmt.Sprintf("%d", perPage))
// Fetch all the pages until total fetched jobs == result.TotalCount
maxPages := 10
for p := 1; p < maxPages; p++ {
v.Set("page", fmt.Sprintf("%d", p))
jobsPath := fmt.Sprintf("%s?%s", run.JobsURL, v.Encode())
if err := client.REST(repo.RepoHost(), "GET", jobsPath, nil, &result); err != nil {
return run.Jobs, err
}
run.Jobs = append(run.Jobs, result.Jobs...)
if len(run.Jobs) >= result.TotalCount {
break
}
}
run.Jobs = result.Jobs
return result.Jobs, nil
}

View file

@ -5,6 +5,7 @@ import (
"time"
workflowShared "github.com/cli/cli/v2/pkg/cmd/workflow/shared"
"github.com/cli/cli/v2/pkg/iostreams"
)
var TestRunStartTime, _ = time.Parse("2006-01-02 15:04:05", "2021-02-23 04:51:00")
@ -122,3 +123,20 @@ var TestWorkflow workflowShared.Workflow = workflowShared.Workflow{
Name: "CI",
ID: 123,
}
type TestExporter struct {
fields []string
writeHandler func(io *iostreams.IOStreams, data interface{}) error
}
func MakeTestExporter(fields []string, wh func(io *iostreams.IOStreams, data interface{}) error) *TestExporter {
return &TestExporter{fields: fields, writeHandler: wh}
}
func (t *TestExporter) Fields() []string {
return t.fields
}
func (t *TestExporter) Write(io *iostreams.IOStreams, data interface{}) error {
return t.writeHandler(io, data)
}

View file

@ -1242,6 +1242,51 @@ func TestViewRun(t *testing.T) {
},
wantOut: "\nX trunk CI · 123\nTriggered via push about 59 minutes ago\n\nX This run likely failed because of a workflow file issue.\n\nFor more information, see: https://github.com/runs/123\n",
},
{
name: "Fetches all of a run's jobs with --json flag",
opts: &ViewOptions{
RunID: "3",
Exporter: shared.MakeTestExporter(
[]string{"jobs"},
func(io *iostreams.IOStreams, data interface{}) error {
run, ok := data.(*shared.Run)
if !ok {
return fmt.Errorf("expected data type *shared.Run")
}
fmt.Fprintf(io.Out, "fetched %d jobs\n", len(run.Jobs))
return nil
},
),
},
httpStubs: func(reg *httpmock.Registry) {
jobs := []shared.Job{}
for i := 0; i < 115; i++ {
jobs = append(jobs, shared.Job{
ID: int64(i),
Name: fmt.Sprintf("job %d", i),
})
}
limit := 100
firstPage := jobs[:limit]
secondPage := jobs[limit:]
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/3"),
httpmock.JSONResponse(shared.SuccessfulRun))
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows/123"),
httpmock.JSONResponse(shared.TestWorkflow))
reg.Register(
httpmock.REST("GET", "runs/3/jobs"),
httpmock.JSONResponse(shared.JobsPayload{TotalCount: len(jobs), Jobs: firstPage}))
// /runs/:runID/jobs endpoint should be called once more to fetch the remaining jobs
reg.Register(
httpmock.REST("GET", "runs/3/jobs"),
httpmock.JSONResponse(shared.JobsPayload{TotalCount: len(jobs), Jobs: secondPage}))
},
wantOut: "fetched 115 jobs\n",
},
}
for _, tt := range tests {