Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions github/resource_github_organization_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ func resourceGithubOrganizationSettings() *schema.Resource {
"members_can_fork_private_repositories": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Whether or not organization members can fork private repositories.",
Computed: true,
Description: "Whether or not organization members can fork private repositories. When an enterprise policy controls this setting, omit this attribute to avoid API validation errors.",
},
"web_commit_signoff_required": {
Type: schema.TypeBool,
Expand Down Expand Up @@ -266,7 +266,11 @@ func buildOrganizationSettings(d *schema.ResourceData, isEnterprise bool) *githu
if shouldInclude("members_can_create_private_pages") {
settings.MembersCanCreatePrivatePages = new(d.Get("members_can_create_private_pages").(bool))
}
if shouldInclude("members_can_fork_private_repositories") {
if !isUpdate {
if _, ok := d.GetOkExists("members_can_fork_private_repositories"); ok { //nolint:staticcheck // SA1019 // GetOkExists needed for Computed+Optional bool fields
settings.MembersCanForkPrivateRepos = new(d.Get("members_can_fork_private_repositories").(bool))
}
} else if d.HasChange("members_can_fork_private_repositories") {
settings.MembersCanForkPrivateRepos = new(d.Get("members_can_fork_private_repositories").(bool))
}
if shouldInclude("web_commit_signoff_required") {
Expand Down
32 changes: 32 additions & 0 deletions github/resource_github_organization_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,3 +611,35 @@ func TestAccGithubOrganizationSettings(t *testing.T) {
})
})
}

func TestAccGithubOrganizationSettings_omittedForkFieldProducesCleanPlan(t *testing.T) {
config := `
resource "github_organization_settings" "test" {
billing_email = "test@example.com"
}`

resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessHasOrgs(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_organization_settings.test",
"billing_email", "test@example.com",
),
resource.TestCheckResourceAttrSet(
"github_organization_settings.test",
"members_can_fork_private_repositories",
),
),
},
{
Config: config,
PlanOnly: true,
ExpectNonEmptyPlan: false,
},
},
})
}
104 changes: 104 additions & 0 deletions github/resource_github_organization_settings_unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package github

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func TestBuildOrganizationSettings_OmittedFieldsNotSent(t *testing.T) {
resource := resourceGithubOrganizationSettings()
d := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"billing_email": "test@example.com",
})

settings := buildOrganizationSettings(d, false)

if settings.MembersCanForkPrivateRepos != nil {
t.Error("MembersCanForkPrivateRepos should be nil when not configured")
}
if settings.BillingEmail == nil {
t.Error("BillingEmail should be set when configured")
}
}

func TestBuildOrganizationSettings_ExplicitTrueFieldsSent(t *testing.T) {
resource := resourceGithubOrganizationSettings()
d := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"billing_email": "test@example.com",
"members_can_fork_private_repositories": true,
})

settings := buildOrganizationSettings(d, false)

if settings.MembersCanForkPrivateRepos == nil {
t.Fatal("MembersCanForkPrivateRepos should not be nil when explicitly set to true")
}
if *settings.MembersCanForkPrivateRepos != true {
t.Errorf("MembersCanForkPrivateRepos = %v, want true", *settings.MembersCanForkPrivateRepos)
}
}

func TestBuildOrganizationSettings_ExplicitFalseFieldsSent(t *testing.T) {
resource := resourceGithubOrganizationSettings()
d := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"billing_email": "test@example.com",
"members_can_fork_private_repositories": false,
})

settings := buildOrganizationSettings(d, false)

if settings.MembersCanForkPrivateRepos == nil {
t.Fatal("MembersCanForkPrivateRepos should not be nil when explicitly set to false")
}
if *settings.MembersCanForkPrivateRepos != false {
t.Errorf("MembersCanForkPrivateRepos = %v, want false", *settings.MembersCanForkPrivateRepos)
}
}

func TestBuildOrganizationSettings_UpdateOmittedFieldsNotSent(t *testing.T) {
resource := resourceGithubOrganizationSettings()
d := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"billing_email": "test@example.com",
})
d.SetId("test-org")

settings := buildOrganizationSettings(d, false)

if settings.MembersCanForkPrivateRepos != nil {
t.Error("MembersCanForkPrivateRepos should be nil on update when field has not changed")
}
}

func TestBuildOrganizationSettings_NonEnterpriseExcludesInternalRepos(t *testing.T) {
resource := resourceGithubOrganizationSettings()
d := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"billing_email": "test@example.com",
"members_can_create_internal_repositories": true,
})

settings := buildOrganizationSettings(d, false)

if settings.MembersCanCreateInternalRepos != nil {
t.Error("MembersCanCreateInternalRepos should be nil when not enterprise")
}
}

func TestOrganizationSettingsSchemaProperties(t *testing.T) {
resource := resourceGithubOrganizationSettings()

field := resource.Schema["members_can_fork_private_repositories"]
if field == nil {
t.Fatal("members_can_fork_private_repositories not found in schema")
}

if !field.Optional {
t.Error("members_can_fork_private_repositories should be Optional")
}
if !field.Computed {
t.Error("members_can_fork_private_repositories should be Computed")
}
if field.Default != nil {
t.Errorf("members_can_fork_private_repositories should have no Default, got %v", field.Default)
}
}
2 changes: 1 addition & 1 deletion website/docs/r/organization_settings.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The following arguments are supported:
* `members_can_create_pages` - (Optional) Whether or not organization members can create new pages. Defaults to `true`.
* `members_can_create_public_pages` - (Optional) Whether or not organization members can create new public pages. Defaults to `true`.
* `members_can_create_private_pages` - (Optional) Whether or not organization members can create new private pages. Defaults to `true`.
* `members_can_fork_private_repositories` - (Optional) Whether or not organization members can fork private repositories. Defaults to `false`.
* `members_can_fork_private_repositories` - (Optional) Whether or not organization members can fork private repositories. When an enterprise policy controls this setting, omit this attribute to avoid API validation errors.
* `web_commit_signoff_required` - (Optional) Whether or not commit signatures are required for commits to the organization. Defaults to `false`.
* `advanced_security_enabled_for_new_repositories` - (Optional) Whether or not advanced security is enabled for new repositories. Defaults to `false`.
* `dependabot_alerts_enabled_for_new_repositories` - (Optional) Whether or not dependabot alerts are enabled for new repositories. Defaults to `false`.
Expand Down