Repository: google/go-github
Pull request #3026 (2023-12-11 14:06:30)

Add scanning validity checks
Solves #3006

google-cla[bot]: Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this [failed invocation](https://github.com/google/go-github/pull/3026/checks?check_run_id=19517141425) of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.
tomasz-adam-skrzypczak: I've managed to accept CLA and added my github email address as an alternative but I cannot rerun workflow (and don't want to commit pointless commits). @gmlewis could you rerun workflow for me?
gmlewis: Whups, please run step 4 of CONTRIBUTING.md and push the results.
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/google/go-github/pull/3026?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`fb8a83d`)](https://app.codecov.io/gh/google/go-github/commit/fb8a83de3e7046c49ab76e09a4e9b5857f8f3997?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) 97.91% compared to head [(`ad453fa`)](https://app.codecov.io/gh/google/go-github/pull/3026?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) 97.91%.


<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #3026   +/-   ##
=======================================
  Coverage   97.91%   97.91%           
=======================================
  Files         150      150           
  Lines       12980    12980           
=======================================
  Hits        12710    12710           
  Misses        192      192           
  Partials       78       78           
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/google/go-github/pull/3026?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).

gmlewis: Thank you, @rufusnufus !
Merging.

Patch:
diff --git a/github/enterprise_code_security_and_analysis.go b/github/enterprise_code_security_and_analysis.go
index af8eb0ff..159aeae4 100644
--- a/github/enterprise_code_security_and_analysis.go
+++ b/github/enterprise_code_security_and_analysis.go
@@ -16,6 +16,7 @@ type EnterpriseSecurityAnalysisSettings struct {
 	SecretScanningEnabledForNewRepositories               *bool   `json:"secret_scanning_enabled_for_new_repositories,omitempty"`
 	SecretScanningPushProtectionEnabledForNewRepositories *bool   `json:"secret_scanning_push_protection_enabled_for_new_repositories,omitempty"`
 	SecretScanningPushProtectionCustomLink                *string `json:"secret_scanning_push_protection_custom_link,omitempty"`
+	SecretScanningValidityChecksEnabled                   *bool   `json:"secret_scanning_validity_checks_enabled,omitempty"`
 }
 
 // GetCodeSecurityAndAnalysis gets code security and analysis features for an enterprise.
diff --git a/github/github-accessors.go b/github/github-accessors.go
index e15eb102..4cb34b12 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -6974,6 +6974,14 @@ func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningPushProtectionEnab
 	return *e.SecretScanningPushProtectionEnabledForNewRepositories
 }
 
+// GetSecretScanningValidityChecksEnabled returns the SecretScanningValidityChecksEnabled field if it's non-nil, zero value otherwise.
+func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningValidityChecksEnabled() bool {
+	if e == nil || e.SecretScanningValidityChecksEnabled == nil {
+		return false
+	}
+	return *e.SecretScanningValidityChecksEnabled
+}
+
 // GetCanAdminsBypass returns the CanAdminsBypass field if it's non-nil, zero value otherwise.
 func (e *Environment) GetCanAdminsBypass() bool {
 	if e == nil || e.CanAdminsBypass == nil {
@@ -12734,6 +12742,14 @@ func (o *Organization) GetSecretScanningPushProtectionEnabledForNewRepos() bool
 	return *o.SecretScanningPushProtectionEnabledForNewRepos
 }
 
+// GetSecretScanningValidityChecksEnabled returns the SecretScanningValidityChecksEnabled field if it's non-nil, zero value otherwise.
+func (o *Organization) GetSecretScanningValidityChecksEnabled() bool {
+	if o == nil || o.SecretScanningValidityChecksEnabled == nil {
+		return false
+	}
+	return *o.SecretScanningValidityChecksEnabled
+}
+
 // GetTotalPrivateRepos returns the TotalPrivateRepos field if it's non-nil, zero value otherwise.
 func (o *Organization) GetTotalPrivateRepos() int64 {
 	if o == nil || o.TotalPrivateRepos == nil {
@@ -21590,6 +21606,14 @@ func (s *SecretScanningPushProtection) GetStatus() string {
 	return *s.Status
 }
 
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (s *SecretScanningValidityChecks) GetStatus() string {
+	if s == nil || s.Status == nil {
+		return ""
+	}
+	return *s.Status
+}
+
 // GetAuthor returns the Author field.
 func (s *SecurityAdvisory) GetAuthor() *User {
 	if s == nil {
@@ -21830,6 +21854,14 @@ func (s *SecurityAndAnalysis) GetSecretScanningPushProtection() *SecretScanningP
 	return s.SecretScanningPushProtection
 }
 
+// GetSecretScanningValidityChecks returns the SecretScanningValidityChecks field.
+func (s *SecurityAndAnalysis) GetSecretScanningValidityChecks() *SecretScanningValidityChecks {
+	if s == nil {
+		return nil
+	}
+	return s.SecretScanningValidityChecks
+}
+
 // GetFrom returns the From field.
 func (s *SecurityAndAnalysisChange) GetFrom() *SecurityAndAnalysisChangeFrom {
 	if s == nil {
diff --git a/github/orgs.go b/github/orgs.go
index 4d346527..27c0f102 100644
--- a/github/orgs.go
+++ b/github/orgs.go
@@ -95,6 +95,8 @@ type Organization struct {
 	SecretScanningEnabledForNewRepos *bool `json:"secret_scanning_enabled_for_new_repositories,omitempty"`
 	// SecretScanningPushProtectionEnabledForNewRepos toggles whether secret scanning push protection is enabled on new repositories.
 	SecretScanningPushProtectionEnabledForNewRepos *bool `json:"secret_scanning_push_protection_enabled_for_new_repositories,omitempty"`
+	// SecretScanningValidityChecksEnabled toggles whether secret scanning validity check is enabled.
+	SecretScanningValidityChecksEnabled *bool `json:"secret_scanning_validity_checks_enabled,omitempty"`
 
 	// API URLs
 	URL              *string `json:"url,omitempty"`
diff --git a/github/repos.go b/github/repos.go
index 5fcf219b..a7574d72 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -198,6 +198,7 @@ type SecurityAndAnalysis struct {
 	SecretScanning               *SecretScanning               `json:"secret_scanning,omitempty"`
 	SecretScanningPushProtection *SecretScanningPushProtection `json:"secret_scanning_push_protection,omitempty"`
 	DependabotSecurityUpdates    *DependabotSecurityUpdates    `json:"dependabot_security_updates,omitempty"`
+	SecretScanningValidityChecks *SecretScanningValidityChecks `json:"secret_scanning_validity_checks,omitempty"`
 }
 
 func (s SecurityAndAnalysis) String() string {
@@ -248,6 +249,13 @@ func (d DependabotSecurityUpdates) String() string {
 	return Stringify(d)
 }
 
+// SecretScanningValidityChecks represents the state of secret scanning validity checks on a repository.
+//
+// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository#allowing-validity-checks-for-partner-patterns-in-a-repository
+type SecretScanningValidityChecks struct {
+	Status *string `json:"status,omitempty"`
+}
+
 // List calls either RepositoriesService.ListByUser or RepositoriesService.ListByAuthenticatedUser
 // depending on whether user is empty.
 //


Test patch:
diff --git a/github/enterprise_code_security_and_analysis_test.go b/github/enterprise_code_security_and_analysis_test.go
index 25dbd941..17bbe18b 100644
--- a/github/enterprise_code_security_and_analysis_test.go
+++ b/github/enterprise_code_security_and_analysis_test.go
@@ -27,7 +27,8 @@ func TestEnterpriseService_GetCodeSecurityAndAnalysis(t *testing.T) {
 		  "advanced_security_enabled_for_new_repositories": true,
 		  "secret_scanning_enabled_for_new_repositories": true,
 		  "secret_scanning_push_protection_enabled_for_new_repositories": true,
-		  "secret_scanning_push_protection_custom_link": "https://github.com/test-org/test-repo/blob/main/README.md"
+		  "secret_scanning_push_protection_custom_link": "https://github.com/test-org/test-repo/blob/main/README.md",
+		  "secret_scanning_validity_checks_enabled": true
 		}`)
 	})
 
@@ -44,6 +45,7 @@ func TestEnterpriseService_GetCodeSecurityAndAnalysis(t *testing.T) {
 		SecretScanningEnabledForNewRepositories:               Bool(true),
 		SecretScanningPushProtectionEnabledForNewRepositories: Bool(true),
 		SecretScanningPushProtectionCustomLink:                String("https://github.com/test-org/test-repo/blob/main/README.md"),
+		SecretScanningValidityChecksEnabled:                   Bool(true),
 	}
 
 	if !cmp.Equal(settings, want) {
@@ -73,6 +75,7 @@ func TestEnterpriseService_UpdateCodeSecurityAndAnalysis(t *testing.T) {
 		SecretScanningEnabledForNewRepositories:               Bool(true),
 		SecretScanningPushProtectionEnabledForNewRepositories: Bool(true),
 		SecretScanningPushProtectionCustomLink:                String("https://github.com/test-org/test-repo/blob/main/README.md"),
+		SecretScanningValidityChecksEnabled:                   Bool(true),
 	}
 
 	mux.HandleFunc("/enterprises/e/code_security_and_analysis", func(w http.ResponseWriter, r *http.Request) {
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 84d104f1..cdc27ab9 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -8175,6 +8175,16 @@ func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningPushProtectionEnabl
 	e.GetSecretScanningPushProtectionEnabledForNewRepositories()
 }
 
+func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningValidityChecksEnabled(tt *testing.T) {
+	var zeroValue bool
+	e := &EnterpriseSecurityAnalysisSettings{SecretScanningValidityChecksEnabled: &zeroValue}
+	e.GetSecretScanningValidityChecksEnabled()
+	e = &EnterpriseSecurityAnalysisSettings{}
+	e.GetSecretScanningValidityChecksEnabled()
+	e = nil
+	e.GetSecretScanningValidityChecksEnabled()
+}
+
 func TestEnvironment_GetCanAdminsBypass(tt *testing.T) {
 	var zeroValue bool
 	e := &Environment{CanAdminsBypass: &zeroValue}
@@ -14928,6 +14938,16 @@ func TestOrganization_GetSecretScanningPushProtectionEnabledForNewRepos(tt *test
 	o.GetSecretScanningPushProtectionEnabledForNewRepos()
 }
 
+func TestOrganization_GetSecretScanningValidityChecksEnabled(tt *testing.T) {
+	var zeroValue bool
+	o := &Organization{SecretScanningValidityChecksEnabled: &zeroValue}
+	o.GetSecretScanningValidityChecksEnabled()
+	o = &Organization{}
+	o.GetSecretScanningValidityChecksEnabled()
+	o = nil
+	o.GetSecretScanningValidityChecksEnabled()
+}
+
 func TestOrganization_GetTotalPrivateRepos(tt *testing.T) {
 	var zeroValue int64
 	o := &Organization{TotalPrivateRepos: &zeroValue}
@@ -25149,6 +25169,16 @@ func TestSecretScanningPushProtection_GetStatus(tt *testing.T) {
 	s.GetStatus()
 }
 
+func TestSecretScanningValidityChecks_GetStatus(tt *testing.T) {
+	var zeroValue string
+	s := &SecretScanningValidityChecks{Status: &zeroValue}
+	s.GetStatus()
+	s = &SecretScanningValidityChecks{}
+	s.GetStatus()
+	s = nil
+	s.GetStatus()
+}
+
 func TestSecurityAdvisory_GetAuthor(tt *testing.T) {
 	s := &SecurityAdvisory{}
 	s.GetAuthor()
@@ -25404,6 +25434,13 @@ func TestSecurityAndAnalysis_GetSecretScanningPushProtection(tt *testing.T) {
 	s.GetSecretScanningPushProtection()
 }
 
+func TestSecurityAndAnalysis_GetSecretScanningValidityChecks(tt *testing.T) {
+	s := &SecurityAndAnalysis{}
+	s.GetSecretScanningValidityChecks()
+	s = nil
+	s.GetSecretScanningValidityChecks()
+}
+
 func TestSecurityAndAnalysisChange_GetFrom(tt *testing.T) {
 	s := &SecurityAndAnalysisChange{}
 	s.GetFrom()
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index 7472edfd..bb69ce1a 100644
--- a/github/github-stringify_test.go
+++ b/github/github-stringify_test.go
@@ -1051,15 +1051,16 @@ func TestOrganization_String(t *testing.T) {
 		DependencyGraphEnabledForNewRepos:              Bool(false),
 		SecretScanningEnabledForNewRepos:               Bool(false),
 		SecretScanningPushProtectionEnabledForNewRepos: Bool(false),
-		URL:              String(""),
-		EventsURL:        String(""),
-		HooksURL:         String(""),
-		IssuesURL:        String(""),
-		MembersURL:       String(""),
-		PublicMembersURL: String(""),
-		ReposURL:         String(""),
+		SecretScanningValidityChecksEnabled:            Bool(false),
+		URL:                                            String(""),
+		EventsURL:                                      String(""),
+		HooksURL:                                       String(""),
+		IssuesURL:                                      String(""),
+		MembersURL:                                     String(""),
+		PublicMembersURL:                               String(""),
+		ReposURL:                                       String(""),
 	}
-	want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", TwitterUsername:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, IsVerified:false, HasOrganizationProjects:false, HasRepositoryProjects:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersCanForkPrivateRepos:false, MembersAllowedRepositoryCreationType:"", MembersCanCreatePages:false, MembersCanCreatePublicPages:false, MembersCanCreatePrivatePages:false, WebCommitSignoffRequired:false, AdvancedSecurityEnabledForNewRepos:false, DependabotAlertsEnabledForNewRepos:false, DependabotSecurityUpdatesEnabledForNewRepos:false, DependencyGraphEnabledForNewRepos:false, SecretScanningEnabledForNewRepos:false, SecretScanningPushProtectionEnabledForNewRepos:false, URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}`
+	want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", TwitterUsername:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, IsVerified:false, HasOrganizationProjects:false, HasRepositoryProjects:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersCanForkPrivateRepos:false, MembersAllowedRepositoryCreationType:"", MembersCanCreatePages:false, MembersCanCreatePublicPages:false, MembersCanCreatePrivatePages:false, WebCommitSignoffRequired:false, AdvancedSecurityEnabledForNewRepos:false, DependabotAlertsEnabledForNewRepos:false, DependabotSecurityUpdatesEnabledForNewRepos:false, DependencyGraphEnabledForNewRepos:false, SecretScanningEnabledForNewRepos:false, SecretScanningPushProtectionEnabledForNewRepos:false, SecretScanningValidityChecksEnabled:false, URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}`
 	if got := v.String(); got != want {
 		t.Errorf("Organization.String = %v, want %v", got, want)
 	}
@@ -1826,8 +1827,9 @@ func TestSecurityAndAnalysis_String(t *testing.T) {
 		SecretScanning:               &SecretScanning{},
 		SecretScanningPushProtection: &SecretScanningPushProtection{},
 		DependabotSecurityUpdates:    &DependabotSecurityUpdates{},
+		SecretScanningValidityChecks: &SecretScanningValidityChecks{},
 	}
-	want := `github.SecurityAndAnalysis{AdvancedSecurity:github.AdvancedSecurity{}, SecretScanning:github.SecretScanning{}, SecretScanningPushProtection:github.SecretScanningPushProtection{}, DependabotSecurityUpdates:github.DependabotSecurityUpdates{}}`
+	want := `github.SecurityAndAnalysis{AdvancedSecurity:github.AdvancedSecurity{}, SecretScanning:github.SecretScanning{}, SecretScanningPushProtection:github.SecretScanningPushProtection{}, DependabotSecurityUpdates:github.DependabotSecurityUpdates{}, SecretScanningValidityChecks:github.SecretScanningValidityChecks{}}`
 	if got := v.String(); got != want {
 		t.Errorf("SecurityAndAnalysis.String = %v, want %v", got, want)
 	}
diff --git a/github/repos_test.go b/github/repos_test.go
index fa49ddd4..2e61aeb1 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -360,7 +360,7 @@ func TestRepositoriesService_Get(t *testing.T) {
 	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
-		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"},"dependabot_security_updates":{"status": "enabled"}}}`)
+		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"},"dependabot_security_updates":{"status": "enabled"}, "secret_scanning_validity_checks":{"status":"enabled"}}}`)
 	})
 
 	ctx := context.Background()
@@ -369,7 +369,7 @@ func TestRepositoriesService_Get(t *testing.T) {
 		t.Errorf("Repositories.Get returned error: %v", err)
 	}
 
-	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{String("enabled")}, DependabotSecurityUpdates: &DependabotSecurityUpdates{String("enabled")}}}
+	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{String("enabled")}, DependabotSecurityUpdates: &DependabotSecurityUpdates{String("enabled")}, SecretScanningValidityChecks: &SecretScanningValidityChecks{String("enabled")}}}
 	if !cmp.Equal(got, want) {
 		t.Errorf("Repositories.Get returned %+v, want %+v", got, want)
 	}