@@ -640,18 +640,18 @@ func GetJobLogs(getClient GetClientFn, t translations.TranslationHelperFunc) (to
640640
641641 if failedOnly && runID > 0 {
642642 // Handle failed-only mode: get logs for all failed jobs in the workflow run
643- return handleFailedJobLogs (ctx , client , owner , repo , int64 (runID ), returnContent , tailLines )
643+ return handleFailedJobLogs (ctx , client , owner , repo , int64 (runID ), returnContent , int16 ( tailLines ) )
644644 } else if jobID > 0 {
645645 // Handle single job mode
646- return handleSingleJobLogs (ctx , client , owner , repo , int64 (jobID ), returnContent , tailLines )
646+ return handleSingleJobLogs (ctx , client , owner , repo , int64 (jobID ), returnContent , int16 ( tailLines ) )
647647 }
648648
649649 return mcp .NewToolResultError ("Either job_id must be provided for single job logs, or run_id with failed_only=true for failed job logs" ), nil
650650 }
651651}
652652
653653// handleFailedJobLogs gets logs for all failed jobs in a workflow run
654- func handleFailedJobLogs (ctx context.Context , client * github.Client , owner , repo string , runID int64 , returnContent bool , tailLines int ) (* mcp.CallToolResult , error ) {
654+ func handleFailedJobLogs (ctx context.Context , client * github.Client , owner , repo string , runID int64 , returnContent bool , tailLines int16 ) (* mcp.CallToolResult , error ) {
655655 // First, get all jobs for the workflow run
656656 jobs , resp , err := client .Actions .ListWorkflowJobs (ctx , owner , repo , runID , & github.ListWorkflowJobsOptions {
657657 Filter : "latest" ,
@@ -716,7 +716,7 @@ func handleFailedJobLogs(ctx context.Context, client *github.Client, owner, repo
716716}
717717
718718// handleSingleJobLogs gets logs for a single job
719- func handleSingleJobLogs (ctx context.Context , client * github.Client , owner , repo string , jobID int64 , returnContent bool , tailLines int ) (* mcp.CallToolResult , error ) {
719+ func handleSingleJobLogs (ctx context.Context , client * github.Client , owner , repo string , jobID int64 , returnContent bool , tailLines int16 ) (* mcp.CallToolResult , error ) {
720720 jobResult , resp , err := getJobLogData (ctx , client , owner , repo , jobID , "" , returnContent , tailLines )
721721 if err != nil {
722722 return ghErrors .NewGitHubAPIErrorResponse (ctx , "failed to get job logs" , resp , err ), nil
@@ -731,7 +731,7 @@ func handleSingleJobLogs(ctx context.Context, client *github.Client, owner, repo
731731}
732732
733733// getJobLogData retrieves log data for a single job, either as URL or content
734- func getJobLogData (ctx context.Context , client * github.Client , owner , repo string , jobID int64 , jobName string , returnContent bool , tailLines int ) (map [string ]any , * github.Response , error ) {
734+ func getJobLogData (ctx context.Context , client * github.Client , owner , repo string , jobID int64 , jobName string , returnContent bool , tailLines int16 ) (map [string ]any , * github.Response , error ) {
735735 // Get the download URL for the job logs
736736 url , resp , err := client .Actions .GetWorkflowJobLogs (ctx , owner , repo , jobID , 1 )
737737 if err != nil {
@@ -748,7 +748,7 @@ func getJobLogData(ctx context.Context, client *github.Client, owner, repo strin
748748
749749 if returnContent {
750750 // Download and return the actual log content
751- content , httpResp , err := downloadLogContent (url .String (), tailLines ) //nolint:bodyclose // Response body is closed in downloadLogContent, but we need to return httpResp
751+ content , originalLength , httpResp , err := downloadLogContent (url .String (), tailLines ) //nolint:bodyclose // Response body is closed in downloadLogContent, but we need to return httpResp
752752 if err != nil {
753753 // To keep the return value consistent wrap the response as a GitHub Response
754754 ghRes := & github.Response {
@@ -758,6 +758,7 @@ func getJobLogData(ctx context.Context, client *github.Client, owner, repo strin
758758 }
759759 result ["logs_content" ] = content
760760 result ["message" ] = "Job logs content retrieved successfully"
761+ result ["original_length" ] = originalLength
761762 } else {
762763 // Return just the URL
763764 result ["logs_url" ] = url .String ()
@@ -769,42 +770,46 @@ func getJobLogData(ctx context.Context, client *github.Client, owner, repo strin
769770}
770771
771772// downloadLogContent downloads the actual log content from a GitHub logs URL
772- func downloadLogContent (logURL string , tailLines int ) (string , * http.Response , error ) {
773+ func downloadLogContent (logURL string , tailLines int16 ) (string , int16 , * http.Response , error ) {
773774 httpResp , err := http .Get (logURL ) //nolint:gosec // URLs are provided by GitHub API and are safe
774775 if err != nil {
775- return "" , httpResp , fmt .Errorf ("failed to download logs: %w" , err )
776+ return "" , 0 , httpResp , fmt .Errorf ("failed to download logs: %w" , err )
776777 }
777778 defer func () { _ = httpResp .Body .Close () }()
778779
779780 if httpResp .StatusCode != http .StatusOK {
780- return "" , httpResp , fmt .Errorf ("failed to download logs: HTTP %d" , httpResp .StatusCode )
781+ return "" , 0 , httpResp , fmt .Errorf ("failed to download logs: HTTP %d" , httpResp .StatusCode )
781782 }
782783
783784 content , err := io .ReadAll (httpResp .Body )
784785 if err != nil {
785- return "" , httpResp , fmt .Errorf ("failed to read log content: %w" , err )
786+ return "" , 0 , httpResp , fmt .Errorf ("failed to read log content: %w" , err )
786787 }
787788
788789 // Clean up and format the log content for better readability
789790 logContent := strings .TrimSpace (string (content ))
790791
792+ trimmedContent , lineCount := trimContent (logContent , tailLines )
793+ return trimmedContent , lineCount , httpResp , nil
794+ }
795+
796+ // trimContent trims the content to a maximum length and returns the trimmed content and an original length
797+ func trimContent (content string , tailLines int16 ) (string , int16 ) {
791798 // Truncate to tail_lines if specified
799+ lineCount := int16 (0 )
792800 if tailLines > 0 {
793- lineCount := 0
794801
795802 // Count backwards to find the nth newline from the end
796- for i := len (logContent ) - 1 ; i >= 0 && lineCount < tailLines ; i -- {
797- if logContent [i ] == '\n' {
803+ for i := len (content ) - 1 ; i >= 0 && lineCount < tailLines ; i -- {
804+ if content [i ] == '\n' {
798805 lineCount ++
799806 if lineCount == tailLines {
800- logContent = logContent [i + 1 :]
801- break
807+ content = content [i + 1 :]
802808 }
803809 }
804810 }
805811 }
806-
807- return logContent , httpResp , nil
812+ return content , lineCount
808813}
809814
810815// RerunWorkflowRun creates a tool to re-run an entire workflow run
0 commit comments