Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb68bec0

Browse files
Update mcp server with latest google/go-github API (#1358)
* licences update from required CI build* fixes licences* implements new helpers to support google/go-github v77 API* upgrades toolset to leverage google/go-github v77 with the exception of Update and Delete items* refactor string conversion helpers* reverts migration google/go-github GetProjectItem due to bug with the underlying library implementation* additional refactoring for server helpers based on recent updates to google/go-github* test updates based on underlying lib requirements* resolves licences conflicts with script/licenses* cleanup* reduce change diff* updates helper docs to reflect to methods* upgrades delete projects item to google/go-github* returns error from parsing string to int64* improved OptionalBigIntArrayParam doc* improves implementation for RequiredBigInt* improves documentation for temporary fieldSelectionOptions struct
1 parentcf0e05e commitb68bec0

File tree

3 files changed

+146
-119
lines changed

3 files changed

+146
-119
lines changed

‎pkg/github/projects.go‎

Lines changed: 67 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,13 @@ func ListProjects(getClient GetClientFn, t translations.TranslationHelperFunc) (
6969

7070
varresp*github.Response
7171
varprojects []*github.ProjectV2
72-
minimalProjects:= []MinimalProject{}
73-
7472
varqueryPtr*string
73+
7574
ifqueryStr!="" {
7675
queryPtr=&queryStr
7776
}
7877

78+
minimalProjects:= []MinimalProject{}
7979
opts:=&github.ListProjectsOptions{
8080
ListProjectsPaginationOptions: github.ListProjectsPaginationOptions{PerPage:&perPage},
8181
Query:queryPtr,
@@ -237,27 +237,19 @@ func ListProjectFields(getClient GetClientFn, t translations.TranslationHelperFu
237237
returnmcp.NewToolResultError(err.Error()),nil
238238
}
239239

240-
varurlstring
241-
ifownerType=="org" {
242-
url=fmt.Sprintf("orgs/%s/projectsV2/%d/fields",owner,projectNumber)
243-
}else {
244-
url=fmt.Sprintf("users/%s/projectsV2/%d/fields",owner,projectNumber)
245-
}
246-
projectFields:= []projectV2Field{}
247-
248-
opts:=paginationOptions{PerPage:perPage}
240+
varresp*github.Response
241+
varprojectFields []*github.ProjectV2Field
249242

250-
url,err=addOptions(url,opts)
251-
iferr!=nil {
252-
returnnil,fmt.Errorf("failed to add options to request: %w",err)
243+
opts:=&github.ListProjectsOptions{
244+
ListProjectsPaginationOptions: github.ListProjectsPaginationOptions{PerPage:&perPage},
253245
}
254246

255-
httpRequest,err:=client.NewRequest("GET",url,nil)
256-
iferr!=nil {
257-
returnnil,fmt.Errorf("failed to create request: %w",err)
247+
ifownerType=="org" {
248+
projectFields,resp,err=client.Projects.ListOrganizationProjectFields(ctx,owner,projectNumber,opts)
249+
}else {
250+
projectFields,resp,err=client.Projects.ListUserProjectFields(ctx,owner,projectNumber,opts)
258251
}
259252

260-
resp,err:=client.Do(ctx,httpRequest,&projectFields)
261253
iferr!=nil {
262254
returnghErrors.NewGitHubAPIErrorResponse(ctx,
263255
"failed to list project fields",
@@ -317,7 +309,7 @@ func GetProjectField(getClient GetClientFn, t translations.TranslationHelperFunc
317309
iferr!=nil {
318310
returnmcp.NewToolResultError(err.Error()),nil
319311
}
320-
fieldID,err:=RequiredInt(req,"field_id")
312+
fieldID,err:=RequiredBigInt(req,"field_id")
321313
iferr!=nil {
322314
returnmcp.NewToolResultError(err.Error()),nil
323315
}
@@ -326,21 +318,15 @@ func GetProjectField(getClient GetClientFn, t translations.TranslationHelperFunc
326318
returnmcp.NewToolResultError(err.Error()),nil
327319
}
328320

329-
varurlstring
321+
varresp*github.Response
322+
varprojectField*github.ProjectV2Field
323+
330324
ifownerType=="org" {
331-
url=fmt.Sprintf("orgs/%s/projectsV2/%d/fields/%d",owner,projectNumber,fieldID)
325+
projectField,resp,err=client.Projects.GetOrganizationProjectField(ctx,owner,projectNumber,fieldID)
332326
}else {
333-
url=fmt.Sprintf("users/%s/projectsV2/%d/fields/%d",owner,projectNumber,fieldID)
327+
projectField,resp,err=client.Projects.GetUserProjectField(ctx,owner,projectNumber,fieldID)
334328
}
335329

336-
projectField:=projectV2Field{}
337-
338-
httpRequest,err:=client.NewRequest("GET",url,nil)
339-
iferr!=nil {
340-
returnnil,fmt.Errorf("failed to create request: %w",err)
341-
}
342-
343-
resp,err:=client.Do(ctx,httpRequest,&projectField)
344330
iferr!=nil {
345331
returnghErrors.NewGitHubAPIErrorResponse(ctx,
346332
"failed to get project field",
@@ -416,41 +402,37 @@ func ListProjectItems(getClient GetClientFn, t translations.TranslationHelperFun
416402
iferr!=nil {
417403
returnmcp.NewToolResultError(err.Error()),nil
418404
}
419-
fields,err:=OptionalStringArrayParam(req,"fields")
405+
fields,err:=OptionalBigIntArrayParam(req,"fields")
420406
iferr!=nil {
421407
returnmcp.NewToolResultError(err.Error()),nil
422408
}
423-
424409
client,err:=getClient(ctx)
425410
iferr!=nil {
426411
returnmcp.NewToolResultError(err.Error()),nil
427412
}
428413

429-
varurlstring
430-
ifownerType=="org" {
431-
url=fmt.Sprintf("orgs/%s/projectsV2/%d/items",owner,projectNumber)
432-
}else {
433-
url=fmt.Sprintf("users/%s/projectsV2/%d/items",owner,projectNumber)
434-
}
435-
projectItems:= []projectV2Item{}
414+
varresp*github.Response
415+
varprojectItems []*github.ProjectV2Item
416+
varqueryPtr*string
436417

437-
opts:=listProjectItemsOptions{
438-
paginationOptions:paginationOptions{PerPage:perPage},
439-
filterQueryOptions:filterQueryOptions{Query:queryStr},
440-
fieldSelectionOptions:fieldSelectionOptions{Fields:fields},
418+
ifqueryStr!="" {
419+
queryPtr=&queryStr
441420
}
442421

443-
url,err=addOptions(url,opts)
444-
iferr!=nil {
445-
returnnil,fmt.Errorf("failed to add options to request: %w",err)
422+
opts:=&github.ListProjectItemsOptions{
423+
Fields:fields,
424+
ListProjectsOptions: github.ListProjectsOptions{
425+
ListProjectsPaginationOptions: github.ListProjectsPaginationOptions{PerPage:&perPage},
426+
Query:queryPtr,
427+
},
446428
}
447429

448-
httpRequest,err:=client.NewRequest("GET",url,nil)
449-
iferr!=nil {
450-
returnnil,fmt.Errorf("failed to create request: %w",err)
430+
ifownerType=="org" {
431+
projectItems,resp,err=client.Projects.ListOrganizationProjectItems(ctx,owner,projectNumber,opts)
432+
}else {
433+
projectItems,resp,err=client.Projects.ListUserProjectItems(ctx,owner,projectNumber,opts)
451434
}
452435

453-
resp,err:=client.Do(ctx,httpRequest,&projectItems)
454436
iferr!=nil {
455437
returnghErrors.NewGitHubAPIErrorResponse(ctx,
456438
ProjectListFailedError,
@@ -518,11 +500,11 @@ func GetProjectItem(getClient GetClientFn, t translations.TranslationHelperFunc)
518500
iferr!=nil {
519501
returnmcp.NewToolResultError(err.Error()),nil
520502
}
521-
itemID,err:=RequiredInt(req,"item_id")
503+
itemID,err:=RequiredBigInt(req,"item_id")
522504
iferr!=nil {
523505
returnmcp.NewToolResultError(err.Error()),nil
524506
}
525-
fields,err:=OptionalStringArrayParam(req,"fields")
507+
fields,err:=OptionalBigIntArrayParam(req,"fields")
526508
iferr!=nil {
527509
returnmcp.NewToolResultError(err.Error()),nil
528510
}
@@ -624,7 +606,7 @@ func AddProjectItem(getClient GetClientFn, t translations.TranslationHelperFunc)
624606
iferr!=nil {
625607
returnmcp.NewToolResultError(err.Error()),nil
626608
}
627-
itemID,err:=RequiredInt(req,"item_id")
609+
itemID,err:=RequiredBigInt(req,"item_id")
628610
iferr!=nil {
629611
returnmcp.NewToolResultError(err.Error()),nil
630612
}
@@ -642,24 +624,20 @@ func AddProjectItem(getClient GetClientFn, t translations.TranslationHelperFunc)
642624
returnmcp.NewToolResultError(err.Error()),nil
643625
}
644626

645-
varprojectsURLstring
646-
ifownerType=="org" {
647-
projectsURL=fmt.Sprintf("orgs/%s/projectsV2/%d/items",owner,projectNumber)
648-
}else {
649-
projectsURL=fmt.Sprintf("users/%s/projectsV2/%d/items",owner,projectNumber)
650-
}
651-
652-
newItem:=&newProjectItem{
653-
ID:int64(itemID),
627+
newItem:=&github.AddProjectItemOptions{
628+
ID:itemID,
654629
Type:toNewProjectType(itemType),
655630
}
656-
httpRequest,err:=client.NewRequest("POST",projectsURL,newItem)
657-
iferr!=nil {
658-
returnnil,fmt.Errorf("failed to create request: %w",err)
631+
632+
varresp*github.Response
633+
varaddedItem*github.ProjectV2Item
634+
635+
ifownerType=="org" {
636+
addedItem,resp,err=client.Projects.AddOrganizationProjectItem(ctx,owner,projectNumber,newItem)
637+
}else {
638+
addedItem,resp,err=client.Projects.AddUserProjectItem(ctx,owner,projectNumber,newItem)
659639
}
660-
addedItem:=projectV2Item{}
661640

662-
resp,err:=client.Do(ctx,httpRequest,&addedItem)
663641
iferr!=nil {
664642
returnghErrors.NewGitHubAPIErrorResponse(ctx,
665643
ProjectAddFailedError,
@@ -827,7 +805,7 @@ func DeleteProjectItem(getClient GetClientFn, t translations.TranslationHelperFu
827805
iferr!=nil {
828806
returnmcp.NewToolResultError(err.Error()),nil
829807
}
830-
itemID,err:=RequiredInt(req,"item_id")
808+
itemID,err:=RequiredBigInt(req,"item_id")
831809
iferr!=nil {
832810
returnmcp.NewToolResultError(err.Error()),nil
833811
}
@@ -836,19 +814,13 @@ func DeleteProjectItem(getClient GetClientFn, t translations.TranslationHelperFu
836814
returnmcp.NewToolResultError(err.Error()),nil
837815
}
838816

839-
varprojectsURLstring
817+
varresp*github.Response
840818
ifownerType=="org" {
841-
projectsURL=fmt.Sprintf("orgs/%s/projectsV2/%d/items/%d",owner,projectNumber,itemID)
819+
resp,err=client.Projects.DeleteOrganizationProjectItem(ctx,owner,projectNumber,itemID)
842820
}else {
843-
projectsURL=fmt.Sprintf("users/%s/projectsV2/%d/items/%d",owner,projectNumber,itemID)
821+
resp,err=client.Projects.DeleteUserProjectItem(ctx,owner,projectNumber,itemID)
844822
}
845823

846-
httpRequest,err:=client.NewRequest("DELETE",projectsURL,nil)
847-
iferr!=nil {
848-
returnnil,fmt.Errorf("failed to create request: %w",err)
849-
}
850-
851-
resp,err:=client.Do(ctx,httpRequest,nil)
852824
iferr!=nil {
853825
returnghErrors.NewGitHubAPIErrorResponse(ctx,
854826
ProjectDeleteFailedError,
@@ -869,9 +841,10 @@ func DeleteProjectItem(getClient GetClientFn, t translations.TranslationHelperFu
869841
}
870842
}
871843

872-
typenewProjectItemstruct {
873-
IDint64`json:"id,omitempty"`
874-
Typestring`json:"type,omitempty"`
844+
typefieldSelectionOptionsstruct {
845+
// Specific list of field IDs to include in the response. If not provided, only the title field is included.
846+
// The comma tag encodes the slice as comma-separated values: fields=102589,985201,169875
847+
Fields []int64`url:"fields,omitempty,comma"`
875848
}
876849

877850
typeupdateProjectItemPayloadstruct {
@@ -883,17 +856,6 @@ type updateProjectItem struct {
883856
Valueany`json:"value"`
884857
}
885858

886-
typeprojectV2Fieldstruct {
887-
ID*int64`json:"id,omitempty"`// The unique identifier for this field.
888-
NodeIDstring`json:"node_id,omitempty"`// The GraphQL node ID for this field.
889-
Namestring`json:"name,omitempty"`// The display name of the field.
890-
DataTypestring`json:"data_type,omitempty"`// The data type of the field (e.g., "text", "number", "date", "single_select", "multi_select").
891-
URLstring`json:"url,omitempty"`// The API URL for this field.
892-
Options []*any`json:"options,omitempty"`// Available options for single_select and multi_select fields.
893-
CreatedAt*github.Timestamp`json:"created_at,omitempty"`// The time when this field was created.
894-
UpdatedAt*github.Timestamp`json:"updated_at,omitempty"`// The time when this field was last updated.
895-
}
896-
897859
typeprojectV2ItemFieldValuestruct {
898860
ID*int64`json:"id,omitempty"`// The unique identifier for this field.
899861
Namestring`json:"name,omitempty"`// The display name of the field.
@@ -931,26 +893,6 @@ type projectV2ItemContent struct {
931893
URL*string`json:"url,omitempty"`
932894
}
933895

934-
typepaginationOptionsstruct {
935-
PerPageint`url:"per_page,omitempty"`
936-
}
937-
938-
typefilterQueryOptionsstruct {
939-
Querystring`url:"q,omitempty"`
940-
}
941-
942-
typefieldSelectionOptionsstruct {
943-
// Specific list of field IDs to include in the response. If not provided, only the title field is included.
944-
// Example: fields=102589,985201,169875 or fields[]=102589&fields[]=985201&fields[]=169875
945-
Fields []string`url:"fields,omitempty"`
946-
}
947-
948-
typelistProjectItemsOptionsstruct {
949-
paginationOptions
950-
filterQueryOptions
951-
fieldSelectionOptions
952-
}
953-
954896
functoNewProjectType(projTypestring)string {
955897
switchstrings.ToLower(projType) {
956898
case"issue":
@@ -994,18 +936,28 @@ func addOptions(s string, opts any) (string, error) {
994936
returns,nil
995937
}
996938

997-
u,err:=url.Parse(s)
939+
origURL,err:=url.Parse(s)
998940
iferr!=nil {
999941
returns,err
1000942
}
1001943

1002-
qs,err:=query.Values(opts)
944+
origValues:=origURL.Query()
945+
946+
// Use the github.com/google/go-querystring library to parse the struct
947+
newValues,err:=query.Values(opts)
1003948
iferr!=nil {
1004949
returns,err
1005950
}
1006951

1007-
u.RawQuery=qs.Encode()
1008-
returnu.String(),nil
952+
// Merge the values
953+
forkey,values:=rangenewValues {
954+
for_,value:=rangevalues {
955+
origValues.Add(key,value)
956+
}
957+
}
958+
959+
origURL.RawQuery=origValues.Encode()
960+
returnorigURL.String(),nil
1009961
}
1010962

1011963
funcManageProjectItemsPrompt(t translations.TranslationHelperFunc) (tool mcp.Prompt,handler server.PromptHandlerFunc) {

‎pkg/github/projects_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ func Test_ListProjectItems(t *testing.T) {
653653
mock.EndpointPattern{Pattern:"/orgs/{org}/projectsV2/{project}/items",Method:http.MethodGet},
654654
http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
655655
q:=r.URL.Query()
656-
fieldParams:=q["fields"]
657-
iflen(fieldParams)==3&&fieldParams[0]=="123"&&fieldParams[1]=="456"&&fieldParams[2]=="789" {
656+
fieldParams:=q.Get("fields")
657+
iffieldParams=="123,456,789" {
658658
w.WriteHeader(http.StatusOK)
659659
_,_=w.Write(mock.MustMarshal(orgItems))
660660
return
@@ -852,8 +852,8 @@ func Test_GetProjectItem(t *testing.T) {
852852
mock.EndpointPattern{Pattern:"/orgs/{org}/projectsV2/{project}/items/{item_id}",Method:http.MethodGet},
853853
http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
854854
q:=r.URL.Query()
855-
fieldParams:=q["fields"]
856-
iflen(fieldParams)==2&&fieldParams[0]=="123"&&fieldParams[1]=="456" {
855+
fieldParams:=q.Get("fields")
856+
iffieldParams=="123,456" {
857857
w.WriteHeader(http.StatusOK)
858858
_,_=w.Write(mock.MustMarshal(orgItem))
859859
return

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp