diff --git a/github/data_source_github_organization.go b/github/data_source_github_organization.go index c588515a61..0dc0938620 100644 --- a/github/data_source_github_organization.go +++ b/github/data_source_github_organization.go @@ -141,6 +141,26 @@ func dataSourceGithubOrganization() *schema.Resource { Type: schema.TypeBool, Computed: true, }, + "members_can_delete_repositories": { + Type: schema.TypeBool, + Computed: true, + }, + "members_can_invite_outside_collaborators": { + Type: schema.TypeBool, + Computed: true, + }, + "members_can_delete_issues": { + Type: schema.TypeBool, + Computed: true, + }, + "display_commenter_full_name_setting_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "readers_can_create_discussions": { + Type: schema.TypeBool, + Computed: true, + }, "summary_only": { Type: schema.TypeBool, Optional: true, @@ -265,6 +285,11 @@ func dataSourceGithubOrganizationRead(ctx context.Context, d *schema.ResourceDat _ = d.Set("dependency_graph_enabled_for_new_repositories", organization.GetDependencyGraphEnabledForNewRepos()) _ = d.Set("secret_scanning_enabled_for_new_repositories", organization.GetSecretScanningEnabledForNewRepos()) _ = d.Set("secret_scanning_push_protection_enabled_for_new_repositories", organization.GetSecretScanningPushProtectionEnabledForNewRepos()) + _ = d.Set("members_can_delete_repositories", organization.GetMembersCanDeleteRepositories()) + _ = d.Set("members_can_invite_outside_collaborators", organization.GetMembersCanInviteOutsideCollaborators()) + _ = d.Set("members_can_delete_issues", organization.GetMembersCanDeleteIssues()) + _ = d.Set("display_commenter_full_name_setting_enabled", organization.GetDisplayCommenterFullNameSettingEnabled()) + _ = d.Set("readers_can_create_discussions", organization.GetReadersCanCreateDiscussions()) } d.SetId(strconv.FormatInt(organization.GetID(), 10)) diff --git a/github/data_source_github_organization_test.go b/github/data_source_github_organization_test.go index 5d8da74a42..4048491ab3 100644 --- a/github/data_source_github_organization_test.go +++ b/github/data_source_github_organization_test.go @@ -41,6 +41,11 @@ func TestAccGithubOrganizationDataSource(t *testing.T) { resource.TestCheckResourceAttrSet("data.github_organization.test", "dependency_graph_enabled_for_new_repositories"), resource.TestCheckResourceAttrSet("data.github_organization.test", "secret_scanning_enabled_for_new_repositories"), resource.TestCheckResourceAttrSet("data.github_organization.test", "secret_scanning_push_protection_enabled_for_new_repositories"), + resource.TestCheckResourceAttrSet("data.github_organization.test", "members_can_delete_repositories"), + resource.TestCheckResourceAttrSet("data.github_organization.test", "members_can_invite_outside_collaborators"), + resource.TestCheckResourceAttrSet("data.github_organization.test", "members_can_delete_issues"), + resource.TestCheckResourceAttrSet("data.github_organization.test", "display_commenter_full_name_setting_enabled"), + resource.TestCheckResourceAttrSet("data.github_organization.test", "readers_can_create_discussions"), ) resource.Test(t, resource.TestCase{ @@ -139,6 +144,11 @@ func TestAccGithubOrganizationDataSource(t *testing.T) { resource.TestCheckNoResourceAttr("data.github_organization.test", "dependency_graph_enabled_for_new_repositories"), resource.TestCheckNoResourceAttr("data.github_organization.test", "secret_scanning_enabled_for_new_repositories"), resource.TestCheckNoResourceAttr("data.github_organization.test", "secret_scanning_push_protection_enabled_for_new_repositories"), + resource.TestCheckNoResourceAttr("data.github_organization.test", "members_can_delete_repositories"), + resource.TestCheckNoResourceAttr("data.github_organization.test", "members_can_invite_outside_collaborators"), + resource.TestCheckNoResourceAttr("data.github_organization.test", "members_can_delete_issues"), + resource.TestCheckNoResourceAttr("data.github_organization.test", "display_commenter_full_name_setting_enabled"), + resource.TestCheckNoResourceAttr("data.github_organization.test", "readers_can_create_discussions"), ) resource.Test(t, resource.TestCase{ diff --git a/github/resource_github_organization_settings.go b/github/resource_github_organization_settings.go index 5b8d0b7062..3d719ead04 100644 --- a/github/resource_github_organization_settings.go +++ b/github/resource_github_organization_settings.go @@ -169,6 +169,48 @@ func resourceGithubOrganizationSettings() *schema.Resource { Default: false, Description: "Whether or not secret scanning push protection is enabled for new repositories.", }, + "members_allowed_repository_creation_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specifies which types of repositories non-admin organization members can create. Can be one of: 'all', 'private', or 'none'. This is a legacy field; prefer the per-visibility 'members_can_create_*_repositories' attributes instead.", + }, + "two_factor_requirement_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether or not two-factor authentication is required for all members of the organization. Enabling this requires that every member already has 2FA enabled, otherwise the API returns 422.", + }, + "members_can_delete_repositories": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether or not organization members (with admin permissions on a repository) can delete or transfer repositories.", + }, + "members_can_invite_outside_collaborators": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether or not organization members can invite outside collaborators to repositories.", + }, + "members_can_delete_issues": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether or not organization members (with admin permissions on a repository) can delete issues.", + }, + "display_commenter_full_name_setting_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether or not the full name of commenters is shown in addition to their username on issues, pull requests, and discussions.", + }, + "readers_can_create_discussions": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether or not users with read access to the organization's repositories can create discussions.", + }, }, } } @@ -290,6 +332,29 @@ func buildOrganizationSettings(d *schema.ResourceData, isEnterprise bool) *githu if shouldInclude("secret_scanning_push_protection_enabled_for_new_repositories") { settings.SecretScanningPushProtectionEnabledForNewRepos = new(d.Get("secret_scanning_push_protection_enabled_for_new_repositories").(bool)) } + if shouldInclude("members_allowed_repository_creation_type") { + if v, ok := d.GetOk("members_allowed_repository_creation_type"); ok { + settings.MembersAllowedRepositoryCreationType = new(v.(string)) + } + } + if shouldInclude("two_factor_requirement_enabled") { + settings.TwoFactorRequirementEnabled = new(d.Get("two_factor_requirement_enabled").(bool)) + } + if shouldInclude("members_can_delete_repositories") { + settings.MembersCanDeleteRepositories = new(d.Get("members_can_delete_repositories").(bool)) + } + if shouldInclude("members_can_invite_outside_collaborators") { + settings.MembersCanInviteOutsideCollaborators = new(d.Get("members_can_invite_outside_collaborators").(bool)) + } + if shouldInclude("members_can_delete_issues") { + settings.MembersCanDeleteIssues = new(d.Get("members_can_delete_issues").(bool)) + } + if shouldInclude("display_commenter_full_name_setting_enabled") { + settings.DisplayCommenterFullNameSettingEnabled = new(d.Get("display_commenter_full_name_setting_enabled").(bool)) + } + if shouldInclude("readers_can_create_discussions") { + settings.ReadersCanCreateDiscussions = new(d.Get("readers_can_create_discussions").(bool)) + } // Enterprise-specific field if isEnterprise { @@ -399,6 +464,27 @@ func resourceGithubOrganizationSettingsCreateOrUpdate(d *schema.ResourceData, me if settings.SecretScanningPushProtectionEnabledForNewRepos != nil { log.Printf("[DEBUG] SecretScanningPushProtectionEnabledForNewRepos: %v", *settings.SecretScanningPushProtectionEnabledForNewRepos) } + if settings.MembersAllowedRepositoryCreationType != nil { + log.Printf("[DEBUG] MembersAllowedRepositoryCreationType: %s", *settings.MembersAllowedRepositoryCreationType) + } + if settings.TwoFactorRequirementEnabled != nil { + log.Printf("[DEBUG] TwoFactorRequirementEnabled: %v", *settings.TwoFactorRequirementEnabled) + } + if settings.MembersCanDeleteRepositories != nil { + log.Printf("[DEBUG] MembersCanDeleteRepositories: %v", *settings.MembersCanDeleteRepositories) + } + if settings.MembersCanInviteOutsideCollaborators != nil { + log.Printf("[DEBUG] MembersCanInviteOutsideCollaborators: %v", *settings.MembersCanInviteOutsideCollaborators) + } + if settings.MembersCanDeleteIssues != nil { + log.Printf("[DEBUG] MembersCanDeleteIssues: %v", *settings.MembersCanDeleteIssues) + } + if settings.DisplayCommenterFullNameSettingEnabled != nil { + log.Printf("[DEBUG] DisplayCommenterFullNameSettingEnabled: %v", *settings.DisplayCommenterFullNameSettingEnabled) + } + if settings.ReadersCanCreateDiscussions != nil { + log.Printf("[DEBUG] ReadersCanCreateDiscussions: %v", *settings.ReadersCanCreateDiscussions) + } orgSettings, _, err := client.Organizations.Edit(ctx, org, settings) if err != nil { @@ -513,6 +599,27 @@ func resourceGithubOrganizationSettingsRead(d *schema.ResourceData, meta any) er if err = d.Set("secret_scanning_push_protection_enabled_for_new_repositories", orgSettings.GetSecretScanningPushProtectionEnabledForNewRepos()); err != nil { return err } + if err = d.Set("members_allowed_repository_creation_type", orgSettings.GetMembersAllowedRepositoryCreationType()); err != nil { + return err + } + if err = d.Set("two_factor_requirement_enabled", orgSettings.GetTwoFactorRequirementEnabled()); err != nil { + return err + } + if err = d.Set("members_can_delete_repositories", orgSettings.GetMembersCanDeleteRepositories()); err != nil { + return err + } + if err = d.Set("members_can_invite_outside_collaborators", orgSettings.GetMembersCanInviteOutsideCollaborators()); err != nil { + return err + } + if err = d.Set("members_can_delete_issues", orgSettings.GetMembersCanDeleteIssues()); err != nil { + return err + } + if err = d.Set("display_commenter_full_name_setting_enabled", orgSettings.GetDisplayCommenterFullNameSettingEnabled()); err != nil { + return err + } + if err = d.Set("readers_can_create_discussions", orgSettings.GetReadersCanCreateDiscussions()); err != nil { + return err + } return nil } diff --git a/github/resource_github_organization_settings_test.go b/github/resource_github_organization_settings_test.go index 742f779b3e..7654fbeb36 100644 --- a/github/resource_github_organization_settings_test.go +++ b/github/resource_github_organization_settings_test.go @@ -586,6 +586,42 @@ func TestAccGithubOrganizationSettings(t *testing.T) { }) }) + t.Run("test newly exposed organization settings fields", func(t *testing.T) { + config := ` + resource "github_organization_settings" "test" { + billing_email = "test@example.com" + members_allowed_repository_creation_type = "private" + two_factor_requirement_enabled = false + members_can_delete_repositories = false + members_can_invite_outside_collaborators = false + members_can_delete_issues = false + display_commenter_full_name_setting_enabled = false + readers_can_create_discussions = true + }` + + check := resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("github_organization_settings.test", "billing_email", "test@example.com"), + resource.TestCheckResourceAttr("github_organization_settings.test", "members_allowed_repository_creation_type", "private"), + resource.TestCheckResourceAttr("github_organization_settings.test", "two_factor_requirement_enabled", "false"), + resource.TestCheckResourceAttr("github_organization_settings.test", "members_can_delete_repositories", "false"), + resource.TestCheckResourceAttr("github_organization_settings.test", "members_can_invite_outside_collaborators", "false"), + resource.TestCheckResourceAttr("github_organization_settings.test", "members_can_delete_issues", "false"), + resource.TestCheckResourceAttr("github_organization_settings.test", "display_commenter_full_name_setting_enabled", "false"), + resource.TestCheckResourceAttr("github_organization_settings.test", "readers_can_create_discussions", "true"), + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: check, + }, + }, + }) + }) + t.Run("test enum field variations", func(t *testing.T) { config := ` resource "github_organization_settings" "test" { diff --git a/website/docs/d/organization.html.markdown b/website/docs/d/organization.html.markdown index 55979f8be1..490293f9c4 100644 --- a/website/docs/d/organization.html.markdown +++ b/website/docs/d/organization.html.markdown @@ -57,3 +57,8 @@ data "github_organization" "example" { * `dependency_graph_enabled_for_new_repositories` - Whether dependency graph is automatically enabled for new repositories. * `secret_scanning_enabled_for_new_repositories` - Whether secret scanning is automatically enabled for new repositories. * `secret_scanning_push_protection_enabled_for_new_repositories` - Whether secret scanning push protection is automatically enabled for new repositories. + * `members_can_delete_repositories` - Whether organization members (with admin permissions on a repository) can delete or transfer repositories. + * `members_can_invite_outside_collaborators` - Whether organization members can invite outside collaborators to repositories. + * `members_can_delete_issues` - Whether organization members (with admin permissions on a repository) can delete issues. + * `display_commenter_full_name_setting_enabled` - Whether the full name of commenters is shown in addition to their username on issues, pull requests, and discussions. + * `readers_can_create_discussions` - Whether users with read access to the organization's repositories can create discussions. diff --git a/website/docs/r/organization_settings.html.markdown b/website/docs/r/organization_settings.html.markdown index c8a4db54a6..0d099eee41 100644 --- a/website/docs/r/organization_settings.html.markdown +++ b/website/docs/r/organization_settings.html.markdown @@ -39,6 +39,13 @@ resource "github_organization_settings" "test" { dependency_graph_enabled_for_new_repositories = false secret_scanning_enabled_for_new_repositories = false secret_scanning_push_protection_enabled_for_new_repositories = false + members_allowed_repository_creation_type = "private" + two_factor_requirement_enabled = false + members_can_delete_repositories = false + members_can_invite_outside_collaborators = false + members_can_delete_issues = false + display_commenter_full_name_setting_enabled = false + readers_can_create_discussions = true } ``` @@ -71,7 +78,14 @@ The following arguments are supported: * `dependabot_security_updates_enabled_for_new_repositories` - (Optional) Whether or not dependabot security updates are enabled for new repositories. Defaults to `false`. * `dependency_graph_enabled_for_new_repositories` - (Optional) Whether or not dependency graph is enabled for new repositories. Defaults to `false`. * `secret_scanning_enabled_for_new_repositories` - (Optional) Whether or not secret scanning is enabled for new repositories. Defaults to `false`. -* `secret_scanning_push_protection_enabled_for_new_repositories` - (Optional) Whether or not secret scanning push protection is enabled for new repositories. Defaults to `false`. +* `secret_scanning_push_protection_enabled_for_new_repositories` - (Optional) Whether or not secret scanning push protection is enabled for new repositories. Defaults to `false`. +* `members_allowed_repository_creation_type` - (Optional) Specifies which types of repositories non-admin organization members can create. Can be one of `all`, `private`, or `none`. This is a legacy field; prefer the per-visibility `members_can_create_*_repositories` attributes instead. The current value is read from the API when not set. +* `two_factor_requirement_enabled` - (Optional) Whether or not two-factor authentication is required for all members of the organization. Enabling this requires that every member already has 2FA enabled, otherwise the GitHub API returns 422. The current value is read from the API when not set. +* `members_can_delete_repositories` - (Optional) Whether or not organization members (with admin permissions on a repository) can delete or transfer repositories. The current value is read from the API when not set. +* `members_can_invite_outside_collaborators` - (Optional) Whether or not organization members can invite outside collaborators to repositories. The current value is read from the API when not set. +* `members_can_delete_issues` - (Optional) Whether or not organization members (with admin permissions on a repository) can delete issues. The current value is read from the API when not set. +* `display_commenter_full_name_setting_enabled` - (Optional) Whether or not the full name of commenters is shown in addition to their username on issues, pull requests, and discussions. The current value is read from the API when not set. +* `readers_can_create_discussions` - (Optional) Whether or not users with read access to the organization's repositories can create discussions. The current value is read from the API when not set. ## Attributes Reference