diff --git a/docs/data-sources/organization.md b/docs/data-sources/organization.md index def786ba5d..fc40cfcb98 100644 --- a/docs/data-sources/organization.md +++ b/docs/data-sources/organization.md @@ -56,3 +56,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/docs/resources/organization_settings.md b/docs/resources/organization_settings.md index 6275f737c9..ee311e520e 100644 --- a/docs/resources/organization_settings.md +++ b/docs/resources/organization_settings.md @@ -38,6 +38,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,6 +78,13 @@ The following arguments are supported: - `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`. +- `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 diff --git a/examples/resources/organization_settings/example_1.tf b/examples/resources/organization_settings/example_1.tf index 1dab26f0ab..2a2b7708c0 100644 --- a/examples/resources/organization_settings/example_1.tf +++ b/examples/resources/organization_settings/example_1.tf @@ -25,4 +25,11 @@ 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 } diff --git a/github/data_source_github_organization.go b/github/data_source_github_organization.go index b5222b0868..b77bd8691d 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 ac2a832de4..579c156b65 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/templates/data-sources/organization.md.tmpl b/templates/data-sources/organization.md.tmpl index bc36284217..29a5e931a0 100644 --- a/templates/data-sources/organization.md.tmpl +++ b/templates/data-sources/organization.md.tmpl @@ -52,3 +52,8 @@ Use this data source to retrieve basic information about a GitHub Organization. - `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/templates/resources/organization_settings.md.tmpl b/templates/resources/organization_settings.md.tmpl index bdd5318c1a..5e3054efee 100644 --- a/templates/resources/organization_settings.md.tmpl +++ b/templates/resources/organization_settings.md.tmpl @@ -42,6 +42,13 @@ The following arguments are supported: - `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`. +- `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