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

Commitabe06cd

Browse files
committed
switch to approach that does commit signing
1 parenta5b1c9d commitabe06cd

File tree

2 files changed

+143
-74
lines changed

2 files changed

+143
-74
lines changed

‎pkg/github/repositories.go

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -585,10 +585,6 @@ func DeleteFile(getClient GetClientFn, t translations.TranslationHelperFunc) (to
585585
mcp.Required(),
586586
mcp.Description("Branch to delete the file from"),
587587
),
588-
mcp.WithString("sha",
589-
mcp.Required(),
590-
mcp.Description("SHA of the file being deleted"),
591-
),
592588
),
593589
func(ctx context.Context,request mcp.CallToolRequest) (*mcp.CallToolResult,error) {
594590
owner,err:=requiredParam[string](request,"owner")
@@ -611,38 +607,70 @@ func DeleteFile(getClient GetClientFn, t translations.TranslationHelperFunc) (to
611607
iferr!=nil {
612608
returnmcp.NewToolResultError(err.Error()),nil
613609
}
614-
sha,err:=requiredParam[string](request,"sha")
610+
611+
client,err:=getClient(ctx)
615612
iferr!=nil {
616-
returnmcp.NewToolResultError(err.Error()),nil
613+
returnnil,fmt.Errorf("failed to get GitHub client: %w",err)
617614
}
618615

619-
// Create the file options
620-
opts:=&github.RepositoryContentFileOptions{
621-
Message:github.Ptr(message),
622-
Branch:github.Ptr(branch),
623-
SHA:github.Ptr(sha),
616+
// Get the reference for the branch
617+
ref,resp,err:=client.Git.GetRef(ctx,owner,repo,"refs/heads/"+branch)
618+
iferr!=nil {
619+
returnnil,fmt.Errorf("failed to get branch reference: %w",err)
624620
}
621+
deferfunc() {_=resp.Body.Close() }()
625622

626-
//Delete thefile
627-
client,err:=getClient(ctx)
623+
//Get thecommit object that the branch points to
624+
baseCommit,resp,err:=client.Git.GetCommit(ctx,owner,repo,*ref.Object.SHA)
628625
iferr!=nil {
629-
returnnil,fmt.Errorf("failed to getGitHub client: %w",err)
626+
returnnil,fmt.Errorf("failed to getbase commit: %w",err)
630627
}
631-
deleteResponse,resp,err:=client.Repositories.DeleteFile(ctx,owner,repo,path,opts)
628+
deferfunc() {_=resp.Body.Close() }()
629+
630+
// Create a tree entry for the file deletion by setting SHA to nil
631+
treeEntries:= []*github.TreeEntry{
632+
{
633+
Path:github.Ptr(path),
634+
Mode:github.Ptr("100644"),// Regular file mode
635+
Type:github.Ptr("blob"),
636+
SHA:nil,// Setting SHA to nil deletes the file
637+
},
638+
}
639+
640+
// Create a new tree with the deletion
641+
newTree,resp,err:=client.Git.CreateTree(ctx,owner,repo,*baseCommit.Tree.SHA,treeEntries)
632642
iferr!=nil {
633-
returnnil,fmt.Errorf("failed todelete file: %w",err)
643+
returnnil,fmt.Errorf("failed tocreate tree: %w",err)
634644
}
635645
deferfunc() {_=resp.Body.Close() }()
636646

637-
ifresp.StatusCode!=200&&resp.StatusCode!=204 {
638-
body,err:=io.ReadAll(resp.Body)
639-
iferr!=nil {
640-
returnnil,fmt.Errorf("failed to read response body: %w",err)
641-
}
642-
returnmcp.NewToolResultError(fmt.Sprintf("failed to delete file: %s",string(body))),nil
647+
// Create a new commit with the new tree
648+
commit:=&github.Commit{
649+
Message:github.Ptr(message),
650+
Tree:newTree,
651+
Parents: []*github.Commit{{SHA:baseCommit.SHA}},
652+
}
653+
newCommit,resp,err:=client.Git.CreateCommit(ctx,owner,repo,commit,nil)
654+
iferr!=nil {
655+
returnnil,fmt.Errorf("failed to create commit: %w",err)
656+
}
657+
deferfunc() {_=resp.Body.Close() }()
658+
659+
// Update the branch reference to point to the new commit
660+
ref.Object.SHA=newCommit.SHA
661+
_,resp,err=client.Git.UpdateRef(ctx,owner,repo,ref,false)
662+
iferr!=nil {
663+
returnnil,fmt.Errorf("failed to update reference: %w",err)
664+
}
665+
deferfunc() {_=resp.Body.Close() }()
666+
667+
// Create a response similar to what the DeleteFile API would return
668+
response:=map[string]interface{}{
669+
"commit":newCommit,
670+
"content":nil,
643671
}
644672

645-
r,err:=json.Marshal(deleteResponse)
673+
r,err:=json.Marshal(response)
646674
iferr!=nil {
647675
returnnil,fmt.Errorf("failed to marshal response: %w",err)
648676
}

‎pkg/github/repositories_test.go

Lines changed: 92 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,49 +1541,96 @@ func Test_DeleteFile(t *testing.T) {
15411541
assert.Contains(t,tool.InputSchema.Properties,"path")
15421542
assert.Contains(t,tool.InputSchema.Properties,"message")
15431543
assert.Contains(t,tool.InputSchema.Properties,"branch")
1544-
assert.Contains(t,tool.InputSchema.Properties,"sha")
1545-
assert.ElementsMatch(t,tool.InputSchema.Required, []string{"owner","repo","path","message","branch","sha"})
1544+
// SHA is no longer required since we're using Git Data API
1545+
assert.ElementsMatch(t,tool.InputSchema.Required, []string{"owner","repo","path","message","branch"})
15461546

1547-
// Setup mock delete response
1548-
mockDeleteResponse:=&github.RepositoryContentResponse{
1549-
Content:&github.RepositoryContent{
1550-
Name:github.Ptr("example.md"),
1551-
Path:github.Ptr("docs/example.md"),
1552-
SHA:github.Ptr("abc123def456"),
1553-
HTMLURL:github.Ptr("https://github.com/owner/repo/blob/main/docs/example.md"),
1547+
// Setup mock objects for Git Data API
1548+
mockRef:=&github.Reference{
1549+
Ref:github.Ptr("refs/heads/main"),
1550+
Object:&github.GitObject{
1551+
SHA:github.Ptr("abc123"),
15541552
},
1555-
Commit: github.Commit{
1556-
SHA:github.Ptr("def456abc789"),
1557-
Message:github.Ptr("Delete example file"),
1558-
Author:&github.CommitAuthor{
1559-
Name:github.Ptr("Test User"),
1560-
Email:github.Ptr("test@example.com"),
1561-
Date:&github.Timestamp{Time:time.Now()},
1562-
},
1563-
HTMLURL:github.Ptr("https://github.com/owner/repo/commit/def456abc789"),
1553+
}
1554+
1555+
mockCommit:=&github.Commit{
1556+
SHA:github.Ptr("abc123"),
1557+
Tree:&github.Tree{
1558+
SHA:github.Ptr("def456"),
15641559
},
15651560
}
15661561

1562+
mockTree:=&github.Tree{
1563+
SHA:github.Ptr("ghi789"),
1564+
}
1565+
1566+
mockNewCommit:=&github.Commit{
1567+
SHA:github.Ptr("jkl012"),
1568+
Message:github.Ptr("Delete example file"),
1569+
HTMLURL:github.Ptr("https://github.com/owner/repo/commit/jkl012"),
1570+
}
1571+
15671572
tests:= []struct {
1568-
namestring
1569-
mockedClient*http.Client
1570-
requestArgsmap[string]interface{}
1571-
expectErrorbool
1572-
expectedResult*github.RepositoryContentResponse
1573-
expectedErrMsgstring
1573+
namestring
1574+
mockedClient*http.Client
1575+
requestArgsmap[string]interface{}
1576+
expectErrorbool
1577+
expectedCommitSHAstring
1578+
expectedErrMsgstring
15741579
}{
15751580
{
1576-
name:"successful file deletion",
1581+
name:"successful file deletion using Git Data API",
15771582
mockedClient:mock.NewMockedHTTPClient(
1583+
// Get branch reference
1584+
mock.WithRequestMatch(
1585+
mock.GetReposGitRefByOwnerByRepoByRef,
1586+
mockRef,
1587+
),
1588+
// Get commit
1589+
mock.WithRequestMatch(
1590+
mock.GetReposGitCommitsByOwnerByRepoByCommitSha,
1591+
mockCommit,
1592+
),
1593+
// Create tree
1594+
mock.WithRequestMatchHandler(
1595+
mock.PostReposGitTreesByOwnerByRepo,
1596+
expectRequestBody(t,map[string]interface{}{
1597+
"base_tree":"def456",
1598+
"tree": []interface{}{
1599+
map[string]interface{}{
1600+
"path":"docs/example.md",
1601+
"mode":"100644",
1602+
"type":"blob",
1603+
"sha":nil,
1604+
},
1605+
},
1606+
}).andThen(
1607+
mockResponse(t,http.StatusCreated,mockTree),
1608+
),
1609+
),
1610+
// Create commit
15781611
mock.WithRequestMatchHandler(
1579-
mock.DeleteReposContentsByOwnerByRepoByPath,
1612+
mock.PostReposGitCommitsByOwnerByRepo,
15801613
expectRequestBody(t,map[string]interface{}{
15811614
"message":"Delete example file",
1582-
"branch":"main",
1583-
"sha":"abc123def456",
1584-
"content":interface{}(nil),
1615+
"tree":"ghi789",
1616+
"parents": []interface{}{"abc123"},
1617+
}).andThen(
1618+
mockResponse(t,http.StatusCreated,mockNewCommit),
1619+
),
1620+
),
1621+
// Update reference
1622+
mock.WithRequestMatchHandler(
1623+
mock.PatchReposGitRefsByOwnerByRepoByRef,
1624+
expectRequestBody(t,map[string]interface{}{
1625+
"sha":"jkl012",
1626+
"force":false,
15851627
}).andThen(
1586-
mockResponse(t,http.StatusOK,mockDeleteResponse),
1628+
mockResponse(t,http.StatusOK,&github.Reference{
1629+
Ref:github.Ptr("refs/heads/main"),
1630+
Object:&github.GitObject{
1631+
SHA:github.Ptr("jkl012"),
1632+
},
1633+
}),
15871634
),
15881635
),
15891636
),
@@ -1593,19 +1640,18 @@ func Test_DeleteFile(t *testing.T) {
15931640
"path":"docs/example.md",
15941641
"message":"Delete example file",
15951642
"branch":"main",
1596-
"sha":"abc123def456",
15971643
},
1598-
expectError:false,
1599-
expectedResult:mockDeleteResponse,
1644+
expectError:false,
1645+
expectedCommitSHA:"jkl012",
16001646
},
16011647
{
1602-
name:"file deletion fails",
1648+
name:"file deletion fails - branch not found",
16031649
mockedClient:mock.NewMockedHTTPClient(
16041650
mock.WithRequestMatchHandler(
1605-
mock.DeleteReposContentsByOwnerByRepoByPath,
1651+
mock.GetReposGitRefByOwnerByRepoByRef,
16061652
http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {
16071653
w.WriteHeader(http.StatusNotFound)
1608-
_,_=w.Write([]byte(`{"message": "Not Found"}`))
1654+
_,_=w.Write([]byte(`{"message": "Reference not found"}`))
16091655
}),
16101656
),
16111657
),
@@ -1614,11 +1660,10 @@ func Test_DeleteFile(t *testing.T) {
16141660
"repo":"repo",
16151661
"path":"docs/nonexistent.md",
16161662
"message":"Delete nonexistent file",
1617-
"branch":"main",
1618-
"sha":"abc123def456",
1663+
"branch":"nonexistent-branch",
16191664
},
16201665
expectError:true,
1621-
expectedErrMsg:"failed todelete file",
1666+
expectedErrMsg:"failed toget branch reference",
16221667
},
16231668
}
16241669

@@ -1647,20 +1692,16 @@ func Test_DeleteFile(t *testing.T) {
16471692
textContent:=getTextResult(t,result)
16481693

16491694
// Unmarshal and verify the result
1650-
varreturnedContent github.RepositoryContentResponse
1651-
err=json.Unmarshal([]byte(textContent.Text),&returnedContent)
1695+
varresponsemap[string]interface{}
1696+
err=json.Unmarshal([]byte(textContent.Text),&response)
16521697
require.NoError(t,err)
16531698

1654-
// Verify content
1655-
iftc.expectedResult.Content!=nil {
1656-
assert.Equal(t,*tc.expectedResult.Content.Name,*returnedContent.Content.Name)
1657-
assert.Equal(t,*tc.expectedResult.Content.Path,*returnedContent.Content.Path)
1658-
assert.Equal(t,*tc.expectedResult.Content.SHA,*returnedContent.Content.SHA)
1659-
}
1660-
1661-
// Verify commit
1662-
assert.Equal(t,*tc.expectedResult.Commit.SHA,*returnedContent.Commit.SHA)
1663-
assert.Equal(t,*tc.expectedResult.Commit.Message,*returnedContent.Commit.Message)
1699+
// Verify the response contains the expected commit
1700+
commit,ok:=response["commit"].(map[string]interface{})
1701+
require.True(t,ok)
1702+
commitSHA,ok:=commit["sha"].(string)
1703+
require.True(t,ok)
1704+
assert.Equal(t,tc.expectedCommitSHA,commitSHA)
16641705
})
16651706
}
16661707
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp