Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion github/copilot_cloud_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,27 @@ type CopilotCloudAgentEnabledTools struct {
func (s *CopilotService) GetCloudAgentConfiguration(ctx context.Context, owner, repo string) (*CopilotCloudAgentConfiguration, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/copilot/cloud-agent/configuration", owner, repo)

req, err := s.client.NewRequest(ctx, "GET", u, nil)
req, err := s.client.NewRequest(ctx, "GET", u, nil, WithVersion(api20260310))
if err != nil {
return nil, nil, err
}

var config *CopilotCloudAgentConfiguration
resp, err := s.client.Do(req, &config)
if err != nil {
return nil, resp, err
}

return config, resp, nil
}

// UpdateCloudAgentConfiguration updates the Copilot cloud agent configuration for a repository.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-cloud-agent-repository-management?apiVersion=2026-03-10#update-copilot-cloud-agent-configuration-for-a-repository
func (s *CopilotService) UpdateCloudAgentConfiguration(ctx context.Context, owner, repo string, opts *CopilotCloudAgentConfiguration) (*CopilotCloudAgentConfiguration, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/copilot/cloud-agent/configuration", owner, repo)

req, err := s.client.NewRequest(ctx, "PATCH", u, opts, WithVersion(api20260310))
if err != nil {
return nil, nil, err
}
Expand Down
113 changes: 113 additions & 0 deletions github/copilot_cloud_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ func TestCopilotService_GetCloudAgentConfiguration(t *testing.T) {

mux.HandleFunc("/repos/o/r/copilot/cloud-agent/configuration", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "X-Github-Api-Version", api20260310)
fmt.Fprint(w, tt.responseBody)
})

Expand Down Expand Up @@ -237,3 +238,115 @@ func TestCopilotService_GetCloudAgentConfiguration_MalformedJSON(t *testing.T) {
t.Errorf("GetCloudAgentConfiguration should return nil on error, got %+v", config)
}
}

func TestCopilotService_UpdateCloudAgentConfiguration(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := &CopilotCloudAgentConfiguration{
MCPConfiguration: map[string]any{
"type": "resource",
"uri": "stdio://server",
},
EnabledTools: &CopilotCloudAgentEnabledTools{
Codeql: true,
CopilotCodeReview: true,
},
RequireActionsWorkflowApproval: true,
IsFirewallEnabled: true,
IsFirewallRecommendedAllowlistEnabled: true,
CustomAllowlist: []string{"example.com"},
}

mux.HandleFunc("/repos/o/r/copilot/cloud-agent/configuration", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testHeader(t, r, "X-Github-Api-Version", api20260310)
testJSONBody(t, r, input)
fmt.Fprint(w, `{
"mcp_configuration": {
"type": "resource",
"uri": "stdio://server"
},
"enabled_tools": {
"codeql": true,
"copilot_code_review": true,
"secret_scanning": false,
"dependency_vulnerability_checks": false
},
"require_actions_workflow_approval": true,
"is_firewall_enabled": true,
"is_firewall_recommended_allowlist_enabled": true,
"custom_allowlist": ["example.com"]
}`)
})

ctx := t.Context()
config, _, err := client.Copilot.UpdateCloudAgentConfiguration(ctx, "o", "r", input)
if err != nil {
t.Errorf("UpdateCloudAgentConfiguration returned error: %v", err)
}

want := &CopilotCloudAgentConfiguration{
MCPConfiguration: map[string]any{
"type": "resource",
"uri": "stdio://server",
},
EnabledTools: &CopilotCloudAgentEnabledTools{
Codeql: true,
CopilotCodeReview: true,
},
RequireActionsWorkflowApproval: true,
IsFirewallEnabled: true,
IsFirewallRecommendedAllowlistEnabled: true,
CustomAllowlist: []string{"example.com"},
}

if !cmp.Equal(config, want) {
t.Errorf("UpdateCloudAgentConfiguration returned %+v, want %+v", config, want)
}
}

func TestCopilotService_UpdateCloudAgentConfiguration_BadOptions(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
const methodName = "UpdateCloudAgentConfiguration"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Copilot.UpdateCloudAgentConfiguration(ctx, "\n", "\n", nil)
return err
})
}

func TestCopilotService_UpdateCloudAgentConfiguration_NewRequestFailure(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

const methodName = "UpdateCloudAgentConfiguration"
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
ctx := t.Context()
got, resp, err := client.Copilot.UpdateCloudAgentConfiguration(ctx, "o", "r", nil)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestCopilotService_UpdateCloudAgentConfiguration_InvalidOwner(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, _, err := client.Copilot.UpdateCloudAgentConfiguration(ctx, "%", "r", nil)
testURLParseError(t, err)
}

func TestCopilotService_UpdateCloudAgentConfiguration_InvalidRepo(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, _, err := client.Copilot.UpdateCloudAgentConfiguration(ctx, "o", "%", nil)
testURLParseError(t, err)
}
1 change: 1 addition & 0 deletions tools/metadata/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,4 +554,5 @@ var skipServiceMethod = map[string]bool{
"CopilotService.DownloadPeriodicMetrics": true,
"CopilotService.DownloadUserDailyMetrics": true,
"CopilotService.DownloadUserPeriodicMetrics": true,
"CopilotService.UpdateCloudAgentConfiguration": true,
}
Loading