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

Commit0568187

Browse files
Always include SHA in get_file_contents responses (#676)
* fix: Add SHA to get_file_contents while preserving MCP behavior (#595)Enhance get_file_contents to include SHA information without changingthe existing MCP server response format.Changes:- Add Contents API call to retrieve SHA before fetching raw content- Include SHA in resourceURI (repo://owner/repo/sha/{SHA}/contents/path)- Add SHA to success messages- Update tests to verify SHA inclusion- Maintain original behavior: text files return raw text, binaries return base64This preserves backward compatibility while providing SHA informationfor better file versioning support.Closes#595* fix: Improve error handling for Contents API responseEnsure response body is properly closed even when an error occurs by movingthe defer statement before the error check. This prevents potential resourceleaks when the Contents API returns an error with a non-nil response.Changes:- Move defer respContents.Body.Close() before error checking- Rename errContents to err for consistency- Add nil check for respContents before attempting to close bodyThis follows Go best practices for handling HTTP responses and preventspotential goroutine/memory leaks.* revert changes to resource URI* use GraphQL API to get file SHA* refactor: mock GQL client instead of getFileSHA function to follow conventions* lint* revert GraphQL---------Co-authored-by: LuluBeatson <lulubeatson@github.com>
1 parentbe91795 commit0568187

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

‎pkg/github/repositories.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,24 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t t
507507
// If the path is (most likely) not to be a directory, we will
508508
// first try to get the raw content from the GitHub raw content API.
509509
ifpath!=""&&!strings.HasSuffix(path,"/") {
510+
// First, get file info from Contents API to retrieve SHA
511+
varfileSHAstring
512+
opts:=&github.RepositoryContentGetOptions{Ref:ref}
513+
fileContent,_,respContents,err:=client.Repositories.GetContents(ctx,owner,repo,path,opts)
514+
ifrespContents!=nil {
515+
deferfunc() {_=respContents.Body.Close() }()
516+
}
517+
iferr!=nil {
518+
returnghErrors.NewGitHubAPIErrorResponse(ctx,
519+
"failed to get file SHA",
520+
respContents,
521+
err,
522+
),nil
523+
}
524+
iffileContent==nil||fileContent.SHA==nil {
525+
returnmcp.NewToolResultError("file content SHA is nil"),nil
526+
}
527+
fileSHA=*fileContent.SHA
510528

511529
rawClient,err:=getRawClient(ctx)
512530
iferr!=nil {
@@ -548,18 +566,28 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t t
548566
}
549567

550568
ifstrings.HasPrefix(contentType,"application")||strings.HasPrefix(contentType,"text") {
551-
returnmcp.NewToolResultResource("successfully downloaded text file", mcp.TextResourceContents{
569+
result:= mcp.TextResourceContents{
552570
URI:resourceURI,
553571
Text:string(body),
554572
MIMEType:contentType,
555-
}),nil
573+
}
574+
// Include SHA in the result metadata
575+
iffileSHA!="" {
576+
returnmcp.NewToolResultResource(fmt.Sprintf("successfully downloaded text file (SHA: %s)",fileSHA),result),nil
577+
}
578+
returnmcp.NewToolResultResource("successfully downloaded text file",result),nil
556579
}
557580

558-
returnmcp.NewToolResultResource("successfully downloaded binary file", mcp.BlobResourceContents{
581+
result:= mcp.BlobResourceContents{
559582
URI:resourceURI,
560583
Blob:base64.StdEncoding.EncodeToString(body),
561584
MIMEType:contentType,
562-
}),nil
585+
}
586+
// Include SHA in the result metadata
587+
iffileSHA!="" {
588+
returnmcp.NewToolResultResource(fmt.Sprintf("successfully downloaded binary file (SHA: %s)",fileSHA),result),nil
589+
}
590+
returnmcp.NewToolResultResource("successfully downloaded binary file",result),nil
563591

564592
}
565593
}

‎pkg/github/repositories_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ func Test_GetFileContents(t *testing.T) {
7676
_,_=w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`))
7777
}),
7878
),
79+
mock.WithRequestMatchHandler(
80+
mock.GetReposContentsByOwnerByRepoByPath,
81+
http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {
82+
w.WriteHeader(http.StatusOK)
83+
fileContent:=&github.RepositoryContent{
84+
Name:github.Ptr("README.md"),
85+
Path:github.Ptr("README.md"),
86+
SHA:github.Ptr("abc123"),
87+
Type:github.Ptr("file"),
88+
}
89+
contentBytes,_:=json.Marshal(fileContent)
90+
_,_=w.Write(contentBytes)
91+
}),
92+
),
7993
mock.WithRequestMatchHandler(
8094
raw.GetRawReposContentsByOwnerByRepoByBranchByPath,
8195
http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {
@@ -107,6 +121,20 @@ func Test_GetFileContents(t *testing.T) {
107121
_,_=w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`))
108122
}),
109123
),
124+
mock.WithRequestMatchHandler(
125+
mock.GetReposContentsByOwnerByRepoByPath,
126+
http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {
127+
w.WriteHeader(http.StatusOK)
128+
fileContent:=&github.RepositoryContent{
129+
Name:github.Ptr("test.png"),
130+
Path:github.Ptr("test.png"),
131+
SHA:github.Ptr("def456"),
132+
Type:github.Ptr("file"),
133+
}
134+
contentBytes,_:=json.Marshal(fileContent)
135+
_,_=w.Write(contentBytes)
136+
}),
137+
),
110138
mock.WithRequestMatchHandler(
111139
raw.GetRawReposContentsByOwnerByRepoByBranchByPath,
112140
http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp