Skip to content
Merged
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
102 changes: 102 additions & 0 deletions github/copilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,108 @@ func (s *CopilotService) ListOrganizationCodingAgentRepositories(ctx context.Con
return result, resp, nil
}

// CopilotCodingAgentPermissions represents which repositories in an organization can use the Copilot coding agent.
type CopilotCodingAgentPermissions struct {
// EnabledRepositories is one of "all", "selected" or "none".
EnabledRepositories string `json:"enabled_repositories"`
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
}

// CopilotCodingAgentPermissionsRequest represents the request body to set the Copilot coding agent permissions for an organization.
type CopilotCodingAgentPermissionsRequest struct {
// EnabledRepositories is one of "all", "selected" or "none".
EnabledRepositories string `json:"enabled_repositories"`
}

// GetOrganizationCodingAgentPermissions gets which repositories in an organization can use the Copilot coding agent.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-coding-agent-management?apiVersion=2022-11-28#get-copilot-cloud-agent-permissions-for-an-organization
//
//meta:operation GET /orgs/{org}/copilot/coding-agent/permissions
func (s *CopilotService) GetOrganizationCodingAgentPermissions(ctx context.Context, org string) (*CopilotCodingAgentPermissions, *Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/coding-agent/permissions", org)

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

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

return permissions, resp, nil
}

// SetOrganizationCodingAgentPermissions sets which repositories in an organization can use the Copilot coding agent.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-coding-agent-management?apiVersion=2022-11-28#set-copilot-cloud-agent-permissions-for-an-organization
//
//meta:operation PUT /orgs/{org}/copilot/coding-agent/permissions
func (s *CopilotService) SetOrganizationCodingAgentPermissions(ctx context.Context, org string, body CopilotCodingAgentPermissionsRequest) (*Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/coding-agent/permissions", org)

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

return s.client.Do(req, nil)
}

// SetOrganizationCodingAgentRepositories replaces the list of repositories enabled for the Copilot coding agent in an organization.
// The organization's EnabledRepositories permission must be set to "selected".
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-coding-agent-management?apiVersion=2022-11-28#set-selected-repositories-for-copilot-cloud-agent-in-an-organization
//
//meta:operation PUT /orgs/{org}/copilot/coding-agent/permissions/repositories
func (s *CopilotService) SetOrganizationCodingAgentRepositories(ctx context.Context, org string, repositoryIDs []int64) (*Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/coding-agent/permissions/repositories", org)

req, err := s.client.NewRequest(ctx, "PUT", u, struct {
IDs []int64 `json:"selected_repository_ids"`
}{IDs: repositoryIDs})
if err != nil {
return nil, err
}

return s.client.Do(req, nil)
}

// EnableOrganizationCodingAgentRepository enables a repository for the Copilot coding agent in an organization.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-coding-agent-management?apiVersion=2022-11-28#enable-a-repository-for-copilot-cloud-agent-in-an-organization
//
//meta:operation PUT /orgs/{org}/copilot/coding-agent/permissions/repositories/{repository_id}
func (s *CopilotService) EnableOrganizationCodingAgentRepository(ctx context.Context, org string, repositoryID int64) (*Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/coding-agent/permissions/repositories/%v", org, repositoryID)

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

return s.client.Do(req, nil)
}

// DisableOrganizationCodingAgentRepository disables a repository for the Copilot coding agent in an organization.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-coding-agent-management?apiVersion=2022-11-28#disable-a-repository-for-copilot-cloud-agent-in-an-organization
//
//meta:operation DELETE /orgs/{org}/copilot/coding-agent/permissions/repositories/{repository_id}
func (s *CopilotService) DisableOrganizationCodingAgentRepository(ctx context.Context, org string, repositoryID int64) (*Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/coding-agent/permissions/repositories/%v", org, repositoryID)

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

return s.client.Do(req, nil)
}

// CopilotOrganizationContentExclusionDetails lists all Copilot content exclusion
// rules for an organization, keyed by repository full name. Each value is the
// list of file paths excluded from Copilot for that repository.
Expand Down
160 changes: 160 additions & 0 deletions github/copilot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,166 @@ func TestCopilotService_ListOrganizationCodingAgentRepositories(t *testing.T) {
})
}

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

mux.HandleFunc("/orgs/o/copilot/coding-agent/permissions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
"enabled_repositories": "selected",
"selected_repositories_url": "https://api.github.com/orgs/o/copilot/coding-agent/permissions/repositories"
}`)
})

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

want := &CopilotCodingAgentPermissions{
EnabledRepositories: "selected",
SelectedRepositoriesURL: new("https://api.github.com/orgs/o/copilot/coding-agent/permissions/repositories"),
}
if !cmp.Equal(got, want) {
t.Errorf("Copilot.GetOrganizationCodingAgentPermissions returned %+v, want %+v", got, want)
}

const methodName = "GetOrganizationCodingAgentPermissions"

testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Copilot.GetOrganizationCodingAgentPermissions(ctx, "\n")
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Copilot.GetOrganizationCodingAgentPermissions(ctx, "o")
if got != nil {
t.Errorf("Copilot.GetOrganizationCodingAgentPermissions returned %+v, want nil", got)
}
return resp, err
})
}

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

input := CopilotCodingAgentPermissionsRequest{EnabledRepositories: "all"}

mux.HandleFunc("/orgs/o/copilot/coding-agent/permissions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testJSONBody(t, r, input)
w.WriteHeader(http.StatusNoContent)
})

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

const methodName = "SetOrganizationCodingAgentPermissions"

testBadOptions(t, methodName, func() (err error) {
_, err = client.Copilot.SetOrganizationCodingAgentPermissions(ctx, "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Copilot.SetOrganizationCodingAgentPermissions(ctx, "o", input)
})
}

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

input := []int64{123, 1234}

mux.HandleFunc("/orgs/o/copilot/coding-agent/permissions/repositories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testJSONBody(t, r, struct {
IDs []int64 `json:"selected_repository_ids"`
}{
IDs: input,
})
w.WriteHeader(http.StatusNoContent)
})

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

const methodName = "SetOrganizationCodingAgentRepositories"

testBadOptions(t, methodName, func() (err error) {
_, err = client.Copilot.SetOrganizationCodingAgentRepositories(ctx, "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Copilot.SetOrganizationCodingAgentRepositories(ctx, "o", input)
})
}

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

mux.HandleFunc("/orgs/o/copilot/coding-agent/permissions/repositories/123", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
w.WriteHeader(http.StatusNoContent)
})

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

const methodName = "EnableOrganizationCodingAgentRepository"

testBadOptions(t, methodName, func() (err error) {
_, err = client.Copilot.EnableOrganizationCodingAgentRepository(ctx, "\n", 123)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Copilot.EnableOrganizationCodingAgentRepository(ctx, "o", 123)
})
}

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

mux.HandleFunc("/orgs/o/copilot/coding-agent/permissions/repositories/123", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})

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

const methodName = "DisableOrganizationCodingAgentRepository"

testBadOptions(t, methodName, func() (err error) {
_, err = client.Copilot.DisableOrganizationCodingAgentRepository(ctx, "\n", 123)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Copilot.DisableOrganizationCodingAgentRepository(ctx, "o", 123)
})
}

func TestCopilotService_GetOrganizationContentExclusionDetails(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)
Expand Down
24 changes: 24 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading