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
52 changes: 52 additions & 0 deletions github/copilot_cloud_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2026 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
"context"
"encoding/json"
"fmt"
)

// CopilotCloudAgentConfiguration represents the Copilot cloud agent configuration for a repository.
type CopilotCloudAgentConfiguration struct {
Comment thread
maishivamhoo123 marked this conversation as resolved.
McpConfiguration *json.RawMessage `json:"mcp_configuration"`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for not catching this sooner, but it looks like we need a new initialism ("MCP") to be added to line 424 of tools/structfield/structfield.go (in sorted order) and then update this line as well. Note that json.RawMessage is already a reference type (it is a byte slice) and there is no need for a pointer here.

So this line needs to be:

Suggested change
McpConfiguration *json.RawMessage `json:"mcp_configuration"`
MCPConfiguration json.RawMessage `json:"mcp_configuration"`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmlewis thank you for your review !
Should we handle null values by storing literal null bytes, or should we implement a custom UnmarshalJSON to convert null to nil? The tests currently expect nil.

--- FAIL: TestCopilotCloudAgentConfiguration_Marshal (0.00s)
       --- FAIL: TestCopilotCloudAgentConfiguration_Marshal/empty_configuration (0.00s)
           copilot_cloud_agent_test.go:299: json.Unmarshal returned:
               &github.CopilotCloudAgentConfiguration{MCPConfiguration:json.RawMessage{0x6e, 0x75, 0x6c, 0x6c}, EnabledTools:(*github.CopilotCloudAgentEnabledTools)(nil), RequireActionsWorkflowApproval:false, IsFirewallEnabled:false, IsFirewallRecommendedAllowlistEnabled:false, CustomAllowlist:[]string(nil)}
               want:
               &github.CopilotCloudAgentConfiguration{MCPConfiguration:json.RawMessage(nil), EnabledTools:(*github.CopilotCloudAgentEnabledTools)(nil), RequireActionsWorkflowApproval:false, IsFirewallEnabled:false, IsFirewallRecommendedAllowlistEnabled:false, CustomAllowlist:[]string(nil)}
               diff:
                 &github.CopilotCloudAgentConfiguration{
               -       MCPConfiguration:               nil,
               +       MCPConfiguration:               json.RawMessage("null"),
                       EnabledTools:                   nil,
                       RequireActionsWorkflowApproval: false,
                       ... // 3 identical fields
                 }
       --- FAIL: TestCopilotCloudAgentConfiguration_Marshal/with_multiple_allowlist_entries (0.00s)
           copilot_cloud_agent_test.go:299: json.Unmarshal returned:
               &github.CopilotCloudAgentConfiguration{MCPConfiguration:json.RawMessage{0x6e, 0x75, 0x6c, 0x6c}, EnabledTools:(*github.CopilotCloudAgentEnabledTools)(0xc0045239dc), RequireActionsWorkflowApproval:false, IsFirewallEnabled:true, IsFirewallRecommendedAllowlistEnabled:true, CustomAllowlist:[]string{"example.com", "example.com", "example.com"}}
               want:
               &github.CopilotCloudAgentConfiguration{MCPConfiguration:json.RawMessage(nil), EnabledTools:(*github.CopilotCloudAgentEnabledTools)(0xc00359355c), RequireActionsWorkflowApproval:false, IsFirewallEnabled:true, IsFirewallRecommendedAllowlistEnabled:true, CustomAllowlist:[]string{"example.com", "example.com", "example.com"}}
               diff:
                 &github.CopilotCloudAgentConfiguration{
               -       MCPConfiguration:               nil,
               +       MCPConfiguration:               json.RawMessage("null"),
                       EnabledTools:                   &{},
                       RequireActionsWorkflowApproval: false,
                       ... // 3 identical fields
                 }
       --- FAIL: TestCopilotCloudAgentConfiguration_Marshal/with_all_settings_configured (0.00s)
           copilot_cloud_agent_test.go:299: json.Unmarshal returned:
               &github.CopilotCloudAgentConfiguration{MCPConfiguration:json.RawMessage{0x6e, 0x75, 0x6c, 0x6c}, EnabledTools:(*github.CopilotCloudAgentEnabledTools)(0xc00488f05c), RequireActionsWorkflowApproval:true, IsFirewallEnabled:false, IsFirewallRecommendedAllowlistEnabled:true, CustomAllowlist:[]string{"example.com"}}
               want:
               &github.CopilotCloudAgentConfiguration{MCPConfiguration:json.RawMessage(nil), EnabledTools:(*github.CopilotCloudAgentEnabledTools)(0xc0035934bc), RequireActionsWorkflowApproval:true, IsFirewallEnabled:false, IsFirewallRecommendedAllowlistEnabled:true, CustomAllowlist:[]string{"example.com"}}
               diff:
                 &github.CopilotCloudAgentConfiguration{
               -       MCPConfiguration:               nil,
               +       MCPConfiguration:               json.RawMessage("null"),
                       EnabledTools:                   &{Codeql: true, SecretScanning: true},
                       RequireActionsWorkflowApproval: true,
                       ... // 3 identical fields
                 }
   --- FAIL: TestCopilotService_GetCloudAgentConfiguration (0.00s)
       --- FAIL: TestCopilotService_GetCloudAgentConfiguration/all_tools_disabled (0.00s)
           copilot_cloud_agent_test.go:135: GetCloudAgentConfiguration returned &{MCPConfiguration:[110 117 108 108] EnabledTools:0xc0057c2dac RequireActionsWorkflowApproval:false IsFirewallEnabled:false IsFirewallRecommendedAllowlistEnabled:false CustomAllowlist:[]}, want &{MCPConfiguration:[] EnabledTools:0xc004eeb03c RequireActionsWorkflowApproval:false IsFirewallEnabled:false IsFirewallRecommendedAllowlistEnabled:false CustomAllowlist:[]}
       --- FAIL: TestCopilotService_GetCloudAgentConfiguration/with_custom_allowlist (0.00s)
           copilot_cloud_agent_test.go:135: GetCloudAgentConfiguration returned &{MCPConfiguration:[110 117 108 108] EnabledTools:0xc0047ccf3c RequireActionsWorkflowApproval:false IsFirewallEnabled:true IsFirewallRecommendedAllowlistEnabled:true CustomAllowlist:[example.com]}, want &{MCPConfiguration:[] EnabledTools:0xc004eeb02c RequireActionsWorkflowApproval:false IsFirewallEnabled:true IsFirewallRecommendedAllowlistEnabled:true CustomAllowlist:[example.com]}
       --- FAIL: TestCopilotService_GetCloudAgentConfiguration/with_null_mcp_configuration (0.00s)
           copilot_cloud_agent_test.go:135: GetCloudAgentConfiguration returned &{MCPConfiguration:[110 117 108 108] EnabledTools:0xc0036f5cec RequireActionsWorkflowApproval:true IsFirewallEnabled:true IsFirewallRecommendedAllowlistEnabled:true CustomAllowlist:[]}, want &{MCPConfiguration:[] EnabledTools:0xc004eeb01c RequireActionsWorkflowApproval:true IsFirewallEnabled:true IsFirewallRecommendedAllowlistEnabled:true CustomAllowlist:[]}
   FAIL
   coverage: 99.3% of statements
   FAIL        github.com/google/go-github/v88/github  3.601s
       github.com/google/go-github/v88/test/fields             coverage: 0.0% of statements
   ?           github.com/google/go-github/v88/test/integration        [no test files]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, since this is a required field, it looks like the custom Unmarshaler is going to be needed. Agreed, @alexandear?

EnabledTools *CopilotCloudAgentEnabledTools `json:"enabled_tools"`
RequireActionsWorkflowApproval bool `json:"require_actions_workflow_approval"`
IsFirewallEnabled bool `json:"is_firewall_enabled"`
IsFirewallRecommendedAllowlistEnabled bool `json:"is_firewall_recommended_allowlist_enabled"`
CustomAllowlist []string `json:"custom_allowlist"`
}

// CopilotCloudAgentEnabledTools represents the enabled review tools for Copilot cloud agent.
type CopilotCloudAgentEnabledTools struct {
Codeql bool `json:"codeql"`
CopilotCodeReview bool `json:"copilot_code_review"`
SecretScanning bool `json:"secret_scanning"`
DependencyVulnerabilityChecks bool `json:"dependency_vulnerability_checks"`
}

// GetCloudAgentConfiguration gets the Copilot cloud agent configuration for a repository.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-cloud-agent-management?apiVersion=2022-11-28#get-copilot-cloud-agent-configuration-for-a-repository
Comment thread
maishivamhoo123 marked this conversation as resolved.
//
//meta:operation GET /repos/{owner}/{repo}/copilot/cloud-agent/configuration
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)
if err != nil {
return nil, nil, err
}

var config *CopilotCloudAgentConfiguration
resp, err := s.client.Do(req, &config)
Comment thread
maishivamhoo123 marked this conversation as resolved.
if err != nil {
return nil, resp, err
}

return config, resp, nil
}
Loading
Loading