MCPcopy Create free account
hub / github.com/github/gh-aw / fetchJobDetailsWithCounts

Function fetchJobDetailsWithCounts

pkg/cli/logs_github_api.go:79–128  ·  view source on GitHub ↗

fetchJobDetailsWithCounts fetches all job information for a workflow run in a single API call and returns the full detail slice together with the count of failed jobs. It is the single source of truth for the jobs endpoint; fetchJobDetails and fetchJobStatuses are thin wrappers that each return only

(runID int64, verbose bool)

Source from the content-addressed store, hash-verified

77// It is the single source of truth for the jobs endpoint; fetchJobDetails and
78// fetchJobStatuses are thin wrappers that each return only the value they need.
79func fetchJobDetailsWithCounts(runID int64, verbose bool) ([]JobInfoWithDuration, int, error) {
80 logsGitHubAPILog.Printf("Fetching job details: runID=%d", runID)
81 if verbose {
82 fmt.Fprintln(os.Stderr, console.FormatVerboseMessage(fmt.Sprintf("Fetching job details for run %d", runID)))
83 }
84
85 output, err := workflow.RunGHCombined("Fetching job details...", "api",
86 fmt.Sprintf("repos/{owner}/{repo}/actions/runs/%d/jobs", runID),
87 "--jq", ".jobs[] | {name: .name, status: .status, conclusion: (.conclusion // \"\"), started_at: .started_at, completed_at: .completed_at, steps: ((.steps // []) | map({name: .name, status: .status, conclusion: (.conclusion // \"\")}))}")
88 if err != nil {
89 if verbose {
90 fmt.Fprintln(os.Stderr, console.FormatVerboseMessage(fmt.Sprintf("Failed to fetch job details for run %d: %v", runID, err)))
91 }
92 return nil, 0, err
93 }
94
95 var jobs []JobInfoWithDuration
96 failedJobs := 0
97 lines := strings.SplitSeq(strings.TrimSpace(string(output)), "\n")
98 for line := range lines {
99 if strings.TrimSpace(line) == "" {
100 continue
101 }
102
103 var job JobInfo
104 if err := json.Unmarshal([]byte(line), &job); err != nil {
105 if verbose {
106 fmt.Fprintln(os.Stderr, console.FormatVerboseMessage("Failed to parse job info: "+line))
107 }
108 continue
109 }
110
111 jobWithDuration := JobInfoWithDuration{JobInfo: job}
112 if !job.StartedAt.IsZero() && !job.CompletedAt.IsZero() {
113 jobWithDuration.Duration = job.CompletedAt.Sub(job.StartedAt)
114 }
115 jobs = append(jobs, jobWithDuration)
116
117 if isFailureConclusion(job.Conclusion) {
118 failedJobs++
119 logsGitHubAPILog.Printf("Found failed job: name=%s, conclusion=%s", job.Name, job.Conclusion)
120 if verbose {
121 fmt.Fprintln(os.Stderr, console.FormatVerboseMessage(fmt.Sprintf("Found failed job '%s' with conclusion '%s'", job.Name, job.Conclusion)))
122 }
123 }
124 }
125
126 logsGitHubAPILog.Printf("Job fetch complete: total=%d failed=%d", len(jobs), failedJobs)
127 return jobs, failedJobs, nil
128}
129
130// fetchJobDetails gets detailed job information including durations for a workflow run.
131// Errors from the underlying API call are suppressed so that callers can continue

Calls 4

FormatVerboseMessageFunction · 0.92
RunGHCombinedFunction · 0.92
isFailureConclusionFunction · 0.85
PrintfMethod · 0.45