@@ -369,3 +369,148 @@ func TestTags(t *testing.T) {
369369 require .Equal (t , "v0.0.1" , trimmedTag [0 ].Name , "expected tag name to match" )
370370 require .Equal (t , * ref .Object .SHA , trimmedTag [0 ].Commit .SHA , "expected tag SHA to match" )
371371}
372+
373+ func TestRequestCopilotReview (t * testing.T ) {
374+ t .Parallel ()
375+
376+ mcpClient := setupMCPClient (t )
377+
378+ ctx := context .Background ()
379+
380+ // First, who am I
381+ getMeRequest := mcp.CallToolRequest {}
382+ getMeRequest .Params .Name = "get_me"
383+
384+ t .Log ("Getting current user..." )
385+ resp , err := mcpClient .CallTool (ctx , getMeRequest )
386+ require .NoError (t , err , "expected to call 'get_me' tool successfully" )
387+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
388+
389+ require .False (t , resp .IsError , "expected result not to be an error" )
390+ require .Len (t , resp .Content , 1 , "expected content to have one item" )
391+
392+ textContent , ok := resp .Content [0 ].(mcp.TextContent )
393+ require .True (t , ok , "expected content to be of type TextContent" )
394+
395+ var trimmedGetMeText struct {
396+ Login string `json:"login"`
397+ }
398+ err = json .Unmarshal ([]byte (textContent .Text ), & trimmedGetMeText )
399+ require .NoError (t , err , "expected to unmarshal text content successfully" )
400+
401+ currentOwner := trimmedGetMeText .Login
402+
403+ // Then create a repository with a README (via autoInit)
404+ repoName := fmt .Sprintf ("github-mcp-server-e2e-%s-%d" , t .Name (), time .Now ().UnixMilli ())
405+ createRepoRequest := mcp.CallToolRequest {}
406+ createRepoRequest .Params .Name = "create_repository"
407+ createRepoRequest .Params .Arguments = map [string ]any {
408+ "name" : repoName ,
409+ "private" : true ,
410+ "autoInit" : true ,
411+ }
412+
413+ t .Logf ("Creating repository %s/%s..." , currentOwner , repoName )
414+ _ , err = mcpClient .CallTool (ctx , createRepoRequest )
415+ require .NoError (t , err , "expected to call 'get_me' tool successfully" )
416+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
417+
418+ // Cleanup the repository after the test
419+ t .Cleanup (func () {
420+ // MCP Server doesn't support deletions, but we can use the GitHub Client
421+ ghClient := gogithub .NewClient (nil ).WithAuthToken (getE2EToken (t ))
422+ t .Logf ("Deleting repository %s/%s..." , currentOwner , repoName )
423+ _ , err := ghClient .Repositories .Delete (context .Background (), currentOwner , repoName )
424+ require .NoError (t , err , "expected to delete repository successfully" )
425+ })
426+
427+ // Create a branch on which to create a new commit
428+ createBranchRequest := mcp.CallToolRequest {}
429+ createBranchRequest .Params .Name = "create_branch"
430+ createBranchRequest .Params .Arguments = map [string ]any {
431+ "owner" : currentOwner ,
432+ "repo" : repoName ,
433+ "branch" : "test-branch" ,
434+ "from_branch" : "main" ,
435+ }
436+
437+ t .Logf ("Creating branch in %s/%s..." , currentOwner , repoName )
438+ resp , err = mcpClient .CallTool (ctx , createBranchRequest )
439+ require .NoError (t , err , "expected to call 'create_branch' tool successfully" )
440+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
441+
442+ // Create a commit with a new file
443+ commitRequest := mcp.CallToolRequest {}
444+ commitRequest .Params .Name = "create_or_update_file"
445+ commitRequest .Params .Arguments = map [string ]any {
446+ "owner" : currentOwner ,
447+ "repo" : repoName ,
448+ "path" : "test-file.txt" ,
449+ "content" : fmt .Sprintf ("Created by e2e test %s" , t .Name ()),
450+ "message" : "Add test file" ,
451+ "branch" : "test-branch" ,
452+ }
453+
454+ t .Logf ("Creating commit with new file in %s/%s..." , currentOwner , repoName )
455+ resp , err = mcpClient .CallTool (ctx , commitRequest )
456+ require .NoError (t , err , "expected to call 'create_or_update_file' tool successfully" )
457+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
458+
459+ textContent , ok = resp .Content [0 ].(mcp.TextContent )
460+ require .True (t , ok , "expected content to be of type TextContent" )
461+
462+ var trimmedCommitText struct {
463+ SHA string `json:"sha"`
464+ }
465+ err = json .Unmarshal ([]byte (textContent .Text ), & trimmedCommitText )
466+ require .NoError (t , err , "expected to unmarshal text content successfully" )
467+ commitId := trimmedCommitText .SHA
468+
469+ // Create a pull request
470+ prRequest := mcp.CallToolRequest {}
471+ prRequest .Params .Name = "create_pull_request"
472+ prRequest .Params .Arguments = map [string ]any {
473+ "owner" : currentOwner ,
474+ "repo" : repoName ,
475+ "title" : "Test PR" ,
476+ "body" : "This is a test PR" ,
477+ "head" : "test-branch" ,
478+ "base" : "main" ,
479+ "commitId" : commitId ,
480+ }
481+
482+ t .Logf ("Creating pull request in %s/%s..." , currentOwner , repoName )
483+ resp , err = mcpClient .CallTool (ctx , prRequest )
484+ require .NoError (t , err , "expected to call 'create_pull_request' tool successfully" )
485+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
486+
487+ // Request a copilot review
488+ requestCopilotReviewRequest := mcp.CallToolRequest {}
489+ requestCopilotReviewRequest .Params .Name = "request_copilot_review"
490+ requestCopilotReviewRequest .Params .Arguments = map [string ]any {
491+ "owner" : currentOwner ,
492+ "repo" : repoName ,
493+ "pullNumber" : 1 ,
494+ }
495+
496+ t .Logf ("Requesting Copilot review for pull request in %s/%s..." , currentOwner , repoName )
497+ resp , err = mcpClient .CallTool (ctx , requestCopilotReviewRequest )
498+ require .NoError (t , err , "expected to call 'request_copilot_review' tool successfully" )
499+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
500+
501+ textContent , ok = resp .Content [0 ].(mcp.TextContent )
502+ require .True (t , ok , "expected content to be of type TextContent" )
503+ require .Equal (t , "" , textContent .Text , "expected content to be empty" )
504+
505+ // Finally, get requested reviews and see copilot is in there
506+ // MCP Server doesn't support requesting reviews yet, but we can use the GitHub Client
507+ ghClient := gogithub .NewClient (nil ).WithAuthToken (getE2EToken (t ))
508+ t .Logf ("Getting reviews for pull request in %s/%s..." , currentOwner , repoName )
509+ reviewRequests , _ , err := ghClient .PullRequests .ListReviewers (context .Background (), currentOwner , repoName , 1 , nil )
510+ require .NoError (t , err , "expected to get review requests successfully" )
511+
512+ // Check that there is one review request from copilot
513+ require .Len (t , reviewRequests .Users , 1 , "expected to find one review request" )
514+ require .Equal (t , "Copilot" , * reviewRequests .Users [0 ].Login , "expected review request to be for Copilot" )
515+ require .Equal (t , "Bot" , * reviewRequests .Users [0 ].Type , "expected review request to be for Bot" )
516+ }
0 commit comments