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

Commit0fd4348

Browse files
authored
Merge branch 'main' into patch-1
2 parents15dccf1 +e4c2f58 commit0fd4348

16 files changed

+507
-203
lines changed

‎.github/workflows/code-scanning.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name:"CodeQL"
2+
run-name:${{ github.event.inputs.code_scanning_run_name }}
3+
on:[push, pull_request, workflow_dispatch]
4+
5+
concurrency:
6+
group:${{ github.workflow }}-${{ github.ref }}
7+
cancel-in-progress:true
8+
9+
env:
10+
CODE_SCANNING_REF:${{ github.event.inputs.code_scanning_ref }}
11+
CODE_SCANNING_BASE_BRANCH:${{ github.event.inputs.code_scanning_base_branch }}
12+
CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH:${{ github.event.inputs.code_scanning_is_analyzing_default_branch }}
13+
14+
jobs:
15+
analyze:
16+
name:Analyze (${{ matrix.language }})
17+
runs-on:${{ fromJSON(matrix.runner) }}
18+
permissions:
19+
actions:read
20+
contents:read
21+
packages:read
22+
security-events:write
23+
continue-on-error:false
24+
strategy:
25+
fail-fast:false
26+
matrix:
27+
include:
28+
-language:actions
29+
category:/language:actions
30+
build-mode:none
31+
runner:'["ubuntu-22.04"]'
32+
-language:go
33+
category:/language:go
34+
build-mode:autobuild
35+
runner:'["ubuntu-22.04"]'
36+
steps:
37+
-name:Checkout repository
38+
uses:actions/checkout@v4
39+
40+
-name:Initialize CodeQL
41+
uses:github/codeql-action/init@v3
42+
with:
43+
languages:${{ matrix.language }}
44+
build-mode:${{ matrix.build-mode }}
45+
dependency-caching:${{ runner.environment == 'github-hosted' }}
46+
queries:""# Default query suite
47+
packs:github/ccr-${{ matrix.language }}-queries
48+
config:|
49+
default-setup:
50+
org:
51+
model-packs: [ ${{ github.event.inputs.code_scanning_codeql_packs }} ]
52+
threat-models: [ ]
53+
-name:Setup proxy for registries
54+
id:proxy
55+
uses:github/codeql-action/start-proxy@v3
56+
with:
57+
registries_credentials:${{ secrets.GITHUB_REGISTRIES_PROXY }}
58+
language:${{ matrix.language }}
59+
60+
-name:Configure
61+
uses:github/codeql-action/resolve-environment@v3
62+
id:resolve-environment
63+
with:
64+
language:${{ matrix.language }}
65+
-name:Setup Go
66+
uses:actions/setup-go@v5
67+
if:matrix.language == 'go' && fromJSON(steps.resolve-environment.outputs.environment).configuration.go.version
68+
with:
69+
go-version:${{ fromJSON(steps.resolve-environment.outputs.environment).configuration.go.version }}
70+
cache:false
71+
72+
-name:Autobuild
73+
uses:github/codeql-action/autobuild@v3
74+
75+
-name:Perform CodeQL Analysis
76+
uses:github/codeql-action/analyze@v3
77+
env:
78+
CODEQL_PROXY_HOST:${{ steps.proxy.outputs.proxy_host }}
79+
CODEQL_PROXY_PORT:${{ steps.proxy.outputs.proxy_port }}
80+
CODEQL_PROXY_CA_CERTIFICATE:${{ steps.proxy.outputs.proxy_ca_certificate }}
81+
with:
82+
category:${{ matrix.category }}

‎README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description
153153
-`repo`: Repository name (string, required)
154154
-`issue_number`: Issue number (number, required)
155155

156+
-**get_issue_comments** - Get comments for a GitHub issue
157+
158+
-`owner`: Repository owner (string, required)
159+
-`repo`: Repository name (string, required)
160+
-`issue_number`: Issue number (number, required)
161+
156162
-**create_issue** - Create a new issue in a GitHub repository
157163

158164
-`owner`: Repository owner (string, required)
@@ -266,7 +272,9 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description
266272
-`body`: Review comment text (string, optional)
267273
-`event`: Review action ('APPROVE', 'REQUEST_CHANGES', 'COMMENT') (string, required)
268274
-`commitId`: SHA of commit to review (string, optional)
269-
-`comments`: Line-specific comments array of objects, each object with path (string), position (number), and body (string) (array, optional)
275+
-`comments`: Line-specific comments array of objects to place comments on pull request changes (array, optional)
276+
- For inline comments: provide`path`,`position` (or`line`), and`body`
277+
- For multi-line comments: provide`path`,`start_line`,`line`, optional`side`/`start_side`, and`body`
270278

271279
-**create_pull_request** - Create a new pull request
272280

‎cmd/mcpcurl/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Available Commands:
5050
fork_repository Fork a GitHub repository to your account or specified organization
5151
get_file_contents Get the contents of a file or directory from a GitHub repository
5252
get_issue Get details of a specific issuein a GitHub repository.
53+
get_issue_comments Get commentsfor a GitHub issue
5354
list_commits Get list of commits of a branchin a GitHub repository
5455
list_issues List issuesin a GitHub repository with filtering options
5556
push_files Push multiple files to a GitHub repositoryin a single commit

‎go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ module github.com/github/github-mcp-server
33
go1.23.7
44

55
require (
6-
github.com/aws/smithy-gov1.22.3
76
github.com/docker/dockerv28.0.4+incompatible
87
github.com/google/go-cmpv0.7.0
98
github.com/google/go-github/v69v69.2.0

‎go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl
22
github.com/Azure/go-ansitermv0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
33
github.com/Microsoft/go-winiov0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
44
github.com/Microsoft/go-winiov0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
5-
github.com/aws/smithy-gov1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
6-
github.com/aws/smithy-gov1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
75
github.com/cenkalti/backoff/v4v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
86
github.com/cenkalti/backoff/v4v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
97
github.com/containerd/logv0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=

‎pkg/github/issues.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,81 @@ func updateIssue(client *github.Client, t translations.TranslationHelperFunc) (t
597597
}
598598
}
599599

600+
// getIssueComments creates a tool to get comments for a GitHub issue.
601+
funcgetIssueComments(client*github.Client,t translations.TranslationHelperFunc) (tool mcp.Tool,handler server.ToolHandlerFunc) {
602+
returnmcp.NewTool("get_issue_comments",
603+
mcp.WithDescription(t("TOOL_GET_ISSUE_COMMENTS_DESCRIPTION","Get comments for a GitHub issue")),
604+
mcp.WithString("owner",
605+
mcp.Required(),
606+
mcp.Description("Repository owner"),
607+
),
608+
mcp.WithString("repo",
609+
mcp.Required(),
610+
mcp.Description("Repository name"),
611+
),
612+
mcp.WithNumber("issue_number",
613+
mcp.Required(),
614+
mcp.Description("Issue number"),
615+
),
616+
mcp.WithNumber("page",
617+
mcp.Description("Page number"),
618+
),
619+
mcp.WithNumber("per_page",
620+
mcp.Description("Number of records per page"),
621+
),
622+
),
623+
func(ctx context.Context,request mcp.CallToolRequest) (*mcp.CallToolResult,error) {
624+
owner,err:=requiredParam[string](request,"owner")
625+
iferr!=nil {
626+
returnmcp.NewToolResultError(err.Error()),nil
627+
}
628+
repo,err:=requiredParam[string](request,"repo")
629+
iferr!=nil {
630+
returnmcp.NewToolResultError(err.Error()),nil
631+
}
632+
issueNumber,err:=requiredInt(request,"issue_number")
633+
iferr!=nil {
634+
returnmcp.NewToolResultError(err.Error()),nil
635+
}
636+
page,err:=optionalIntParamWithDefault(request,"page",1)
637+
iferr!=nil {
638+
returnmcp.NewToolResultError(err.Error()),nil
639+
}
640+
perPage,err:=optionalIntParamWithDefault(request,"per_page",30)
641+
iferr!=nil {
642+
returnmcp.NewToolResultError(err.Error()),nil
643+
}
644+
645+
opts:=&github.IssueListCommentsOptions{
646+
ListOptions: github.ListOptions{
647+
Page:page,
648+
PerPage:perPage,
649+
},
650+
}
651+
652+
comments,resp,err:=client.Issues.ListComments(ctx,owner,repo,issueNumber,opts)
653+
iferr!=nil {
654+
returnnil,fmt.Errorf("failed to get issue comments: %w",err)
655+
}
656+
deferfunc() {_=resp.Body.Close() }()
657+
658+
ifresp.StatusCode!=http.StatusOK {
659+
body,err:=io.ReadAll(resp.Body)
660+
iferr!=nil {
661+
returnnil,fmt.Errorf("failed to read response body: %w",err)
662+
}
663+
returnmcp.NewToolResultError(fmt.Sprintf("failed to get issue comments: %s",string(body))),nil
664+
}
665+
666+
r,err:=json.Marshal(comments)
667+
iferr!=nil {
668+
returnnil,fmt.Errorf("failed to marshal response: %w",err)
669+
}
670+
671+
returnmcp.NewToolResultText(string(r)),nil
672+
}
673+
}
674+
600675
// parseISOTimestamp parses an ISO 8601 timestamp string into a time.Time object.
601676
// Returns the parsed time or an error if parsing fails.
602677
// Example formats supported: "2023-01-15T14:30:00Z", "2023-01-15"

‎pkg/github/issues_test.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,3 +984,137 @@ func Test_ParseISOTimestamp(t *testing.T) {
984984
})
985985
}
986986
}
987+
988+
funcTest_GetIssueComments(t*testing.T) {
989+
// Verify tool definition once
990+
mockClient:=github.NewClient(nil)
991+
tool,_:=getIssueComments(mockClient,translations.NullTranslationHelper)
992+
993+
assert.Equal(t,"get_issue_comments",tool.Name)
994+
assert.NotEmpty(t,tool.Description)
995+
assert.Contains(t,tool.InputSchema.Properties,"owner")
996+
assert.Contains(t,tool.InputSchema.Properties,"repo")
997+
assert.Contains(t,tool.InputSchema.Properties,"issue_number")
998+
assert.Contains(t,tool.InputSchema.Properties,"page")
999+
assert.Contains(t,tool.InputSchema.Properties,"per_page")
1000+
assert.ElementsMatch(t,tool.InputSchema.Required, []string{"owner","repo","issue_number"})
1001+
1002+
// Setup mock comments for success case
1003+
mockComments:= []*github.IssueComment{
1004+
{
1005+
ID:github.Ptr(int64(123)),
1006+
Body:github.Ptr("This is the first comment"),
1007+
User:&github.User{
1008+
Login:github.Ptr("user1"),
1009+
},
1010+
CreatedAt:&github.Timestamp{Time:time.Now().Add(-time.Hour*24)},
1011+
},
1012+
{
1013+
ID:github.Ptr(int64(456)),
1014+
Body:github.Ptr("This is the second comment"),
1015+
User:&github.User{
1016+
Login:github.Ptr("user2"),
1017+
},
1018+
CreatedAt:&github.Timestamp{Time:time.Now().Add(-time.Hour)},
1019+
},
1020+
}
1021+
1022+
tests:= []struct {
1023+
namestring
1024+
mockedClient*http.Client
1025+
requestArgsmap[string]interface{}
1026+
expectErrorbool
1027+
expectedComments []*github.IssueComment
1028+
expectedErrMsgstring
1029+
}{
1030+
{
1031+
name:"successful comments retrieval",
1032+
mockedClient:mock.NewMockedHTTPClient(
1033+
mock.WithRequestMatch(
1034+
mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber,
1035+
mockComments,
1036+
),
1037+
),
1038+
requestArgs:map[string]interface{}{
1039+
"owner":"owner",
1040+
"repo":"repo",
1041+
"issue_number":float64(42),
1042+
},
1043+
expectError:false,
1044+
expectedComments:mockComments,
1045+
},
1046+
{
1047+
name:"successful comments retrieval with pagination",
1048+
mockedClient:mock.NewMockedHTTPClient(
1049+
mock.WithRequestMatchHandler(
1050+
mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber,
1051+
expectQueryParams(t,map[string]string{
1052+
"page":"2",
1053+
"per_page":"10",
1054+
}).andThen(
1055+
mockResponse(t,http.StatusOK,mockComments),
1056+
),
1057+
),
1058+
),
1059+
requestArgs:map[string]interface{}{
1060+
"owner":"owner",
1061+
"repo":"repo",
1062+
"issue_number":float64(42),
1063+
"page":float64(2),
1064+
"per_page":float64(10),
1065+
},
1066+
expectError:false,
1067+
expectedComments:mockComments,
1068+
},
1069+
{
1070+
name:"issue not found",
1071+
mockedClient:mock.NewMockedHTTPClient(
1072+
mock.WithRequestMatchHandler(
1073+
mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber,
1074+
mockResponse(t,http.StatusNotFound,`{"message": "Issue not found"}`),
1075+
),
1076+
),
1077+
requestArgs:map[string]interface{}{
1078+
"owner":"owner",
1079+
"repo":"repo",
1080+
"issue_number":float64(999),
1081+
},
1082+
expectError:true,
1083+
expectedErrMsg:"failed to get issue comments",
1084+
},
1085+
}
1086+
1087+
for_,tc:=rangetests {
1088+
t.Run(tc.name,func(t*testing.T) {
1089+
// Setup client with mock
1090+
client:=github.NewClient(tc.mockedClient)
1091+
_,handler:=getIssueComments(client,translations.NullTranslationHelper)
1092+
1093+
// Create call request
1094+
request:=createMCPRequest(tc.requestArgs)
1095+
1096+
// Call handler
1097+
result,err:=handler(context.Background(),request)
1098+
1099+
// Verify results
1100+
iftc.expectError {
1101+
require.Error(t,err)
1102+
assert.Contains(t,err.Error(),tc.expectedErrMsg)
1103+
return
1104+
}
1105+
1106+
require.NoError(t,err)
1107+
textContent:=getTextResult(t,result)
1108+
1109+
// Unmarshal and verify the result
1110+
varreturnedComments []*github.IssueComment
1111+
err=json.Unmarshal([]byte(textContent.Text),&returnedComments)
1112+
require.NoError(t,err)
1113+
assert.Equal(t,len(tc.expectedComments),len(returnedComments))
1114+
iflen(returnedComments)>0 {
1115+
assert.Equal(t,*tc.expectedComments[0].Body,*returnedComments[0].Body)
1116+
assert.Equal(t,*tc.expectedComments[0].User.Login,*returnedComments[0].User.Login)
1117+
}
1118+
})
1119+
}
1120+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp