diff --git a/github/copilot.go b/github/copilot.go index 301a837b333..44e2a3e20b7 100644 --- a/github/copilot.go +++ b/github/copilot.go @@ -390,17 +390,25 @@ func (s *CopilotService) ListOrganizationCodingAgentRepositories(ctx context.Con return result, resp, 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. -type CopilotOrganizationContentExclusionDetails map[string][]string +// CopilotContentExclusionDetails lists Copilot content exclusion path rules, +// keyed by repository identifier. Each value is the list of file paths excluded +// from Copilot for that repository. +// +// NOTE Breaking API change: renamed from CopilotOrganizationContentExclusionDetails. +type CopilotContentExclusionDetails map[string][]string + +// CopilotContentExclusionUpdateResponse represents the response from setting +// Copilot content exclusion rules. +type CopilotContentExclusionUpdateResponse struct { + Message *string `json:"message,omitempty"` +} // GetOrganizationContentExclusionDetails gets the Copilot content exclusion rules for an organization. // // GitHub API docs: https://docs.github.com/rest/copilot/copilot-content-exclusion-management?apiVersion=2022-11-28#get-copilot-content-exclusion-rules-for-an-organization // //meta:operation GET /orgs/{org}/copilot/content_exclusion -func (s *CopilotService) GetOrganizationContentExclusionDetails(ctx context.Context, org string) (CopilotOrganizationContentExclusionDetails, *Response, error) { +func (s *CopilotService) GetOrganizationContentExclusionDetails(ctx context.Context, org string) (CopilotContentExclusionDetails, *Response, error) { u := fmt.Sprintf("orgs/%v/copilot/content_exclusion", org) req, err := s.client.NewRequest(ctx, "GET", u, nil) @@ -408,7 +416,51 @@ func (s *CopilotService) GetOrganizationContentExclusionDetails(ctx context.Cont return nil, nil, err } - details := CopilotOrganizationContentExclusionDetails{} + details := CopilotContentExclusionDetails{} + resp, err := s.client.Do(req, &details) + if err != nil { + return nil, resp, err + } + + return details, resp, nil +} + +// SetOrganizationContentExclusionDetails sets Copilot content exclusion path rules for an organization. +// +// GitHub API docs: https://docs.github.com/rest/copilot/copilot-content-exclusion-management?apiVersion=2022-11-28#set-copilot-content-exclusion-rules-for-an-organization +// +//meta:operation PUT /orgs/{org}/copilot/content_exclusion +func (s *CopilotService) SetOrganizationContentExclusionDetails(ctx context.Context, org string, body CopilotContentExclusionDetails) (*CopilotContentExclusionUpdateResponse, *Response, error) { + u := fmt.Sprintf("orgs/%v/copilot/content_exclusion", org) + + req, err := s.client.NewRequest(ctx, "PUT", u, body) + if err != nil { + return nil, nil, err + } + + var result *CopilotContentExclusionUpdateResponse + resp, err := s.client.Do(req, &result) + if err != nil { + return nil, resp, err + } + + return result, resp, nil +} + +// GetEnterpriseContentExclusionDetails gets the Copilot content exclusion rules for an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-content-exclusion-management?apiVersion=2022-11-28#get-copilot-content-exclusion-rules-for-an-enterprise +// +//meta:operation GET /enterprises/{enterprise}/copilot/content_exclusion +func (s *CopilotService) GetEnterpriseContentExclusionDetails(ctx context.Context, enterprise string) (CopilotContentExclusionDetails, *Response, error) { + u := fmt.Sprintf("enterprises/%v/copilot/content_exclusion", enterprise) + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + details := CopilotContentExclusionDetails{} resp, err := s.client.Do(req, &details) if err != nil { return nil, resp, err @@ -417,6 +469,28 @@ func (s *CopilotService) GetOrganizationContentExclusionDetails(ctx context.Cont return details, resp, nil } +// SetEnterpriseContentExclusionDetails sets Copilot content exclusion path rules for an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-content-exclusion-management?apiVersion=2022-11-28#set-copilot-content-exclusion-rules-for-an-enterprise +// +//meta:operation PUT /enterprises/{enterprise}/copilot/content_exclusion +func (s *CopilotService) SetEnterpriseContentExclusionDetails(ctx context.Context, enterprise string, body CopilotContentExclusionDetails) (*CopilotContentExclusionUpdateResponse, *Response, error) { + u := fmt.Sprintf("enterprises/%v/copilot/content_exclusion", enterprise) + + req, err := s.client.NewRequest(ctx, "PUT", u, body) + if err != nil { + return nil, nil, err + } + + var result *CopilotContentExclusionUpdateResponse + resp, err := s.client.Do(req, &result) + if err != nil { + return nil, resp, err + } + + return result, resp, nil +} + // AddCopilotTeams adds teams to the Copilot for Business subscription for an organization. // // GitHub API docs: https://docs.github.com/rest/copilot/copilot-user-management?apiVersion=2022-11-28#add-teams-to-the-copilot-subscription-for-an-organization diff --git a/github/copilot_test.go b/github/copilot_test.go index b04b406d24d..e0fa9c5b6c3 100644 --- a/github/copilot_test.go +++ b/github/copilot_test.go @@ -845,7 +845,7 @@ func TestCopilotService_GetOrganizationContentExclusionDetails(t *testing.T) { t.Errorf("Copilot.GetOrganizationContentExclusionDetails returned error: %v", err) } - want := CopilotOrganizationContentExclusionDetails{ + want := CopilotContentExclusionDetails{ "octo-repo": {"/src/some-dir/kernel.rs"}, "octo-repo-2": {"/docs/secret.md", "**/*.env"}, } @@ -869,6 +869,132 @@ func TestCopilotService_GetOrganizationContentExclusionDetails(t *testing.T) { }) } +func TestCopilotService_SetOrganizationContentExclusionDetails(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + input := CopilotContentExclusionDetails{ + "octo-repo": {"/src/some-dir/kernel.rs"}, + } + + mux.HandleFunc("/orgs/o/copilot/content_exclusion", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testJSONBody(t, r, input) + fmt.Fprint(w, `{"message": "Content exclusion rules updated"}`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.SetOrganizationContentExclusionDetails(ctx, "o", input) + if err != nil { + t.Errorf("Copilot.SetOrganizationContentExclusionDetails returned error: %v", err) + } + + want := &CopilotContentExclusionUpdateResponse{ + Message: new("Content exclusion rules updated"), + } + if !cmp.Equal(got, want) { + t.Errorf("Copilot.SetOrganizationContentExclusionDetails returned %+v, want %+v", got, want) + } + + const methodName = "SetOrganizationContentExclusionDetails" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Copilot.SetOrganizationContentExclusionDetails(ctx, "\n", input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Copilot.SetOrganizationContentExclusionDetails(ctx, "o", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCopilotService_GetEnterpriseContentExclusionDetails(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/copilot/content_exclusion", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "git@github.com:*/copilot": ["/__tests__/**"], + "octo-org/octo-repo": ["/src/some-dir/kernel.rs"] + }`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.GetEnterpriseContentExclusionDetails(ctx, "e") + if err != nil { + t.Errorf("Copilot.GetEnterpriseContentExclusionDetails returned error: %v", err) + } + + want := CopilotContentExclusionDetails{ + "git@github.com:*/copilot": {"/__tests__/**"}, + "octo-org/octo-repo": {"/src/some-dir/kernel.rs"}, + } + if !cmp.Equal(got, want) { + t.Errorf("Copilot.GetEnterpriseContentExclusionDetails returned %+v, want %+v", got, want) + } + + const methodName = "GetEnterpriseContentExclusionDetails" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Copilot.GetEnterpriseContentExclusionDetails(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Copilot.GetEnterpriseContentExclusionDetails(ctx, "e") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCopilotService_SetEnterpriseContentExclusionDetails(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + input := CopilotContentExclusionDetails{ + "git@github.com:*/copilot": {"/__tests__/**"}, + "octo-org/octo-repo": {"/src/some-dir/kernel.rs"}, + } + + mux.HandleFunc("/enterprises/e/copilot/content_exclusion", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testJSONBody(t, r, input) + fmt.Fprint(w, `{"message": "Content exclusion rules updated"}`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.SetEnterpriseContentExclusionDetails(ctx, "e", input) + if err != nil { + t.Errorf("Copilot.SetEnterpriseContentExclusionDetails returned error: %v", err) + } + + want := &CopilotContentExclusionUpdateResponse{ + Message: new("Content exclusion rules updated"), + } + if !cmp.Equal(got, want) { + t.Errorf("Copilot.SetEnterpriseContentExclusionDetails returned %+v, want %+v", got, want) + } + + const methodName = "SetEnterpriseContentExclusionDetails" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Copilot.SetEnterpriseContentExclusionDetails(ctx, "\n", input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Copilot.SetEnterpriseContentExclusionDetails(ctx, "e", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + func TestCopilotService_AddCopilotTeams(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/github-accessors.go b/github/github-accessors.go index b9ce167b413..eae98b0326b 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9094,6 +9094,14 @@ func (c *CopilotCodeReviewRuleParameters) GetReviewOnPush() bool { return c.ReviewOnPush } +// GetMessage returns the Message field if it's non-nil, zero value otherwise. +func (c *CopilotContentExclusionUpdateResponse) GetMessage() string { + if c == nil || c.Message == nil { + return "" + } + return *c.Message +} + // GetCodeAcceptanceActivityCount returns the CodeAcceptanceActivityCount field if it's non-nil, zero value otherwise. func (c *CopilotDailyMetrics) GetCodeAcceptanceActivityCount() int { if c == nil || c.CodeAcceptanceActivityCount == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index bc822744add..3ed26528614 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -11600,6 +11600,17 @@ func TestCopilotCodeReviewRuleParameters_GetReviewOnPush(tt *testing.T) { c.GetReviewOnPush() } +func TestCopilotContentExclusionUpdateResponse_GetMessage(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotContentExclusionUpdateResponse{Message: &zeroValue} + c.GetMessage() + c = &CopilotContentExclusionUpdateResponse{} + c.GetMessage() + c = nil + c.GetMessage() +} + func TestCopilotDailyMetrics_GetCodeAcceptanceActivityCount(tt *testing.T) { tt.Parallel() var zeroValue int