Skip to content

Commit 0867d89

Browse files
committed
Return total number of lines
1 parent 36236f5 commit 0867d89

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

pkg/github/actions.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

pkg/github/actions_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,7 @@ func Test_GetJobLogs_WithContentReturnAndTailLines(t *testing.T) {
11391139
require.NoError(t, err)
11401140

11411141
assert.Equal(t, float64(123), response["job_id"])
1142+
assert.Equal(t, float64(1), response["original_length"])
11421143
assert.Equal(t, expectedLogContent, response["logs_content"])
11431144
assert.Equal(t, "Job logs content retrieved successfully", response["message"])
11441145
assert.NotContains(t, response, "logs_url") // Should not have URL when returning content

0 commit comments

Comments
 (0)