diff --git a/github/enterprise_codesecurity_configurations.go b/github/enterprise_codesecurity_configurations.go new file mode 100644 index 00000000000..83c9c5e603a --- /dev/null +++ b/github/enterprise_codesecurity_configurations.go @@ -0,0 +1,201 @@ +// 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" +) + +// GetCodeSecurityConfigurations 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) GetCodeSecurityConfigurations(ctx context.Context, enterprise string) ([]*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations", enterprise) + + 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, c *CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations", enterprise) + + req, err := s.client.NewRequest("POST", u, c) + 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 +} + +// GetCodeSecurityConfiguration 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) GetCodeSecurityConfiguration(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, c *CodeSecurityConfiguration) (*CodeSecurityConfiguration, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code-security/configurations/%v", enterprise, id) + + req, err := s.client.NewRequest("PATCH", u, c) + 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. +// +// 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. +// +// 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, newReposParam 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: newReposParam}) + if err != nil { + return nil, nil, err + } + var c *CodeSecurityConfigurationWithDefaultForNewRepos + resp, err := s.client.Do(ctx, req, &c) + if err != nil { + return nil, resp, err + } + return c, 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..48535d67b13 --- /dev/null +++ b/github/enterprise_codesecurity_configurations_test.go @@ -0,0 +1,430 @@ +// 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_GetCodeSecurityConfigurations(t *testing.T) { + t.Parallel() + 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") + fmt.Fprint(w, `[ + { + "id":1, + "name":"config1", + "code_scanning_default_setup": "enabled" + }, + { + "id":2, + "name":"config2", + "private_vulnerability_reporting": "enabled" + }]`) + }) + + configurations, _, err := client.Enterprise.GetCodeSecurityConfigurations(ctx, "e") + if err != nil { + t.Errorf("Enterprise.GetCodeSecurityConfigurations 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")}, + } + if !cmp.Equal(configurations, want) { + t.Errorf("Enterprise.GetCodeSecurityConfigurations returned %+v, want %+v", configurations, want) + } + const methodName = "GetCodeSecurityConfigurations" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetCodeSecurityConfigurations(ctx, "\n") + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetCodeSecurityConfigurations(ctx, "e") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_GetCodeSecurityConfiguration(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", + "code_scanning_default_setup": "enabled" + }`) + }) + + configuration, _, err := client.Enterprise.GetCodeSecurityConfiguration(ctx, "e", 1) + if err != nil { + t.Errorf("Enterprise.GetCodeSecurityConfiguration returned error: %v", err) + } + + want := &CodeSecurityConfiguration{ID: Ptr(int64(1)), Name: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")} + if !cmp.Equal(configuration, want) { + t.Errorf("Enterprise.GetCodeSecurityConfiguration returned %+v, want %+v", configuration, want) + } + + const methodName = "GetCodeSecurityConfiguration" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetCodeSecurityConfiguration(ctx, "\n", -1) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetCodeSecurityConfiguration(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: Ptr("config1"), + CodeScanningDefaultSetup: Ptr("enabled"), + } + + mux.HandleFunc("/enterprises/e/code-security/configurations", func(w http.ResponseWriter, r *http.Request) { + v := new(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", + "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: Ptr("config1"), 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", + "code_scanning_default_setup": "enabled" + } + }, + { + "default_for_new_repos": "private_and_internal", + "configuration": { + "id":2, + "name":"config2", + "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: Ptr("config1"), CodeScanningDefaultSetup: Ptr("enabled")}}, + {DefaultForNewRepos: Ptr("private_and_internal"), Configuration: &CodeSecurityConfiguration{ID: Ptr(int64(2)), Name: Ptr("config2"), 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: Ptr("config1"), + CodeScanningDefaultSetup: Ptr("enabled"), + } + + mux.HandleFunc("/enterprises/e/code-security/configurations/1", func(w http.ResponseWriter, r *http.Request) { + v := new(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", + "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: Ptr("config1"), 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", + "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: Ptr("config1"), 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..3cd404215f1 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 { @@ -3358,6 +3406,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 +3422,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 { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 33f25e90ee3..bf53e3eff0c 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 @@ -4382,6 +4442,17 @@ func TestCodeSecurityConfiguration_GetPrivateVulnerabilityReporting(tt *testing. c.GetPrivateVulnerabilityReporting() } +func TestCodeSecurityConfiguration_GetSecretProtection(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodeSecurityConfiguration{SecretProtection: &zeroValue} + c.GetSecretProtection() + c = &CodeSecurityConfiguration{} + c.GetSecretProtection() + c = nil + c.GetSecretProtection() +} + func TestCodeSecurityConfiguration_GetSecretScanning(tt *testing.T) { tt.Parallel() var zeroValue string @@ -4393,6 +4464,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 diff --git a/github/orgs_codesecurity_configurations.go b/github/orgs_codesecurity_configurations.go index b78bbbc28fc..8032d0aecfb 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"` @@ -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"` @@ -204,12 +222,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"` diff --git a/github/orgs_codesecurity_configurations_test.go b/github/orgs_codesecurity_configurations_test.go index 38034a5982d..5c52c08d135 100644 --- a/github/orgs_codesecurity_configurations_test.go +++ b/github/orgs_codesecurity_configurations_test.go @@ -36,7 +36,7 @@ func TestOrganizationsService_GetCodeSecurityConfigurations(t *testing.T) { configurations, _, err := client.Organizations.GetCodeSecurityConfigurations(ctx, "o") if err != nil { - t.Errorf("Organizations.GetOrganizationCodeSecurityConfigurations returned error: %v", err) + t.Errorf("Organizations.GetCodeSecurityConfigurations returned error: %v", err) } want := []*CodeSecurityConfiguration{ @@ -318,7 +318,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 +332,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 }) }