From e733f06faeff8776819367215fa16a4f6988a58d Mon Sep 17 00:00:00 2001 From: Pranav RK Date: Thu, 5 Jun 2025 23:00:29 +0530 Subject: [PATCH 1/2] feat: add type to issues --- pkg/github/issues.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pkg/github/issues.go b/pkg/github/issues.go index 7fba9f9d..5324bc0e 100644 --- a/pkg/github/issues.go +++ b/pkg/github/issues.go @@ -283,6 +283,9 @@ func CreateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (t mcp.WithNumber("milestone", mcp.Description("Milestone number"), ), + mcp.WithString("type", + mcp.Description("Type of this issue"), + ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner, err := requiredParam[string](request, "owner") @@ -327,6 +330,12 @@ func CreateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (t milestoneNum = &milestone } + // Get optional type + issueType, err := OptionalParam[string](request, "type") + if err != nil { + return mcp.NewToolResultError(err.Error()), nil + } + // Create the issue request issueRequest := &github.IssueRequest{ Title: github.Ptr(title), @@ -334,6 +343,7 @@ func CreateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (t Assignees: &assignees, Labels: &labels, Milestone: milestoneNum, + Type: &issueType, } client, err := getClient(ctx) @@ -534,6 +544,9 @@ func UpdateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (t mcp.WithNumber("milestone", mcp.Description("New milestone number"), ), + mcp.WithString("type", + mcp.Description("New issue type"), + ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner, err := requiredParam[string](request, "owner") @@ -604,6 +617,15 @@ func UpdateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (t issueRequest.Milestone = &milestoneNum } + // Get issue type + issueType, err := OptionalParam[string](request, "type") + if err != nil { + return mcp.NewToolResultError(err.Error()), nil + } + if issueType != "" { + issueRequest.Type = github.Ptr(issueType) + } + client, err := getClient(ctx) if err != nil { return nil, fmt.Errorf("failed to get GitHub client: %w", err) From 6a1695520587b351b5e82d28e8a63de4676155a7 Mon Sep 17 00:00:00 2001 From: Pranav RK Date: Sat, 7 Jun 2025 00:22:09 +0530 Subject: [PATCH 2/2] test: add `type` test for create and update issues --- pkg/github/issues_test.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index 251fc32b..164b32fa 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -396,6 +396,7 @@ func Test_CreateIssue(t *testing.T) { assert.Contains(t, tool.InputSchema.Properties, "assignees") assert.Contains(t, tool.InputSchema.Properties, "labels") assert.Contains(t, tool.InputSchema.Properties, "milestone") + assert.Contains(t, tool.InputSchema.Properties, "type") assert.ElementsMatch(t, tool.InputSchema.Required, []string{"owner", "repo", "title"}) // Setup mock issue for success case @@ -408,6 +409,7 @@ func Test_CreateIssue(t *testing.T) { Assignees: []*github.User{{Login: github.Ptr("user1")}, {Login: github.Ptr("user2")}}, Labels: []*github.Label{{Name: github.Ptr("bug")}, {Name: github.Ptr("help wanted")}}, Milestone: &github.Milestone{Number: github.Ptr(5)}, + Type: &github.IssueType{Name: github.Ptr("Bug")}, } tests := []struct { @@ -429,6 +431,7 @@ func Test_CreateIssue(t *testing.T) { "labels": []any{"bug", "help wanted"}, "assignees": []any{"user1", "user2"}, "milestone": float64(5), + "type": "Bug", }).andThen( mockResponse(t, http.StatusCreated, mockIssue), ), @@ -442,6 +445,7 @@ func Test_CreateIssue(t *testing.T) { "assignees": []any{"user1", "user2"}, "labels": []any{"bug", "help wanted"}, "milestone": float64(5), + "type": "Bug", }, expectError: false, expectedIssue: mockIssue, @@ -537,6 +541,10 @@ func Test_CreateIssue(t *testing.T) { assert.Equal(t, *tc.expectedIssue.Body, *returnedIssue.Body) } + if tc.expectedIssue.Type != nil { + assert.Equal(t, *tc.expectedIssue.Type.Name, *returnedIssue.Type.Name) + } + // Check assignees if expected if len(tc.expectedIssue.Assignees) > 0 { assert.Equal(t, len(tc.expectedIssue.Assignees), len(returnedIssue.Assignees)) @@ -748,6 +756,7 @@ func Test_UpdateIssue(t *testing.T) { assert.Contains(t, tool.InputSchema.Properties, "labels") assert.Contains(t, tool.InputSchema.Properties, "assignees") assert.Contains(t, tool.InputSchema.Properties, "milestone") + assert.Contains(t, tool.InputSchema.Properties, "type") assert.ElementsMatch(t, tool.InputSchema.Required, []string{"owner", "repo", "issue_number"}) // Setup mock issue for success case @@ -760,6 +769,7 @@ func Test_UpdateIssue(t *testing.T) { Assignees: []*github.User{{Login: github.Ptr("assignee1")}, {Login: github.Ptr("assignee2")}}, Labels: []*github.Label{{Name: github.Ptr("bug")}, {Name: github.Ptr("priority")}}, Milestone: &github.Milestone{Number: github.Ptr(5)}, + Type: &github.IssueType{Name: github.Ptr("Bug")}, } tests := []struct { @@ -782,6 +792,7 @@ func Test_UpdateIssue(t *testing.T) { "labels": []any{"bug", "priority"}, "assignees": []any{"assignee1", "assignee2"}, "milestone": float64(5), + "type": "Bug", }).andThen( mockResponse(t, http.StatusOK, mockIssue), ), @@ -797,6 +808,7 @@ func Test_UpdateIssue(t *testing.T) { "labels": []any{"bug", "priority"}, "assignees": []any{"assignee1", "assignee2"}, "milestone": float64(5), + "type": "Bug", }, expectError: false, expectedIssue: mockIssue, @@ -808,9 +820,10 @@ func Test_UpdateIssue(t *testing.T) { mock.PatchReposIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusOK, &github.Issue{ Number: github.Ptr(123), - Title: github.Ptr("Only Title Updated"), + Title: github.Ptr("Updated Issue Title"), HTMLURL: github.Ptr("https://github.com/owner/repo/issues/123"), State: github.Ptr("open"), + Type: &github.IssueType{Name: github.Ptr("Feature")}, }), ), ), @@ -818,14 +831,16 @@ func Test_UpdateIssue(t *testing.T) { "owner": "owner", "repo": "repo", "issue_number": float64(123), - "title": "Only Title Updated", + "title": "Updated Issue Title", + "type": "Feature", }, expectError: false, expectedIssue: &github.Issue{ Number: github.Ptr(123), - Title: github.Ptr("Only Title Updated"), + Title: github.Ptr("Updated Issue Title"), HTMLURL: github.Ptr("https://github.com/owner/repo/issues/123"), State: github.Ptr("open"), + Type: &github.IssueType{Name: github.Ptr("Feature")}, }, }, { @@ -914,6 +929,10 @@ func Test_UpdateIssue(t *testing.T) { assert.Equal(t, *tc.expectedIssue.Body, *returnedIssue.Body) } + if tc.expectedIssue.Type != nil { + assert.Equal(t, *tc.expectedIssue.Type.Name, *returnedIssue.Type.Name) + } + // Check assignees if expected if len(tc.expectedIssue.Assignees) > 0 { assert.Len(t, returnedIssue.Assignees, len(tc.expectedIssue.Assignees))