diff --git a/github/enterprise_codesecurity_configurations.go b/github/enterprise_codesecurity_configurations.go new file mode 100644 index 00000000000..27e07583440 --- /dev/null +++ b/github/enterprise_codesecurity_configurations.go @@ -0,0 +1,228 @@ +// Copyright 2025 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" + "fmt" + "net/http" +) + +// ListEnterpriseCodeSecurityConfigurationOptions specifies optional parameters to get security configurations for enterprises. +// +// Note: Pagination is powered by before/after cursor-style pagination. After the initial call, +// inspect the returned *Response. Use resp.After as the opts.After value to request +// the next page, and resp.Before as the opts.Before value to request the previous +// page. Set either Before or After for a request; if both are +// supplied GitHub API will return an error. PerPage controls the number of items +// per page (max 100 per GitHub API docs). +type ListEnterpriseCodeSecurityConfigurationOptions struct { + // A cursor, as given in the Link header. If specified, the query only searches for security configurations before this cursor. + Before *string `url:"before,omitempty"` + + // A cursor, as given in the Link header. If specified, the query only searches for security configurations after this cursor. + After *string `url:"after,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage *int `url:"per_page,omitempty"` +} + +// ListCodeSecurityConfigurations lists all code security configurations available in an enterprise. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#get-code-security-configurations-for-an-enterprise +// +//meta:operation GET /enterprises/{enterprise}/code-security/configurations +func (s *EnterpriseService) ListCodeSecurityConfigurations(ctx context.Context, enterprise string, opts *ListEnterpriseCodeSecurityConfigurationOptions) ([]*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations", enterprise) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var configurations []*CodeSecurityConfiguration + resp, err := s.client.Do(ctx, req, &configurations) + if err != nil { + return nil, resp, err + } + return configurations, resp, nil +} + +// CreateCodeSecurityConfiguration creates a code security configuration in an enterprise. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#create-a-code-security-configuration-for-an-enterprise +// +//meta:operation POST /enterprises/{enterprise}/code-security/configurations +func (s *EnterpriseService) CreateCodeSecurityConfiguration(ctx context.Context, enterprise string, config CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations", enterprise) + + req, err := s.client.NewRequest("POST", u, config) + if err != nil { + return nil, nil, err + } + + var configuration *CodeSecurityConfiguration + resp, err := s.client.Do(ctx, req, &configuration) + if err != nil { + return nil, resp, err + } + return configuration, resp, nil +} + +// GetDefaultCodeSecurityConfigurations lists the default code security configurations for an enterprise. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#get-default-code-security-configurations-for-an-enterprise +// +//meta:operation GET /enterprises/{enterprise}/code-security/configurations/defaults +func (s *EnterpriseService) GetDefaultCodeSecurityConfigurations(ctx context.Context, enterprise string) ([]*CodeSecurityConfigurationWithDefaultForNewRepos, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/defaults", enterprise) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var configurations []*CodeSecurityConfigurationWithDefaultForNewRepos + resp, err := s.client.Do(ctx, req, &configurations) + if err != nil { + return nil, resp, err + } + return configurations, resp, nil +} + +// ListCodeSecurityConfiguration gets a code security configuration available in an enterprise. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#retrieve-a-code-security-configuration-of-an-enterprise +// +//meta:operation GET /enterprises/{enterprise}/code-security/configurations/{configuration_id} +func (s *EnterpriseService) ListCodeSecurityConfiguration(ctx context.Context, enterprise string, id int64) (*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v", enterprise, id) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var configuration *CodeSecurityConfiguration + resp, err := s.client.Do(ctx, req, &configuration) + if err != nil { + return nil, resp, err + } + return configuration, resp, nil +} + +// UpdateCodeSecurityConfiguration updates a code security configuration in an enterprise. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#update-a-custom-code-security-configuration-for-an-enterprise +// +//meta:operation PATCH /enterprises/{enterprise}/code-security/configurations/{configuration_id} +func (s *EnterpriseService) UpdateCodeSecurityConfiguration(ctx context.Context, enterprise string, id int64, config CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v", enterprise, id) + + req, err := s.client.NewRequest("PATCH", u, config) + if err != nil { + return nil, nil, err + } + + var configuration *CodeSecurityConfiguration + resp, err := s.client.Do(ctx, req, &configuration) + if err != nil { + return nil, resp, err + } + return configuration, resp, nil +} + +// DeleteCodeSecurityConfiguration deletes a code security configuration from an enterprise. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#delete-a-code-security-configuration-for-an-enterprise +// +//meta:operation DELETE /enterprises/{enterprise}/code-security/configurations/{configuration_id} +func (s *EnterpriseService) DeleteCodeSecurityConfiguration(ctx context.Context, enterprise string, id int64) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v", enterprise, id) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + return resp, nil +} + +// AttachCodeSecurityConfigurationToRepositories attaches an enterprise code security configuration to repositories. +// `scope` is the type of repositories to attach the configuration to. +// Can be one of: `all`, `all_without_configurations`. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#attach-an-enterprise-configuration-to-repositories +// +//meta:operation POST /enterprises/{enterprise}/code-security/configurations/{configuration_id}/attach +func (s *EnterpriseService) AttachCodeSecurityConfigurationToRepositories(ctx context.Context, enterprise string, id int64, scope string) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v/attach", enterprise, id) + type scopeType struct { + Scope string `json:"scope"` + } + + req, err := s.client.NewRequest("POST", u, scopeType{Scope: scope}) + if err != nil { + return nil, err + } + resp, err := s.client.Do(ctx, req, nil) + if err != nil && resp.StatusCode != http.StatusAccepted { // StatusAccepted(202) is the expected status code as job is queued for processing + return resp, err + } + return resp, nil +} + +// SetDefaultCodeSecurityConfiguration sets a code security configuration as a default for an enterprise. +// `defaultForNewRepos` specifies which types of repository this security configuration should be applied to by default. +// Can be one of: `all`, `none`, `private_and_internal, public`. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#set-a-code-security-configuration-as-a-default-for-an-enterprise +// +//meta:operation PUT /enterprises/{enterprise}/code-security/configurations/{configuration_id}/defaults +func (s *EnterpriseService) SetDefaultCodeSecurityConfiguration(ctx context.Context, enterprise string, id int64, defaultForNewRepos string) (*CodeSecurityConfigurationWithDefaultForNewRepos, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v/defaults", enterprise, id) + type configParam struct { + DefaultForNewRepos string `json:"default_for_new_repos"` + } + + req, err := s.client.NewRequest("PUT", u, configParam{DefaultForNewRepos: defaultForNewRepos}) + if err != nil { + return nil, nil, err + } + var config *CodeSecurityConfigurationWithDefaultForNewRepos + resp, err := s.client.Do(ctx, req, &config) + if err != nil { + return nil, resp, err + } + return config, resp, nil +} + +// GetRepositoriesForCodeSecurityConfiguration lists the repositories associated with an enterprise code security configuration. +// +// GitHub API docs: https://docs.github.com/rest/code-security/configurations#get-repositories-associated-with-an-enterprise-code-security-configuration +// +//meta:operation GET /enterprises/{enterprise}/code-security/configurations/{configuration_id}/repositories +func (s *EnterpriseService) GetRepositoriesForCodeSecurityConfiguration(ctx context.Context, enterprise string, id int64) ([]*RepositoryAttachment, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v/repositories", enterprise, id) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + var attachments []*RepositoryAttachment + resp, err := s.client.Do(ctx, req, &attachments) + if err != nil { + return nil, resp, err + } + return attachments, resp, nil +} diff --git a/github/enterprise_codesecurity_configurations_test.go b/github/enterprise_codesecurity_configurations_test.go new file mode 100644 index 00000000000..1f4ea1774e2 --- /dev/null +++ b/github/enterprise_codesecurity_configurations_test.go @@ -0,0 +1,442 @@ +// Copyright 2024 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 ( + "encoding/json" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestEnterpriseService_ListCodeSecurityConfigurations(t *testing.T) { + t.Parallel() + opts := &ListEnterpriseCodeSecurityConfigurationOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(30)} + ctx := t.Context() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/code-security/configurations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"before": "1", "after": "2", "per_page": "30"}) + fmt.Fprint(w, `[ + { + "id":1, + "name":"config1", + "description":"desc1", + "code_scanning_default_setup": "enabled" + }, + { + "id":2, + "name":"config2", + "description":"desc2", + "private_vulnerability_reporting": "enabled" + }]`) + }) + + configurations, _, err := client.Enterprise.ListCodeSecurityConfigurations(ctx, "e", opts) + if err != nil { + t.Errorf("Enterprise.ListCodeSecurityConfigurations returned error: %v", err) + } + + want := []*CodeSecurityConfiguration{ + {ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")}, + {ID: Ptr(int64(2)), Name: "config2", Description: "desc2", PrivateVulnerabilityReporting: Ptr("enabled")}, + } + if !cmp.Equal(configurations, want) { + t.Errorf("Enterprise.ListCodeSecurityConfigurations returned %+v, want %+v", configurations, want) + } + const methodName = "ListCodeSecurityConfigurations" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.ListCodeSecurityConfigurations(ctx, "\n", opts) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.ListCodeSecurityConfigurations(ctx, "e", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_ListCodeSecurityConfiguration(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + ctx := t.Context() + + mux.HandleFunc("/enterprises/e/code-security/configurations/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "id":1, + "name":"config1", + "description":"desc1", + "code_scanning_default_setup": "enabled" + }`) + }) + + configuration, _, err := client.Enterprise.ListCodeSecurityConfiguration(ctx, "e", 1) + if err != nil { + t.Errorf("Enterprise.ListCodeSecurityConfiguration returned error: %v", err) + } + + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} + if !cmp.Equal(configuration, want) { + t.Errorf("Enterprise.ListCodeSecurityConfiguration returned %+v, want %+v", configuration, want) + } + + const methodName = "ListCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.ListCodeSecurityConfiguration(ctx, "\n", -1) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.ListCodeSecurityConfiguration(ctx, "e", 1) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_CreateCodeSecurityConfiguration(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + ctx := t.Context() + + input := CodeSecurityConfiguration{ + Name: "config1", + Description: "desc1", + CodeScanningDefaultSetup: Ptr("enabled"), + } + + mux.HandleFunc("/enterprises/e/code-security/configurations", func(w http.ResponseWriter, r *http.Request) { + var v CodeSecurityConfiguration + assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) + + if !cmp.Equal(v, input) { + t.Errorf("Enterprise.CreateCodeSecurityConfiguration request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{ + "id":1, + "name":"config1", + "description":"desc1", + "code_scanning_default_setup": "enabled" + }`) + }) + + configuration, _, err := client.Enterprise.CreateCodeSecurityConfiguration(ctx, "e", input) + if err != nil { + t.Errorf("Enterprise.CreateCodeSecurityConfiguration returned error: %v", err) + } + + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} + if !cmp.Equal(configuration, want) { + t.Errorf("Enterprise.CreateCodeSecurityConfiguration returned %+v, want %+v", configuration, want) + } + + const methodName = "CreateCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.CreateCodeSecurityConfiguration(ctx, "\n", input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.CreateCodeSecurityConfiguration(ctx, "e", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_GetDefaultCodeSecurityConfigurations(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + ctx := t.Context() + + mux.HandleFunc("/enterprises/e/code-security/configurations/defaults", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[ + { + "default_for_new_repos": "public", + "configuration": { + "id":1, + "name":"config1", + "description":"desc1", + "code_scanning_default_setup": "enabled" + } + }, + { + "default_for_new_repos": "private_and_internal", + "configuration": { + "id":2, + "name":"config2", + "description":"desc2", + "private_vulnerability_reporting": "enabled" + } + } + ]`) + }) + + configurations, _, err := client.Enterprise.GetDefaultCodeSecurityConfigurations(ctx, "e") + if err != nil { + t.Errorf("Enterprise.GetDefaultCodeSecurityConfigurations returned error: %v", err) + } + + want := []*CodeSecurityConfigurationWithDefaultForNewRepos{ + {DefaultForNewRepos: Ptr("public"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")}}, + {DefaultForNewRepos: Ptr("private_and_internal"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(2)), Name: "config2", Description: "desc2", PrivateVulnerabilityReporting: Ptr("enabled")}}, + } + if !cmp.Equal(configurations, want) { + t.Errorf("Enterprise.GetDefaultCodeSecurityConfigurations returned %+v, want %+v", configurations, want) + } + + const methodName = "GetDefaultCodeSecurityConfigurations" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetDefaultCodeSecurityConfigurations(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetDefaultCodeSecurityConfigurations(ctx, "e") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_UpdateCodeSecurityConfiguration(t *testing.T) { + t.Parallel() + ctx := t.Context() + client, mux, _ := setup(t) + + input := CodeSecurityConfiguration{ + Name: "config1", + Description: "desc1", + CodeScanningDefaultSetup: Ptr("enabled"), + } + + mux.HandleFunc("/enterprises/e/code-security/configurations/1", func(w http.ResponseWriter, r *http.Request) { + var v CodeSecurityConfiguration + assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) + + if !cmp.Equal(v, input) { + t.Errorf("Enterprise.UpdateCodeSecurityConfiguration request body = %+v, want %+v", v, input) + } + + fmt.Fprint(w, `{ + "id":1, + "name":"config1", + "description":"desc1", + "code_scanning_default_setup": "enabled" + }`) + }) + + configuration, _, err := client.Enterprise.UpdateCodeSecurityConfiguration(ctx, "e", 1, input) + if err != nil { + t.Errorf("Enterprise.UpdateCodeSecurityConfiguration returned error: %v", err) + } + + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} + if !cmp.Equal(configuration, want) { + t.Errorf("Enterprise.UpdateCodeSecurityConfiguration returned %+v, want %+v", configuration, want) + } + + const methodName = "UpdateCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.UpdateCodeSecurityConfiguration(ctx, "\n", -1, input) + return + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.UpdateCodeSecurityConfiguration(ctx, "e", 1, input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_DeleteCodeSecurityConfiguration(t *testing.T) { + t.Parallel() + ctx := t.Context() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/code-security/configurations/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + resp, err := client.Enterprise.DeleteCodeSecurityConfiguration(ctx, "e", 1) + if err != nil { + t.Errorf("Enterprise.DeleteCodeSecurityConfiguration returned error: %v", err) + } + + want := http.StatusNoContent + if resp.StatusCode != want { + t.Errorf("Enterprise.DeleteCodeSecurityConfiguration returned status %v, want %v", resp.StatusCode, want) + } + + const methodName = "DeleteCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, err = client.Enterprise.DeleteCodeSecurityConfiguration(ctx, "\n", -1) + return + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + resp, err := client.Enterprise.DeleteCodeSecurityConfiguration(ctx, "e", 1) + return resp, err + }) +} + +func TestEnterpriseService_AttachCodeSecurityConfigurationToRepositories(t *testing.T) { + t.Parallel() + ctx := t.Context() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/code-security/configurations/1/attach", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + type request struct { + Scope string `json:"scope"` + } + v := new(request) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + if v.Scope != "all_without_configurations" { + t.Errorf("Enterprise.AttachCodeSecurityConfigurationToRepositories request body scope = %v, want selected", v.Scope) + } + w.WriteHeader(http.StatusAccepted) + }) + + resp, err := client.Enterprise.AttachCodeSecurityConfigurationToRepositories(ctx, "e", int64(1), "all_without_configurations") + if err != nil { + t.Errorf("Enterprise.AttachCodeSecurityConfigurationToRepositories returned error: %v", err) + } + + want := http.StatusAccepted + if resp.StatusCode != want { + t.Errorf("Enterprise.AttachCodeSecurityConfigurationToRepositories returned status %v, want %v", resp.StatusCode, want) + } + + const methodName = "AttachCodeSecurityConfigurationToRepositories" + testBadOptions(t, methodName, func() (err error) { + _, err = client.Enterprise.AttachCodeSecurityConfigurationToRepositories(ctx, "\n", -1, "") + return + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + resp, err := client.Enterprise.AttachCodeSecurityConfigurationToRepositories(ctx, "e", 1, "all_without_configurations") + return resp, err + }) +} + +func TestEnterpriseService_SetDefaultCodeSecurityConfiguration(t *testing.T) { + t.Parallel() + ctx := t.Context() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/code-security/configurations/1/defaults", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprint(w, ` + { + "default_for_new_repos": "all", + "configuration": + { + "id": 1, + "name": "config1", + "description": "desc1", + "code_scanning_default_setup": "enabled" + } + }`) + }) + got, resp, err := client.Enterprise.SetDefaultCodeSecurityConfiguration(ctx, "e", 1, "all") + if err != nil { + t.Errorf("Enterprise.SetDefaultCodeSecurityConfiguration returned error: %v", err) + } + wantStatus := http.StatusOK + if resp.StatusCode != wantStatus { + t.Errorf("Enterprise.SetDefaultCodeSecurityConfiguration returned status %v, want %v", resp.StatusCode, wantStatus) + } + want := &CodeSecurityConfigurationWithDefaultForNewRepos{ + DefaultForNewRepos: Ptr("all"), + Configuration: &CodeSecurityConfiguration{ + ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled"), + }, + } + if !cmp.Equal(got, want) { + t.Errorf("Enterprise.SetDefaultCodeSecurityConfiguration returned %+v, want %+v", got, want) + } + + const methodName = "SetDefaultCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.SetDefaultCodeSecurityConfiguration(ctx, "\n", -1, "") + return + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.SetDefaultCodeSecurityConfiguration(ctx, "e", 1, "all") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_GetRepositoriesForCodeSecurityConfiguration(t *testing.T) { + t.Parallel() + ctx := t.Context() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/code-security/configurations/1/repositories", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[ + { + "status": "attached", + "repository": { + "id":8, + "name":"repo8" + } + }, + { + "status": "attached", + "repository": { + "id":42, + "name":"repo42" + } + } + ]`) + }) + + attachments, _, err := client.Enterprise.GetRepositoriesForCodeSecurityConfiguration(ctx, "e", 1) + if err != nil { + t.Errorf("Enterprise.GetRepositoriesForCodeSecurityConfiguration returned error: %v", err) + } + want := []*RepositoryAttachment{ + {Status: Ptr("attached"), Repository: &Repository{ID: Ptr(int64(8)), Name: Ptr("repo8")}}, + {Status: Ptr("attached"), Repository: &Repository{ID: Ptr(int64(42)), Name: Ptr("repo42")}}, + } + if !cmp.Equal(attachments, want) { + t.Errorf("Enterprise.GetRepositoriesForCodeSecurityConfiguration returned %+v, want %+v", attachments, want) + } + + const methodName = "GetRepositoriesForCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetRepositoriesForCodeSecurityConfiguration(ctx, "\n", -1) + return + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetRepositoriesForCodeSecurityConfiguration(ctx, "e", 1) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 6a6ef9c9599..5a5b79467d7 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3230,6 +3230,22 @@ func (c *CodeScanningAlertState) GetDismissedReason() string { return *c.DismissedReason } +// GetRunnerLabel returns the RunnerLabel field if it's non-nil, zero value otherwise. +func (c *CodeScanningDefaultSetupOptions) GetRunnerLabel() string { + if c == nil || c.RunnerLabel == nil { + return "" + } + return *c.RunnerLabel +} + +// GetAllowAdvanced returns the AllowAdvanced field if it's non-nil, zero value otherwise. +func (c *CodeScanningOptions) GetAllowAdvanced() bool { + if c == nil || c.AllowAdvanced == nil { + return false + } + return *c.AllowAdvanced +} + // GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise. func (c *CodeSearchResult) GetIncompleteResults() bool { if c == nil || c.IncompleteResults == nil { @@ -3262,6 +3278,38 @@ func (c *CodeSecurityConfiguration) GetCodeScanningDefaultSetup() string { return *c.CodeScanningDefaultSetup } +// GetCodeScanningDefaultSetupOptions returns the CodeScanningDefaultSetupOptions field. +func (c *CodeSecurityConfiguration) GetCodeScanningDefaultSetupOptions() *CodeScanningDefaultSetupOptions { + if c == nil { + return nil + } + return c.CodeScanningDefaultSetupOptions +} + +// GetCodeScanningDelegatedAlertDismissal returns the CodeScanningDelegatedAlertDismissal field if it's non-nil, zero value otherwise. +func (c *CodeSecurityConfiguration) GetCodeScanningDelegatedAlertDismissal() string { + if c == nil || c.CodeScanningDelegatedAlertDismissal == nil { + return "" + } + return *c.CodeScanningDelegatedAlertDismissal +} + +// GetCodeScanningOptions returns the CodeScanningOptions field. +func (c *CodeSecurityConfiguration) GetCodeScanningOptions() *CodeScanningOptions { + if c == nil { + return nil + } + return c.CodeScanningOptions +} + +// GetCodeSecurity returns the CodeSecurity field if it's non-nil, zero value otherwise. +func (c *CodeSecurityConfiguration) GetCodeSecurity() string { + if c == nil || c.CodeSecurity == nil { + return "" + } + return *c.CodeSecurity +} + // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. func (c *CodeSecurityConfiguration) GetCreatedAt() Timestamp { if c == nil || c.CreatedAt == nil { @@ -3310,14 +3358,6 @@ func (c *CodeSecurityConfiguration) GetDependencyGraphAutosubmitActionOptions() return c.DependencyGraphAutosubmitActionOptions } -// GetDescription returns the Description field if it's non-nil, zero value otherwise. -func (c *CodeSecurityConfiguration) GetDescription() string { - if c == nil || c.Description == nil { - return "" - } - return *c.Description -} - // GetEnforcement returns the Enforcement field if it's non-nil, zero value otherwise. func (c *CodeSecurityConfiguration) GetEnforcement() string { if c == nil || c.Enforcement == nil { @@ -3342,14 +3382,6 @@ func (c *CodeSecurityConfiguration) GetID() int64 { return *c.ID } -// GetName returns the Name field if it's non-nil, zero value otherwise. -func (c *CodeSecurityConfiguration) GetName() string { - if c == nil || c.Name == nil { - return "" - } - return *c.Name -} - // GetPrivateVulnerabilityReporting returns the PrivateVulnerabilityReporting field if it's non-nil, zero value otherwise. func (c *CodeSecurityConfiguration) GetPrivateVulnerabilityReporting() string { if c == nil || c.PrivateVulnerabilityReporting == nil { @@ -3358,6 +3390,14 @@ func (c *CodeSecurityConfiguration) GetPrivateVulnerabilityReporting() string { return *c.PrivateVulnerabilityReporting } +// GetSecretProtection returns the SecretProtection field if it's non-nil, zero value otherwise. +func (c *CodeSecurityConfiguration) GetSecretProtection() string { + if c == nil || c.SecretProtection == nil { + return "" + } + return *c.SecretProtection +} + // GetSecretScanning returns the SecretScanning field if it's non-nil, zero value otherwise. func (c *CodeSecurityConfiguration) GetSecretScanning() string { if c == nil || c.SecretScanning == nil { @@ -3366,6 +3406,22 @@ func (c *CodeSecurityConfiguration) GetSecretScanning() string { return *c.SecretScanning } +// GetSecretScanningDelegatedAlertDismissal returns the SecretScanningDelegatedAlertDismissal field if it's non-nil, zero value otherwise. +func (c *CodeSecurityConfiguration) GetSecretScanningDelegatedAlertDismissal() string { + if c == nil || c.SecretScanningDelegatedAlertDismissal == nil { + return "" + } + return *c.SecretScanningDelegatedAlertDismissal +} + +// GetSecretScanningGenericSecrets returns the SecretScanningGenericSecrets field if it's non-nil, zero value otherwise. +func (c *CodeSecurityConfiguration) GetSecretScanningGenericSecrets() string { + if c == nil || c.SecretScanningGenericSecrets == nil { + return "" + } + return *c.SecretScanningGenericSecrets +} + // GetSecretScanningNonProviderPatterns returns the SecretScanningNonProviderPatterns field if it's non-nil, zero value otherwise. func (c *CodeSecurityConfiguration) GetSecretScanningNonProviderPatterns() string { if c == nil || c.SecretScanningNonProviderPatterns == nil { @@ -14078,6 +14134,30 @@ func (l *ListDeploymentProtectionRuleResponse) GetTotalCount() int { return *l.TotalCount } +// GetAfter returns the After field if it's non-nil, zero value otherwise. +func (l *ListEnterpriseCodeSecurityConfigurationOptions) GetAfter() string { + if l == nil || l.After == nil { + return "" + } + return *l.After +} + +// GetBefore returns the Before field if it's non-nil, zero value otherwise. +func (l *ListEnterpriseCodeSecurityConfigurationOptions) GetBefore() string { + if l == nil || l.Before == nil { + return "" + } + return *l.Before +} + +// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. +func (l *ListEnterpriseCodeSecurityConfigurationOptions) GetPerPage() int { + if l == nil || l.PerPage == nil { + return 0 + } + return *l.PerPage +} + // GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. func (l *ListExternalGroupsOptions) GetDisplayName() string { if l == nil || l.DisplayName == nil { @@ -14174,6 +14254,38 @@ func (l *ListOrganizations) GetTotalCount() int { return *l.TotalCount } +// GetAfter returns the After field if it's non-nil, zero value otherwise. +func (l *ListOrgCodeSecurityConfigurationOptions) GetAfter() string { + if l == nil || l.After == nil { + return "" + } + return *l.After +} + +// GetBefore returns the Before field if it's non-nil, zero value otherwise. +func (l *ListOrgCodeSecurityConfigurationOptions) GetBefore() string { + if l == nil || l.Before == nil { + return "" + } + return *l.Before +} + +// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. +func (l *ListOrgCodeSecurityConfigurationOptions) GetPerPage() int { + if l == nil || l.PerPage == nil { + return 0 + } + return *l.PerPage +} + +// GetTargetType returns the TargetType field if it's non-nil, zero value otherwise. +func (l *ListOrgCodeSecurityConfigurationOptions) GetTargetType() string { + if l == nil || l.TargetType == nil { + return "" + } + return *l.TargetType +} + // GetQuery returns the Query field if it's non-nil, zero value otherwise. func (l *ListProjectsOptions) GetQuery() string { if l == nil || l.Query == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 33f25e90ee3..cd85326bfaf 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -4209,6 +4209,28 @@ func TestCodeScanningAlertState_GetDismissedReason(tt *testing.T) { c.GetDismissedReason() } +func TestCodeScanningDefaultSetupOptions_GetRunnerLabel(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodeScanningDefaultSetupOptions{RunnerLabel: &zeroValue} + c.GetRunnerLabel() + c = &CodeScanningDefaultSetupOptions{} + c.GetRunnerLabel() + c = nil + c.GetRunnerLabel() +} + +func TestCodeScanningOptions_GetAllowAdvanced(tt *testing.T) { + tt.Parallel() + var zeroValue bool + c := &CodeScanningOptions{AllowAdvanced: &zeroValue} + c.GetAllowAdvanced() + c = &CodeScanningOptions{} + c.GetAllowAdvanced() + c = nil + c.GetAllowAdvanced() +} + func TestCodeSearchResult_GetIncompleteResults(tt *testing.T) { tt.Parallel() var zeroValue bool @@ -4253,6 +4275,44 @@ func TestCodeSecurityConfiguration_GetCodeScanningDefaultSetup(tt *testing.T) { c.GetCodeScanningDefaultSetup() } +func TestCodeSecurityConfiguration_GetCodeScanningDefaultSetupOptions(tt *testing.T) { + tt.Parallel() + c := &CodeSecurityConfiguration{} + c.GetCodeScanningDefaultSetupOptions() + c = nil + c.GetCodeScanningDefaultSetupOptions() +} + +func TestCodeSecurityConfiguration_GetCodeScanningDelegatedAlertDismissal(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodeSecurityConfiguration{CodeScanningDelegatedAlertDismissal: &zeroValue} + c.GetCodeScanningDelegatedAlertDismissal() + c = &CodeSecurityConfiguration{} + c.GetCodeScanningDelegatedAlertDismissal() + c = nil + c.GetCodeScanningDelegatedAlertDismissal() +} + +func TestCodeSecurityConfiguration_GetCodeScanningOptions(tt *testing.T) { + tt.Parallel() + c := &CodeSecurityConfiguration{} + c.GetCodeScanningOptions() + c = nil + c.GetCodeScanningOptions() +} + +func TestCodeSecurityConfiguration_GetCodeSecurity(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodeSecurityConfiguration{CodeSecurity: &zeroValue} + c.GetCodeSecurity() + c = &CodeSecurityConfiguration{} + c.GetCodeSecurity() + c = nil + c.GetCodeSecurity() +} + func TestCodeSecurityConfiguration_GetCreatedAt(tt *testing.T) { tt.Parallel() var zeroValue Timestamp @@ -4316,17 +4376,6 @@ func TestCodeSecurityConfiguration_GetDependencyGraphAutosubmitActionOptions(tt c.GetDependencyGraphAutosubmitActionOptions() } -func TestCodeSecurityConfiguration_GetDescription(tt *testing.T) { - tt.Parallel() - var zeroValue string - c := &CodeSecurityConfiguration{Description: &zeroValue} - c.GetDescription() - c = &CodeSecurityConfiguration{} - c.GetDescription() - c = nil - c.GetDescription() -} - func TestCodeSecurityConfiguration_GetEnforcement(tt *testing.T) { tt.Parallel() var zeroValue string @@ -4360,26 +4409,26 @@ func TestCodeSecurityConfiguration_GetID(tt *testing.T) { c.GetID() } -func TestCodeSecurityConfiguration_GetName(tt *testing.T) { +func TestCodeSecurityConfiguration_GetPrivateVulnerabilityReporting(tt *testing.T) { tt.Parallel() var zeroValue string - c := &CodeSecurityConfiguration{Name: &zeroValue} - c.GetName() + c := &CodeSecurityConfiguration{PrivateVulnerabilityReporting: &zeroValue} + c.GetPrivateVulnerabilityReporting() c = &CodeSecurityConfiguration{} - c.GetName() + c.GetPrivateVulnerabilityReporting() c = nil - c.GetName() + c.GetPrivateVulnerabilityReporting() } -func TestCodeSecurityConfiguration_GetPrivateVulnerabilityReporting(tt *testing.T) { +func TestCodeSecurityConfiguration_GetSecretProtection(tt *testing.T) { tt.Parallel() var zeroValue string - c := &CodeSecurityConfiguration{PrivateVulnerabilityReporting: &zeroValue} - c.GetPrivateVulnerabilityReporting() + c := &CodeSecurityConfiguration{SecretProtection: &zeroValue} + c.GetSecretProtection() c = &CodeSecurityConfiguration{} - c.GetPrivateVulnerabilityReporting() + c.GetSecretProtection() c = nil - c.GetPrivateVulnerabilityReporting() + c.GetSecretProtection() } func TestCodeSecurityConfiguration_GetSecretScanning(tt *testing.T) { @@ -4393,6 +4442,28 @@ func TestCodeSecurityConfiguration_GetSecretScanning(tt *testing.T) { c.GetSecretScanning() } +func TestCodeSecurityConfiguration_GetSecretScanningDelegatedAlertDismissal(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodeSecurityConfiguration{SecretScanningDelegatedAlertDismissal: &zeroValue} + c.GetSecretScanningDelegatedAlertDismissal() + c = &CodeSecurityConfiguration{} + c.GetSecretScanningDelegatedAlertDismissal() + c = nil + c.GetSecretScanningDelegatedAlertDismissal() +} + +func TestCodeSecurityConfiguration_GetSecretScanningGenericSecrets(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodeSecurityConfiguration{SecretScanningGenericSecrets: &zeroValue} + c.GetSecretScanningGenericSecrets() + c = &CodeSecurityConfiguration{} + c.GetSecretScanningGenericSecrets() + c = nil + c.GetSecretScanningGenericSecrets() +} + func TestCodeSecurityConfiguration_GetSecretScanningNonProviderPatterns(tt *testing.T) { tt.Parallel() var zeroValue string @@ -18288,6 +18359,39 @@ func TestListDeploymentProtectionRuleResponse_GetTotalCount(tt *testing.T) { l.GetTotalCount() } +func TestListEnterpriseCodeSecurityConfigurationOptions_GetAfter(tt *testing.T) { + tt.Parallel() + var zeroValue string + l := &ListEnterpriseCodeSecurityConfigurationOptions{After: &zeroValue} + l.GetAfter() + l = &ListEnterpriseCodeSecurityConfigurationOptions{} + l.GetAfter() + l = nil + l.GetAfter() +} + +func TestListEnterpriseCodeSecurityConfigurationOptions_GetBefore(tt *testing.T) { + tt.Parallel() + var zeroValue string + l := &ListEnterpriseCodeSecurityConfigurationOptions{Before: &zeroValue} + l.GetBefore() + l = &ListEnterpriseCodeSecurityConfigurationOptions{} + l.GetBefore() + l = nil + l.GetBefore() +} + +func TestListEnterpriseCodeSecurityConfigurationOptions_GetPerPage(tt *testing.T) { + tt.Parallel() + var zeroValue int + l := &ListEnterpriseCodeSecurityConfigurationOptions{PerPage: &zeroValue} + l.GetPerPage() + l = &ListEnterpriseCodeSecurityConfigurationOptions{} + l.GetPerPage() + l = nil + l.GetPerPage() +} + func TestListExternalGroupsOptions_GetDisplayName(tt *testing.T) { tt.Parallel() var zeroValue string @@ -18420,6 +18524,50 @@ func TestListOrganizations_GetTotalCount(tt *testing.T) { l.GetTotalCount() } +func TestListOrgCodeSecurityConfigurationOptions_GetAfter(tt *testing.T) { + tt.Parallel() + var zeroValue string + l := &ListOrgCodeSecurityConfigurationOptions{After: &zeroValue} + l.GetAfter() + l = &ListOrgCodeSecurityConfigurationOptions{} + l.GetAfter() + l = nil + l.GetAfter() +} + +func TestListOrgCodeSecurityConfigurationOptions_GetBefore(tt *testing.T) { + tt.Parallel() + var zeroValue string + l := &ListOrgCodeSecurityConfigurationOptions{Before: &zeroValue} + l.GetBefore() + l = &ListOrgCodeSecurityConfigurationOptions{} + l.GetBefore() + l = nil + l.GetBefore() +} + +func TestListOrgCodeSecurityConfigurationOptions_GetPerPage(tt *testing.T) { + tt.Parallel() + var zeroValue int + l := &ListOrgCodeSecurityConfigurationOptions{PerPage: &zeroValue} + l.GetPerPage() + l = &ListOrgCodeSecurityConfigurationOptions{} + l.GetPerPage() + l = nil + l.GetPerPage() +} + +func TestListOrgCodeSecurityConfigurationOptions_GetTargetType(tt *testing.T) { + tt.Parallel() + var zeroValue string + l := &ListOrgCodeSecurityConfigurationOptions{TargetType: &zeroValue} + l.GetTargetType() + l = &ListOrgCodeSecurityConfigurationOptions{} + l.GetTargetType() + l = nil + l.GetTargetType() +} + func TestListProjectsOptions_GetQuery(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/orgs_codesecurity_configurations.go b/github/orgs_codesecurity_configurations.go index b78bbbc28fc..177a7e001f4 100644 --- a/github/orgs_codesecurity_configurations.go +++ b/github/orgs_codesecurity_configurations.go @@ -16,6 +16,17 @@ type DependencyGraphAutosubmitActionOptions struct { LabeledRunners *bool `json:"labeled_runners,omitempty"` } +// CodeScanningOptions represents the options for the Security Configuration code scanning feature. +type CodeScanningOptions struct { + AllowAdvanced *bool `json:"allow_advanced,omitempty"` +} + +// CodeScanningDefaultSetupOptions represents the feature options for the code scanning default options. +type CodeScanningDefaultSetupOptions struct { + RunnerType string `json:"runner_type"` + RunnerLabel *string `json:"runner_label,omitempty"` +} + // RepositoryAttachment represents a repository attachment to a code security configuration. type RepositoryAttachment struct { Status *string `json:"status"` @@ -26,8 +37,8 @@ type RepositoryAttachment struct { type CodeSecurityConfiguration struct { ID *int64 `json:"id,omitempty"` TargetType *string `json:"target_type,omitempty"` - Name *string `json:"name"` - Description *string `json:"description,omitempty"` + Name string `json:"name"` + Description string `json:"description"` AdvancedSecurity *string `json:"advanced_security,omitempty"` DependencyGraph *string `json:"dependency_graph,omitempty"` DependencyGraphAutosubmitAction *string `json:"dependency_graph_autosubmit_action,omitempty"` @@ -35,10 +46,17 @@ type CodeSecurityConfiguration struct { DependabotAlerts *string `json:"dependabot_alerts,omitempty"` DependabotSecurityUpdates *string `json:"dependabot_security_updates,omitempty"` CodeScanningDefaultSetup *string `json:"code_scanning_default_setup,omitempty"` + CodeScanningDefaultSetupOptions *CodeScanningDefaultSetupOptions `json:"code_scanning_default_setup_options,omitempty"` + CodeScanningDelegatedAlertDismissal *string `json:"code_scanning_delegated_alert_dismissal,omitempty"` + CodeScanningOptions *CodeScanningOptions `json:"code_scanning_options,omitempty"` + CodeSecurity *string `json:"code_security,omitempty"` SecretScanning *string `json:"secret_scanning,omitempty"` SecretScanningPushProtection *string `json:"secret_scanning_push_protection,omitempty"` SecretScanningValidityChecks *string `json:"secret_scanning_validity_checks,omitempty"` SecretScanningNonProviderPatterns *string `json:"secret_scanning_non_provider_patterns,omitempty"` + SecretScanningGenericSecrets *string `json:"secret_scanning_generic_secrets,omitempty"` + SecretScanningDelegatedAlertDismissal *string `json:"secret_scanning_delegated_alert_dismissal,omitempty"` + SecretProtection *string `json:"secret_protection,omitempty"` PrivateVulnerabilityReporting *string `json:"private_vulnerability_reporting,omitempty"` Enforcement *string `json:"enforcement,omitempty"` URL *string `json:"url,omitempty"` @@ -59,13 +77,41 @@ type RepositoryCodeSecurityConfiguration struct { Configuration *CodeSecurityConfiguration `json:"configuration,omitempty"` } -// GetCodeSecurityConfigurations gets code security configurations for an organization. +// ListOrgCodeSecurityConfigurationOptions specifies optional parameters to get security configurations for orgs. +// +// Note: Pagination is powered by before/after cursor-style pagination. After the initial call, +// inspect the returned *Response. Use resp.After as the opts.After value to request +// the next page, and resp.Before as the opts.Before value to request the previous +// page. Set either Before or After for a request; if both are +// supplied GitHub API will return an error. PerPage controls the number of items +// per page (max 100 per GitHub API docs). +type ListOrgCodeSecurityConfigurationOptions struct { + // A cursor, as given in the Link header. If specified, the query only searches for security configurations before this cursor. + Before *string `url:"before,omitempty"` + + // A cursor, as given in the Link header. If specified, the query only searches for security configurations after this cursor. + After *string `url:"after,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage *int `url:"per_page,omitempty"` + + // The target type of the code security configurations to get. + // + // `target_type` defaults to all, can be one of global, all + TargetType *string `url:"target_type,omitempty"` +} + +// ListCodeSecurityConfigurations gets code security configurations for an organization. // // GitHub API docs: https://docs.github.com/rest/code-security/configurations#get-code-security-configurations-for-an-organization // //meta:operation GET /orgs/{org}/code-security/configurations -func (s *OrganizationsService) GetCodeSecurityConfigurations(ctx context.Context, org string) ([]*CodeSecurityConfiguration, *Response, error) { +func (s *OrganizationsService) ListCodeSecurityConfigurations(ctx context.Context, org string, opts *ListOrgCodeSecurityConfigurationOptions) ([]*CodeSecurityConfiguration, *Response, error) { u := fmt.Sprintf("orgs/%v/code-security/configurations", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -85,10 +131,10 @@ func (s *OrganizationsService) GetCodeSecurityConfigurations(ctx context.Context // GitHub API docs: https://docs.github.com/rest/code-security/configurations#create-a-code-security-configuration // //meta:operation POST /orgs/{org}/code-security/configurations -func (s *OrganizationsService) CreateCodeSecurityConfiguration(ctx context.Context, org string, c *CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { +func (s *OrganizationsService) CreateCodeSecurityConfiguration(ctx context.Context, org string, config CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { u := fmt.Sprintf("orgs/%v/code-security/configurations", org) - req, err := s.client.NewRequest("POST", u, c) + req, err := s.client.NewRequest("POST", u, config) if err != nil { return nil, nil, err } @@ -143,12 +189,12 @@ func (s *OrganizationsService) DetachCodeSecurityConfigurationsFromRepositories( return resp, nil } -// GetCodeSecurityConfiguration gets a code security configuration available in an organization. +// ListCodeSecurityConfiguration gets a code security configuration available in an organization. // // GitHub API docs: https://docs.github.com/rest/code-security/configurations#get-a-code-security-configuration // //meta:operation GET /orgs/{org}/code-security/configurations/{configuration_id} -func (s *OrganizationsService) GetCodeSecurityConfiguration(ctx context.Context, org string, id int64) (*CodeSecurityConfiguration, *Response, error) { +func (s *OrganizationsService) ListCodeSecurityConfiguration(ctx context.Context, org string, id int64) (*CodeSecurityConfiguration, *Response, error) { u := fmt.Sprintf("orgs/%v/code-security/configurations/%v", org, id) req, err := s.client.NewRequest("GET", u, nil) @@ -169,10 +215,10 @@ func (s *OrganizationsService) GetCodeSecurityConfiguration(ctx context.Context, // GitHub API docs: https://docs.github.com/rest/code-security/configurations#update-a-code-security-configuration // //meta:operation PATCH /orgs/{org}/code-security/configurations/{configuration_id} -func (s *OrganizationsService) UpdateCodeSecurityConfiguration(ctx context.Context, org string, id int64, c *CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { +func (s *OrganizationsService) UpdateCodeSecurityConfiguration(ctx context.Context, org string, id int64, config CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { u := fmt.Sprintf("orgs/%v/code-security/configurations/%v", org, id) - req, err := s.client.NewRequest("PATCH", u, c) + req, err := s.client.NewRequest("PATCH", u, config) if err != nil { return nil, nil, err } @@ -204,12 +250,12 @@ func (s *OrganizationsService) DeleteCodeSecurityConfiguration(ctx context.Conte return resp, nil } -// AttachCodeSecurityConfigurationsToRepositories attaches code security configurations to repositories for an organization. +// AttachCodeSecurityConfigurationToRepositories attaches code security configurations to repositories for an organization. // // GitHub API docs: https://docs.github.com/rest/code-security/configurations#attach-a-configuration-to-repositories // //meta:operation POST /orgs/{org}/code-security/configurations/{configuration_id}/attach -func (s *OrganizationsService) AttachCodeSecurityConfigurationsToRepositories(ctx context.Context, org string, id int64, scope string, repoIDs []int64) (*Response, error) { +func (s *OrganizationsService) AttachCodeSecurityConfigurationToRepositories(ctx context.Context, org string, id int64, scope string, repoIDs []int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/code-security/configurations/%v/attach", org, id) type selectedRepoIDs struct { Scope string `json:"scope"` @@ -240,12 +286,12 @@ func (s *OrganizationsService) SetDefaultCodeSecurityConfiguration(ctx context.C if err != nil { return nil, nil, err } - var c *CodeSecurityConfigurationWithDefaultForNewRepos - resp, err := s.client.Do(ctx, req, &c) + var config *CodeSecurityConfigurationWithDefaultForNewRepos + resp, err := s.client.Do(ctx, req, &config) if err != nil { return nil, resp, err } - return c, resp, nil + return config, resp, nil } // GetRepositoriesForCodeSecurityConfiguration gets repositories associated with a code security configuration. @@ -270,12 +316,12 @@ func (s *OrganizationsService) GetRepositoriesForCodeSecurityConfiguration(ctx c return attachments, resp, nil } -// GetCodeSecurityConfigurationForRepository gets code security configuration that manages a repository's code security settings. +// ListCodeSecurityConfigurationForRepository gets code security configuration that manages a repository's code security settings. // // GitHub API docs: https://docs.github.com/rest/code-security/configurations#get-the-code-security-configuration-associated-with-a-repository // //meta:operation GET /repos/{owner}/{repo}/code-security-configuration -func (s *OrganizationsService) GetCodeSecurityConfigurationForRepository(ctx context.Context, org, repo string) (*RepositoryCodeSecurityConfiguration, *Response, error) { +func (s *OrganizationsService) ListCodeSecurityConfigurationForRepository(ctx context.Context, org, repo string) (*RepositoryCodeSecurityConfiguration, *Response, error) { u := fmt.Sprintf("repos/%v/%v/code-security-configuration", org, repo) req, err := s.client.NewRequest("GET", u, nil) diff --git a/github/orgs_codesecurity_configurations_test.go b/github/orgs_codesecurity_configurations_test.go index 38034a5982d..aa62d75ff79 100644 --- a/github/orgs_codesecurity_configurations_test.go +++ b/github/orgs_codesecurity_configurations_test.go @@ -14,45 +14,49 @@ import ( "github.com/google/go-cmp/cmp" ) -func TestOrganizationsService_GetCodeSecurityConfigurations(t *testing.T) { +func TestOrganizationsService_ListCodeSecurityConfigurations(t *testing.T) { t.Parallel() + opts := &ListOrgCodeSecurityConfigurationOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(30), TargetType: Ptr("all")} ctx := t.Context() client, mux, _ := setup(t) mux.HandleFunc("/orgs/o/code-security/configurations", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testFormValues(t, r, values{"before": "1", "after": "2", "per_page": "30", "target_type": "all"}) fmt.Fprint(w, `[ { "id":1, "name":"config1", + "description":"desc1", "code_scanning_default_setup": "enabled" }, { "id":2, "name":"config2", + "description":"desc2", "private_vulnerability_reporting": "enabled" }]`) }) - configurations, _, err := client.Organizations.GetCodeSecurityConfigurations(ctx, "o") + configurations, _, err := client.Organizations.ListCodeSecurityConfigurations(ctx, "o", opts) if err != nil { - t.Errorf("Organizations.GetOrganizationCodeSecurityConfigurations returned error: %v", err) + t.Errorf("Organizations.ListCodeSecurityConfigurations returned error: %v", err) } want := []*CodeSecurityConfiguration{ - {ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")}, - {ID: Ptr(int64(2)), Name: Ptr("config2"), PrivateVulnerabilityReporting: Ptr("enabled")}, + {ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")}, + {ID: Ptr(int64(2)), Name: "config2", Description: "desc2", PrivateVulnerabilityReporting: Ptr("enabled")}, } if !cmp.Equal(configurations, want) { - t.Errorf("Organizations.GetCodeSecurityConfigurations returned %+v, want %+v", configurations, want) + t.Errorf("Organizations.ListCodeSecurityConfigurations returned %+v, want %+v", configurations, want) } - const methodName = "GetCodeSecurityConfigurations" + const methodName = "ListCodeSecurityConfigurations" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Organizations.GetCodeSecurityConfigurations(ctx, "\n") + _, _, err = client.Organizations.ListCodeSecurityConfigurations(ctx, "\n", opts) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetCodeSecurityConfigurations(ctx, "o") + got, resp, err := client.Organizations.ListCodeSecurityConfigurations(ctx, "o", opts) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -60,7 +64,7 @@ func TestOrganizationsService_GetCodeSecurityConfigurations(t *testing.T) { }) } -func TestOrganizationsService_GetCodeSecurityConfiguration(t *testing.T) { +func TestOrganizationsService_ListCodeSecurityConfiguration(t *testing.T) { t.Parallel() client, mux, _ := setup(t) ctx := t.Context() @@ -70,28 +74,29 @@ func TestOrganizationsService_GetCodeSecurityConfiguration(t *testing.T) { fmt.Fprint(w, `{ "id":1, "name":"config1", + "description":"desc1", "code_scanning_default_setup": "enabled" }`) }) - configuration, _, err := client.Organizations.GetCodeSecurityConfiguration(ctx, "o", 1) + configuration, _, err := client.Organizations.ListCodeSecurityConfiguration(ctx, "o", 1) if err != nil { - t.Errorf("Organizations.GetCodeSecurityConfiguration returned error: %v", err) + t.Errorf("Organizations.ListCodeSecurityConfiguration returned error: %v", err) } - want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")} + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} if !cmp.Equal(configuration, want) { - t.Errorf("Organizations.GetCodeSecurityConfiguration returned %+v, want %+v", configuration, want) + t.Errorf("Organizations.ListCodeSecurityConfiguration returned %+v, want %+v", configuration, want) } - const methodName = "GetCodeSecurityConfiguration" + const methodName = "ListCodeSecurityConfiguration" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Organizations.GetCodeSecurityConfiguration(ctx, "\n", -1) + _, _, err = client.Organizations.ListCodeSecurityConfiguration(ctx, "\n", -1) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetCodeSecurityConfiguration(ctx, "o", 1) + got, resp, err := client.Organizations.ListCodeSecurityConfiguration(ctx, "o", 1) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -104,14 +109,15 @@ func TestOrganizationsService_CreateCodeSecurityConfiguration(t *testing.T) { client, mux, _ := setup(t) ctx := t.Context() - input := &CodeSecurityConfiguration{ - Name: Ptr("config1"), + input := CodeSecurityConfiguration{ + Name: "config1", + Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled"), } mux.HandleFunc("/orgs/o/code-security/configurations", func(w http.ResponseWriter, r *http.Request) { - v := new(CodeSecurityConfiguration) - assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + var v CodeSecurityConfiguration + assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) if !cmp.Equal(v, input) { t.Errorf("Organizations.CreateCodeSecurityConfiguration request body = %+v, want %+v", v, input) @@ -120,6 +126,7 @@ func TestOrganizationsService_CreateCodeSecurityConfiguration(t *testing.T) { fmt.Fprint(w, `{ "id":1, "name":"config1", + "description":"desc1", "code_scanning_default_setup": "enabled" }`) }) @@ -129,7 +136,7 @@ func TestOrganizationsService_CreateCodeSecurityConfiguration(t *testing.T) { t.Errorf("Organizations.CreateCodeSecurityConfiguration returned error: %v", err) } - want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")} + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} if !cmp.Equal(configuration, want) { t.Errorf("Organizations.CreateCodeSecurityConfiguration returned %+v, want %+v", configuration, want) } @@ -162,6 +169,7 @@ func TestOrganizationsService_GetDefaultCodeSecurityConfigurations(t *testing.T) "configuration": { "id":1, "name":"config1", + "description":"desc1", "code_scanning_default_setup": "enabled" } }, @@ -170,6 +178,7 @@ func TestOrganizationsService_GetDefaultCodeSecurityConfigurations(t *testing.T) "configuration": { "id":2, "name":"config2", + "description":"desc2", "private_vulnerability_reporting": "enabled" } } @@ -182,8 +191,8 @@ func TestOrganizationsService_GetDefaultCodeSecurityConfigurations(t *testing.T) } want := []*CodeSecurityConfigurationWithDefaultForNewRepos{ - {DefaultForNewRepos: Ptr("public"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")}}, - {DefaultForNewRepos: Ptr("private_and_internal"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(2)), Name: Ptr("config2"), PrivateVulnerabilityReporting: Ptr("enabled")}}, + {DefaultForNewRepos: Ptr("public"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")}}, + {DefaultForNewRepos: Ptr("private_and_internal"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(2)), Name: "config2", Description: "desc2", PrivateVulnerabilityReporting: Ptr("enabled")}}, } if !cmp.Equal(configurations, want) { t.Errorf("Organizations.GetDefaultCodeSecurityConfigurations returned %+v, want %+v", configurations, want) @@ -241,14 +250,15 @@ func TestOrganizationsService_UpdateCodeSecurityConfiguration(t *testing.T) { ctx := t.Context() client, mux, _ := setup(t) - input := &CodeSecurityConfiguration{ - Name: Ptr("config1"), + input := CodeSecurityConfiguration{ + Name: "config1", + Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled"), } mux.HandleFunc("/orgs/o/code-security/configurations/1", func(w http.ResponseWriter, r *http.Request) { - v := new(CodeSecurityConfiguration) - assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + var v CodeSecurityConfiguration + assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) if !cmp.Equal(v, input) { t.Errorf("Organizations.UpdateCodeSecurityConfiguration request body = %+v, want %+v", v, input) @@ -257,6 +267,7 @@ func TestOrganizationsService_UpdateCodeSecurityConfiguration(t *testing.T) { fmt.Fprint(w, `{ "id":1, "name":"config1", + "description":"desc1", "code_scanning_default_setup": "enabled" }`) }) @@ -266,7 +277,7 @@ func TestOrganizationsService_UpdateCodeSecurityConfiguration(t *testing.T) { t.Errorf("Organizations.UpdateCodeSecurityConfiguration returned error: %v", err) } - want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")} + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} if !cmp.Equal(configuration, want) { t.Errorf("Organizations.UpdateCodeSecurityConfiguration returned %+v, want %+v", configuration, want) } @@ -318,7 +329,7 @@ func TestOrganizationsService_DeleteCodeSecurityConfiguration(t *testing.T) { }) } -func TestOrganizationsService_AttachCodeSecurityConfigurationsToRepositories(t *testing.T) { +func TestOrganizationsService_AttachCodeSecurityConfigurationToRepositories(t *testing.T) { t.Parallel() ctx := t.Context() client, mux, _ := setup(t) @@ -332,32 +343,32 @@ func TestOrganizationsService_AttachCodeSecurityConfigurationsToRepositories(t * v := new(request) assertNilError(t, json.NewDecoder(r.Body).Decode(v)) if v.Scope != "selected" { - t.Errorf("Organizations.AttachCodeSecurityConfigurationsToRepositories request body scope = %v, want selected", v.Scope) + t.Errorf("Organizations.AttachCodeSecurityConfigurationToRepositories request body scope = %v, want selected", v.Scope) } if !cmp.Equal(v.SelectedRepositoryIDs, []int64{5, 20}) { - t.Errorf("Organizations.AttachCodeSecurityConfigurationsToRepositories request body selected_repository_ids = %+v, want %+v", v.SelectedRepositoryIDs, []int64{5, 20}) + t.Errorf("Organizations.AttachCodeSecurityConfigurationToRepositories request body selected_repository_ids = %+v, want %+v", v.SelectedRepositoryIDs, []int64{5, 20}) } w.WriteHeader(http.StatusAccepted) }) - resp, err := client.Organizations.AttachCodeSecurityConfigurationsToRepositories(ctx, "o", int64(1), "selected", []int64{5, 20}) + resp, err := client.Organizations.AttachCodeSecurityConfigurationToRepositories(ctx, "o", int64(1), "selected", []int64{5, 20}) if err != nil { - t.Errorf("Organizations.AttachCodeSecurityConfigurationsToRepositories returned error: %v", err) + t.Errorf("Organizations.AttachCodeSecurityConfigurationToRepositories returned error: %v", err) } want := http.StatusAccepted if resp.StatusCode != want { - t.Errorf("Organizations.AttachCodeSecurityConfigurationsToRepositories returned status %v, want %v", resp.StatusCode, want) + t.Errorf("Organizations.AttachCodeSecurityConfigurationToRepositories returned status %v, want %v", resp.StatusCode, want) } - const methodName = "AttachCodeSecurityConfigurationsToRepositories" + const methodName = "AttachCodeSecurityConfigurationToRepositories" testBadOptions(t, methodName, func() (err error) { - _, err = client.Organizations.AttachCodeSecurityConfigurationsToRepositories(ctx, "\n", -1, "", nil) + _, err = client.Organizations.AttachCodeSecurityConfigurationToRepositories(ctx, "\n", -1, "", nil) return }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - resp, err := client.Organizations.AttachCodeSecurityConfigurationsToRepositories(ctx, "o", 1, "selected", []int64{5, 20}) + resp, err := client.Organizations.AttachCodeSecurityConfigurationToRepositories(ctx, "o", 1, "selected", []int64{5, 20}) return resp, err }) } @@ -376,6 +387,7 @@ func TestOrganizationsService_SetDefaultCodeSecurityConfiguration(t *testing.T) { "id": 1, "name": "config1", + "description": "desc1", "code_scanning_default_setup": "enabled" } }`) @@ -391,7 +403,7 @@ func TestOrganizationsService_SetDefaultCodeSecurityConfiguration(t *testing.T) want := &CodeSecurityConfigurationWithDefaultForNewRepos{ DefaultForNewRepos: Ptr("all"), Configuration: &CodeSecurityConfiguration{ - ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled"), + ID: Ptr(int64(1)), Name: "config1", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled"), }, } if !cmp.Equal(got, want) { @@ -465,7 +477,7 @@ func TestOrganizationsService_GetRepositoriesForCodeSecurityConfiguration(t *tes }) } -func TestOrganizationsService_GetCodeSecurityConfigurationForRepository(t *testing.T) { +func TestOrganizationsService_ListCodeSecurityConfigurationForRepository(t *testing.T) { t.Parallel() ctx := t.Context() client, mux, _ := setup(t) @@ -477,32 +489,33 @@ func TestOrganizationsService_GetCodeSecurityConfigurationForRepository(t *testi "configuration": { "id":42, "name":"config42", + "description":"desc1", "code_scanning_default_setup": "enabled" } }`) }) - rc, _, err := client.Organizations.GetCodeSecurityConfigurationForRepository(ctx, "o", "repo8") + rc, _, err := client.Organizations.ListCodeSecurityConfigurationForRepository(ctx, "o", "repo8") if err != nil { - t.Errorf("Organizations.GetCodeSecurityConfigurationForRepository returned error: %v", err) + t.Errorf("Organizations.ListCodeSecurityConfigurationForRepository returned error: %v", err) } - c := &CodeSecurityConfiguration{ID: Ptr(int64(42)), Name: Ptr("config42"), CodeScanningDefaultSetup: Ptr("enabled")} + c := &CodeSecurityConfiguration{ID: Ptr(int64(42)), Name: "config42", Description: "desc1", CodeScanningDefaultSetup: Ptr("enabled")} want := &RepositoryCodeSecurityConfiguration{ State: Ptr("attached"), Configuration: c, } if !cmp.Equal(rc, want) { - t.Errorf("Organizations.GetCodeSecurityConfigurationForRepository returned %+v, want %+v", rc, want) + t.Errorf("Organizations.ListCodeSecurityConfigurationForRepository returned %+v, want %+v", rc, want) } - const methodName = "GetCodeSecurityConfigurationForRepository" + const methodName = "ListCodeSecurityConfigurationForRepository" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Organizations.GetCodeSecurityConfigurationForRepository(ctx, "\n", "\n") + _, _, err = client.Organizations.ListCodeSecurityConfigurationForRepository(ctx, "\n", "\n") return }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetCodeSecurityConfigurationForRepository(ctx, "o", "repo8") + got, resp, err := client.Organizations.ListCodeSecurityConfigurationForRepository(ctx, "o", "repo8") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) }