From e1a4bfa4bbb76a5199e1151d139f10ba04bfa746 Mon Sep 17 00:00:00 2001 From: Matt Holloway Date: Wed, 24 Dec 2025 10:59:32 +0000 Subject: [PATCH 1/2] change list workflow runs to allow empty resource id to list all runs in repo --- pkg/github/__toolsnaps__/actions_list.snap | 22 ++++++------- pkg/github/actions.go | 20 ++++++------ pkg/github/actions_test.go | 36 +++++++++++++++++++--- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/pkg/github/__toolsnaps__/actions_list.snap b/pkg/github/__toolsnaps__/actions_list.snap index 3968a6eae..4bd029388 100644 --- a/pkg/github/__toolsnaps__/actions_list.snap +++ b/pkg/github/__toolsnaps__/actions_list.snap @@ -6,11 +6,6 @@ "description": "Tools for listing GitHub Actions resources.\nUse this tool to list workflows in a repository, or list workflow runs, jobs, and artifacts for a specific workflow or workflow run.\n", "inputSchema": { "type": "object", - "required": [ - "method", - "owner", - "repo" - ], "properties": { "method": { "type": "string", @@ -43,11 +38,10 @@ }, "resource_id": { "type": "string", - "description": "The unique identifier of the resource. This will vary based on the \"method\" provided, so ensure you provide the correct ID:\n- Do not provide any resource ID for 'list_workflows' method.\n- Provide a workflow ID or workflow file name (e.g. ci.yaml) for 'list_workflow_runs' method.\n- Provide a workflow run ID for 'list_workflow_jobs' and 'list_workflow_run_artifacts' methods.\n" + "description": "The unique identifier of the resource. This will vary based on the \"method\" provided, so ensure you provide the correct ID:\n- Do not provide any resource ID for 'list_workflows' method.\n- Provide a workflow ID or workflow file name (e.g. ci.yaml) for 'list_workflow_runs' method, or omit to list all workflow runs in the repository.\n- Provide a workflow run ID for 'list_workflow_jobs' and 'list_workflow_run_artifacts' methods.\n" }, "workflow_jobs_filter": { "type": "object", - "description": "Filters for workflow jobs. **ONLY** used when method is 'list_workflow_jobs'", "properties": { "filter": { "type": "string", @@ -57,11 +51,11 @@ "all" ] } - } + }, + "description": "Filters for workflow jobs. **ONLY** used when method is 'list_workflow_jobs'" }, "workflow_runs_filter": { "type": "object", - "description": "Filters for workflow runs. **ONLY** used when method is 'list_workflow_runs'", "properties": { "actor": { "type": "string", @@ -120,9 +114,15 @@ "waiting" ] } - } + }, + "description": "Filters for workflow runs. **ONLY** used when method is 'list_workflow_runs'" } - } + }, + "required": [ + "method", + "owner", + "repo" + ] }, "name": "actions_list" } \ No newline at end of file diff --git a/pkg/github/actions.go b/pkg/github/actions.go index 6c7cdc367..1547c3251 100644 --- a/pkg/github/actions.go +++ b/pkg/github/actions.go @@ -1463,7 +1463,7 @@ Use this tool to list workflows in a repository, or list workflow runs, jobs, an Type: "string", Description: `The unique identifier of the resource. This will vary based on the "method" provided, so ensure you provide the correct ID: - Do not provide any resource ID for 'list_workflows' method. -- Provide a workflow ID or workflow file name (e.g. ci.yaml) for 'list_workflow_runs' method. +- Provide a workflow ID or workflow file name (e.g. ci.yaml) for 'list_workflow_runs' method, or omit to list all workflow runs in the repository. - Provide a workflow run ID for 'list_workflow_jobs' and 'list_workflow_run_artifacts' methods. `, }, @@ -1586,18 +1586,18 @@ Use this tool to list workflows in a repository, or list workflow runs, jobs, an switch method { case actionsMethodListWorkflows: // Do nothing, no resource ID needed + case actionsMethodListWorkflowRuns: + // resource_id is optional for list_workflow_runs + // If not provided, list all workflow runs in the repository default: if resourceID == "" { return utils.NewToolResultError(fmt.Sprintf("missing required parameter for method %s: resource_id", method)), nil, nil } - // For list_workflow_runs, resource_id could be a filename or numeric ID - // For other actions, resource ID must be an integer - if method != actionsMethodListWorkflowRuns { - resourceIDInt, parseErr = strconv.ParseInt(resourceID, 10, 64) - if parseErr != nil { - return utils.NewToolResultError(fmt.Sprintf("invalid resource_id, must be an integer for method %s: %v", method, parseErr)), nil, nil - } + // resource ID must be an integer for jobs and artifacts + resourceIDInt, parseErr = strconv.ParseInt(resourceID, 10, 64) + if parseErr != nil { + return utils.NewToolResultError(fmt.Sprintf("invalid resource_id, must be an integer for method %s: %v", method, parseErr)), nil, nil } } @@ -2063,7 +2063,9 @@ func listWorkflowRuns(ctx context.Context, client *github.Client, args map[strin var workflowRuns *github.WorkflowRuns var resp *github.Response - if workflowIDInt, parseErr := strconv.ParseInt(resourceID, 10, 64); parseErr == nil { + if resourceID == "" { + workflowRuns, resp, err = client.Actions.ListRepositoryWorkflowRuns(ctx, owner, repo, listWorkflowRunsOptions) + } else if workflowIDInt, parseErr := strconv.ParseInt(resourceID, 10, 64); parseErr == nil { workflowRuns, resp, err = client.Actions.ListWorkflowRunsByID(ctx, owner, repo, workflowIDInt, listWorkflowRunsOptions) } else { workflowRuns, resp, err = client.Actions.ListWorkflowRunsByFileName(ctx, owner, repo, resourceID, listWorkflowRunsOptions) diff --git a/pkg/github/actions_test.go b/pkg/github/actions_test.go index f2d336e21..7319feddf 100644 --- a/pkg/github/actions_test.go +++ b/pkg/github/actions_test.go @@ -1997,8 +1997,33 @@ func Test_ActionsList_ListWorkflowRuns(t *testing.T) { assert.NotNil(t, response.TotalCount) }) - t.Run("missing resource_id for list_workflow_runs", func(t *testing.T) { - mockedClient := mock.NewMockedHTTPClient() + t.Run("list all workflow runs without resource_id", func(t *testing.T) { + mockedClient := mock.NewMockedHTTPClient( + mock.WithRequestMatchHandler( + mock.GetReposActionsRunsByOwnerByRepo, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + runs := &github.WorkflowRuns{ + TotalCount: github.Ptr(2), + WorkflowRuns: []*github.WorkflowRun{ + { + ID: github.Ptr(int64(123)), + Name: github.Ptr("CI"), + Status: github.Ptr("completed"), + Conclusion: github.Ptr("success"), + }, + { + ID: github.Ptr(int64(456)), + Name: github.Ptr("Deploy"), + Status: github.Ptr("in_progress"), + Conclusion: nil, + }, + }, + } + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(runs) + }), + ), + ) client := github.NewClient(mockedClient) deps := BaseDeps{ @@ -2014,10 +2039,13 @@ func Test_ActionsList_ListWorkflowRuns(t *testing.T) { result, err := handler(ContextWithDeps(context.Background(), deps), &request) require.NoError(t, err) - require.True(t, result.IsError) + require.False(t, result.IsError) textContent := getTextResult(t, result) - assert.Contains(t, textContent.Text, "missing required parameter") + var response github.WorkflowRuns + err = json.Unmarshal([]byte(textContent.Text), &response) + require.NoError(t, err) + assert.Equal(t, 2, *response.TotalCount) }) } From bafe14b93f173931a5a896b25efd03eca1c65990 Mon Sep 17 00:00:00 2001 From: Matt Holloway Date: Wed, 24 Dec 2025 11:01:50 +0000 Subject: [PATCH 2/2] update docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 059256aaa..87986e0f7 100644 --- a/README.md +++ b/README.md @@ -509,7 +509,7 @@ The following sets of tools are available: - `repo`: Repository name (string, required) - `resource_id`: The unique identifier of the resource. This will vary based on the "method" provided, so ensure you provide the correct ID: - Do not provide any resource ID for 'list_workflows' method. - - Provide a workflow ID or workflow file name (e.g. ci.yaml) for 'list_workflow_runs' method. + - Provide a workflow ID or workflow file name (e.g. ci.yaml) for 'list_workflow_runs' method, or omit to list all workflow runs in the repository. - Provide a workflow run ID for 'list_workflow_jobs' and 'list_workflow_run_artifacts' methods. (string, optional) - `workflow_jobs_filter`: Filters for workflow jobs. **ONLY** used when method is 'list_workflow_jobs' (object, optional)