Skip to content

Commit 8922132

Browse files
authored
address comments
1 parent 2bbee8b commit 8922132

2 files changed

Lines changed: 83 additions & 7 deletions

File tree

pkg/github/issue_fields.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77

88
ghcontext "github.com/github/github-mcp-server/pkg/context"
9+
ghErrors "github.com/github/github-mcp-server/pkg/errors"
910
"github.com/github/github-mcp-server/pkg/inventory"
1011
"github.com/github/github-mcp-server/pkg/scopes"
1112
"github.com/github/github-mcp-server/pkg/translations"
@@ -35,9 +36,9 @@ type IssueSingleSelectFieldOption struct {
3536
}
3637

3738
// issueFieldNode is the GraphQL fragment for a single issue field in the IssueFields union.
39+
// Only the fragment matching __typename is populated; read from the matching fragment.
3840
type issueFieldNode struct {
39-
TypeName githubv4.String `graphql:"__typename"`
40-
// All field types share these fields; any populated fragment gives the same values.
41+
TypeName githubv4.String `graphql:"__typename"`
4142
IssueFieldText struct {
4243
ID githubv4.ID
4344
Name githubv4.String
@@ -144,7 +145,7 @@ func ListIssueFields(t translations.TranslationHelperFunc) inventory.ServerTool
144145
"name": githubv4.String(repo),
145146
}
146147
if err := gqlClient.Query(ctxWithFeatures, &query, vars); err != nil {
147-
return utils.NewToolResultErrorFromErr("failed to list issue fields", err), nil, nil
148+
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, "failed to list issue fields", err), nil, nil
148149
}
149150
nodes = query.Repository.IssueFields.Nodes
150151
} else {
@@ -153,16 +154,15 @@ func ListIssueFields(t translations.TranslationHelperFunc) inventory.ServerTool
153154
"login": githubv4.String(owner),
154155
}
155156
if err := gqlClient.Query(ctxWithFeatures, &query, vars); err != nil {
156-
return utils.NewToolResultErrorFromErr("failed to list issue fields", err), nil, nil
157+
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, "failed to list issue fields", err), nil, nil
157158
}
158159
nodes = query.Organization.IssueFields.Nodes
159160
}
160161

161162
fields := make([]IssueField, 0, len(nodes))
162163
for _, node := range nodes {
163164
var f IssueField
164-
// Use TypeName to discriminate; shurcooL populates all matching fragment structs,
165-
// so any non-SingleSelect struct gives the correct shared field values.
165+
// Read from the fragment matching __typename; the other fragments are zero-valued.
166166
switch string(node.TypeName) {
167167
case "IssueFieldSingleSelect":
168168
opts := make([]IssueSingleSelectFieldOption, 0, len(node.IssueFieldSingleSelect.Options))
@@ -183,14 +183,30 @@ func ListIssueFields(t translations.TranslationHelperFunc) inventory.ServerTool
183183
Visibility: string(node.IssueFieldSingleSelect.Visibility),
184184
Options: opts,
185185
}
186-
case "IssueFieldText", "IssueFieldNumber", "IssueFieldDate":
186+
case "IssueFieldText":
187187
f = IssueField{
188188
ID: fmt.Sprintf("%v", node.IssueFieldText.ID),
189189
Name: string(node.IssueFieldText.Name),
190190
Description: string(node.IssueFieldText.Description),
191191
DataType: string(node.IssueFieldText.DataType),
192192
Visibility: string(node.IssueFieldText.Visibility),
193193
}
194+
case "IssueFieldNumber":
195+
f = IssueField{
196+
ID: fmt.Sprintf("%v", node.IssueFieldNumber.ID),
197+
Name: string(node.IssueFieldNumber.Name),
198+
Description: string(node.IssueFieldNumber.Description),
199+
DataType: string(node.IssueFieldNumber.DataType),
200+
Visibility: string(node.IssueFieldNumber.Visibility),
201+
}
202+
case "IssueFieldDate":
203+
f = IssueField{
204+
ID: fmt.Sprintf("%v", node.IssueFieldDate.ID),
205+
Name: string(node.IssueFieldDate.Name),
206+
Description: string(node.IssueFieldDate.Description),
207+
DataType: string(node.IssueFieldDate.DataType),
208+
Visibility: string(node.IssueFieldDate.Visibility),
209+
}
194210
default:
195211
continue
196212
}

pkg/github/issue_fields_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,66 @@ func Test_ListIssueFields(t *testing.T) {
179179
{ID: "IFT_1", Name: "DRI", DataType: "TEXT", Visibility: "ORG_ONLY"},
180180
},
181181
},
182+
{
183+
name: "number field returned",
184+
requestArgs: map[string]any{
185+
"owner": "testowner",
186+
"repo": "testrepo",
187+
},
188+
gqlResponse: githubv4mock.DataResponse(map[string]any{
189+
"repository": map[string]any{
190+
"issueFields": map[string]any{
191+
"nodes": []any{
192+
map[string]any{
193+
"__typename": "IssueFieldNumber",
194+
"id": "IFN_1",
195+
"name": "Engineering Staffing",
196+
"dataType": "NUMBER",
197+
"visibility": "ORG_ONLY",
198+
},
199+
},
200+
},
201+
},
202+
}),
203+
expectedFields: []IssueField{
204+
{ID: "IFN_1", Name: "Engineering Staffing", DataType: "NUMBER", Visibility: "ORG_ONLY"},
205+
},
206+
},
207+
{
208+
name: "date field returned",
209+
requestArgs: map[string]any{
210+
"owner": "testowner",
211+
"repo": "testrepo",
212+
},
213+
gqlResponse: githubv4mock.DataResponse(map[string]any{
214+
"repository": map[string]any{
215+
"issueFields": map[string]any{
216+
"nodes": []any{
217+
map[string]any{
218+
"__typename": "IssueFieldDate",
219+
"id": "IFD_1",
220+
"name": "Target Date",
221+
"dataType": "DATE",
222+
"visibility": "ORG_ONLY",
223+
},
224+
},
225+
},
226+
},
227+
}),
228+
expectedFields: []IssueField{
229+
{ID: "IFD_1", Name: "Target Date", DataType: "DATE", Visibility: "ORG_ONLY"},
230+
},
231+
},
232+
{
233+
name: "graphql error returns failure",
234+
requestArgs: map[string]any{
235+
"owner": "testowner",
236+
"repo": "testrepo",
237+
},
238+
gqlResponse: githubv4mock.ErrorResponse("boom"),
239+
expectError: true,
240+
expectedErrMsg: "failed to list issue fields",
241+
},
182242
}
183243

184244
for _, tc := range tests {

0 commit comments

Comments
 (0)