@@ -125,6 +125,61 @@ func handleSingleJobLogs(ctx context.Context, client *github.Client, owner, repo
125125 return utils .NewToolResultText (string (r )), nil , nil
126126}
127127
128+ // handleAllJobLogs gets logs for all jobs in a workflow run
129+ func handleAllJobLogs (ctx context.Context , client * github.Client , owner , repo string , runID int64 , returnContent bool , tailLines int , contentWindowSize int ) (* mcp.CallToolResult , any , error ) {
130+ // First, get all jobs for the workflow run
131+ jobs , resp , err := client .Actions .ListWorkflowJobs (ctx , owner , repo , runID , & github.ListWorkflowJobsOptions {
132+ Filter : "latest" ,
133+ })
134+ if err != nil {
135+ return ghErrors .NewGitHubAPIErrorResponse (ctx , "failed to list workflow jobs" , resp , err ), nil , nil
136+ }
137+ defer func () { _ = resp .Body .Close () }()
138+
139+ if len (jobs .Jobs ) == 0 {
140+ result := map [string ]any {
141+ "message" : "No jobs found in this workflow run" ,
142+ "run_id" : runID ,
143+ "total_jobs" : 0 ,
144+ }
145+ r , _ := json .Marshal (result )
146+ return utils .NewToolResultText (string (r )), nil , nil
147+ }
148+
149+ // Collect logs for all jobs
150+ var logResults []map [string ]any
151+ for _ , job := range jobs .Jobs {
152+ jobResult , resp , err := getJobLogData (ctx , client , owner , repo , job .GetID (), job .GetName (), returnContent , tailLines , contentWindowSize )
153+ if err != nil {
154+ // Continue with other jobs even if one fails
155+ jobResult = map [string ]any {
156+ "job_id" : job .GetID (),
157+ "job_name" : job .GetName (),
158+ "error" : err .Error (),
159+ }
160+ // Enable reporting of status codes and error causes
161+ _ , _ = ghErrors .NewGitHubAPIErrorToCtx (ctx , "failed to get job logs" , resp , err ) // Explicitly ignore error for graceful handling
162+ }
163+
164+ logResults = append (logResults , jobResult )
165+ }
166+
167+ result := map [string ]any {
168+ "message" : fmt .Sprintf ("Retrieved logs for %d jobs" , len (jobs .Jobs )),
169+ "run_id" : runID ,
170+ "total_jobs" : len (jobs .Jobs ),
171+ "logs" : logResults ,
172+ "return_format" : map [string ]bool {"content" : returnContent , "urls" : ! returnContent },
173+ }
174+
175+ r , err := json .Marshal (result )
176+ if err != nil {
177+ return nil , nil , fmt .Errorf ("failed to marshal response: %w" , err )
178+ }
179+
180+ return utils .NewToolResultText (string (r )), nil , nil
181+ }
182+
128183// getJobLogData retrieves log data for a single job, either as URL or content
129184func getJobLogData (ctx context.Context , client * github.Client , owner , repo string , jobID int64 , jobName string , returnContent bool , tailLines int , contentWindowSize int ) (map [string ]any , * github.Response , error ) {
130185 // Get the download URL for the job logs
@@ -716,19 +771,20 @@ For single job logs, provide job_id. For all failed jobs in a run, provide run_i
716771 if failedOnly && runID == 0 {
717772 return utils .NewToolResultError ("run_id is required when failed_only is true" ), nil , nil
718773 }
719- if ! failedOnly && jobID == 0 {
720- return utils .NewToolResultError ("job_id is required when failed_only is false" ), nil , nil
721- }
722774
723- if failedOnly && runID > 0 {
724- // Handle failed-only mode: get logs for all failed jobs in the workflow run
725- return handleFailedJobLogs (ctx , client , owner , repo , int64 (runID ), returnContent , tailLines , deps .GetContentWindowSize ())
775+ if runID > 0 {
776+ if failedOnly {
777+ // Handle failed-only mode: get logs for all failed jobs in the workflow run
778+ return handleFailedJobLogs (ctx , client , owner , repo , int64 (runID ), returnContent , tailLines , deps .GetContentWindowSize ())
779+ }
780+ // Handle all jobs mode: get logs for all jobs in the workflow run
781+ return handleAllJobLogs (ctx , client , owner , repo , int64 (runID ), returnContent , tailLines , deps .GetContentWindowSize ())
726782 } else if jobID > 0 {
727783 // Handle single job mode
728784 return handleSingleJobLogs (ctx , client , owner , repo , int64 (jobID ), returnContent , tailLines , deps .GetContentWindowSize ())
729785 }
730786
731- return utils .NewToolResultError ("Either job_id must be provided for single job logs, or run_id with failed_only=true for failed job logs " ), nil , nil
787+ return utils .NewToolResultError ("Either job_id or run_id must be provided " ), nil , nil
732788 },
733789 )
734790 return tool
0 commit comments