Skip to content

feat: Add support for Private Vulnerability Reporting#2969

Open
eslerm wants to merge 1 commit intointegrations:mainfrom
eslerm:feature/private-vulnerability-reporting
Open

feat: Add support for Private Vulnerability Reporting#2969
eslerm wants to merge 1 commit intointegrations:mainfrom
eslerm:feature/private-vulnerability-reporting

Conversation

@eslerm
Copy link

@eslerm eslerm commented Dec 5, 2025

Adds private_vulnerability_reporting to the github_repository resource's security_and_analysis block.

Implementation uses dedicated GitHub API endpoints rather than the repository Edit API, since PVR status is not included in the SecurityAndAnalysis response:

  • EnablePrivateReporting/DisablePrivateReporting for writes
  • IsPrivateReportingEnabled for reads
  • Gracefully handles repos where PVR is unavailable

Changes:

  • Add private_vulnerability_reporting schema field (Optional, Computed)
  • Add updatePrivateVulnerabilityReporting helper function
  • Fetch and merge PVR status separately in Read function
  • Add acceptance test for public repository PVR management
  • Add documentation for private_vulnerability_reporting field

Resolves #2399

@github-actions github-actions bot added the Type: Feature New feature or request label Dec 5, 2025
Copy link

@cpanato cpanato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

+1

@deiga
Copy link
Collaborator

deiga commented Jan 24, 2026

Hey @eslerm

Thank you for your contribution!

Could you change your approach here? Instead of adding a new field to github_repository please create a new resource.
~Every API endpoint should be a separate resource in Terraform as that makes dealing with edge-cases and errors a lot simpler and has the least potential for breaking State

Add a standalone resource for managing private vulnerability reporting
on GitHub repositories, following the pattern established by
github_repository_dependabot_security_updates.

Includes 404 handling for unavailable repos, archived repo handling
in delete, and comprehensive tests including import and private repo
validation.

Closes integrations#2399
@eslerm eslerm force-pushed the feature/private-vulnerability-reporting branch from 6e22178 to 69c7e18 Compare March 6, 2026 06:03
@eslerm
Copy link
Author

eslerm commented Mar 6, 2026

Rebased onto main and refactored per @deiga's feedback — private vulnerability reporting is now a standalone resource (github_repository_private_vulnerability_reporting) instead of a field on github_repository.

The resource follows the same pattern as github_repository_dependabot_security_updates:

  • repository (required, ForceNew) and enabled (required, bool) schema
  • CRUD via EnablePrivateReporting/DisablePrivateReporting/IsPrivateReportingEnabled APIs
  • Import by repository name

Additional improvements over the reference pattern:

  • 404 handling in Read (gracefully removes from state if repo is deleted or PVR unavailable)
  • Archived repository handling in Delete via handleArchivedRepoDelete
  • Error wrapping with fmt.Errorf for better debugging context
  • Test for private repo rejection (PVR is public-only)
  • CheckDestroy validation in all test cases

Please let me know if I can make improvements!

Comment on lines +16 to +21
Create: resourceGithubRepositoryPrivateVulnerabilityReportingCreateOrUpdate,
Read: resourceGithubRepositoryPrivateVulnerabilityReportingRead,
Update: resourceGithubRepositoryPrivateVulnerabilityReportingCreateOrUpdate,
Delete: resourceGithubRepositoryPrivateVulnerabilityReportingDelete,
Importer: &schema.ResourceImporter{
State: resourceGithubRepositoryPrivateVulnerabilityReportingImport,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the Context-aware functions here

Comment on lines +25 to +30
"repository": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The GitHub repository.",
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please adopt the repo rename pattern which has been introduced:

  • Remove ForceNew
  • Add new Computed field repository_id
  • Add diffRepository to CustomizeDiff


func resourceGithubRepositoryPrivateVulnerabilityReporting() *schema.Resource {
return &schema.Resource{
Create: resourceGithubRepositoryPrivateVulnerabilityReportingCreateOrUpdate,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a top-level Describe

return fmt.Errorf("error setting private vulnerability reporting for repository %s/%s: %w", owner, repoName, err)
}
d.SetId(repoName)
return resourceGithubRepositoryPrivateVulnerabilityReportingRead(d, meta)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every CRUD function should have no calls to other CRUD functions

if err != nil {
var ghErr *github.ErrorResponse
if errors.As(err, &ghErr) && ghErr.Response.StatusCode == http.StatusNotFound {
log.Printf("[WARN] private vulnerability reporting not available for %s/%s, removing from state", owner, repoName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use tflog


_ = d.Set("repository", repoName)

err := resourceGithubRepositoryPrivateVulnerabilityReportingRead(d, meta)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not call any CRUD functions directly

func resourceGithubRepositoryPrivateVulnerabilityReportingImport(d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
repoName := d.Id()

_ = d.Set("repository", repoName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not swallow errors

Comment on lines +34 to +47
checks := map[string]resource.TestCheckFunc{
"before": resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_repository_private_vulnerability_reporting.test", "enabled",
"false",
),
),
"after": resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_repository_private_vulnerability_reporting.test", "enabled",
"true",
),
),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use a separate variable for these

Steps: []resource.TestStep{
{
Config: config,
Check: checks["before"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use ConfigStateChecks instead

Comment on lines +59 to +61
Config: strings.Replace(config,
enabled,
updatedEnabled, 1),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use strings.Replace on the config, rather use fmt.Sprintf

@eslerm
Copy link
Author

eslerm commented Mar 9, 2026

Thank you @deiga 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT]: Add "Privately reporting a security vulnerability" feature

3 participants