From fa495b1a057cc3a9aaa4896afef320cf506542a2 Mon Sep 17 00:00:00 2001 From: Konstantin Zamyakin Date: Tue, 24 Mar 2026 14:03:02 +0300 Subject: [PATCH 1/2] fix: allow empty required_workflow blocks in required_workflows rule The GitHub UI and API allow creating a required_workflows rule without specifying any workflows. However, the Terraform schema enforced MinItems: 1 and Required: true on the required_workflow sub-block, making it impossible to represent or import such rulesets. Change required_workflow from Required to Optional and remove the MinItems constraint so that an empty workflow list is accepted. Fixes #3217 --- github/resource_github_organization_ruleset.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/github/resource_github_organization_ruleset.go b/github/resource_github_organization_ruleset.go index cfc67a95c7..14a95acce9 100644 --- a/github/resource_github_organization_ruleset.go +++ b/github/resource_github_organization_ruleset.go @@ -609,8 +609,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource { }, "required_workflow": { Type: schema.TypeSet, - MinItems: 1, - Required: true, + Optional: true, Description: "Actions workflows that are required. Several can be defined.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ From 625fa1f72ffd87959bc9d1c269ff7dd50d7da4ae Mon Sep 17 00:00:00 2001 From: Konstantin Zamyakin Date: Tue, 24 Mar 2026 14:10:12 +0300 Subject: [PATCH 2/2] test: add acceptance test for empty required_workflows Validates that a required_workflows rule with no required_workflow sub-blocks is accepted, matching GitHub UI/API behavior. --- ...source_github_organization_ruleset_test.go | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/github/resource_github_organization_ruleset_test.go b/github/resource_github_organization_ruleset_test.go index 30afe67393..3ff816f6dd 100644 --- a/github/resource_github_organization_ruleset_test.go +++ b/github/resource_github_organization_ruleset_test.go @@ -184,6 +184,53 @@ resource "github_organization_ruleset" "test" { }) }) + t.Run("create_branch_ruleset_with_empty_required_workflows", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + rulesetName := fmt.Sprintf("%s-empty-wf-ruleset-%s", testResourcePrefix, randomID) + + config := fmt.Sprintf(` +resource "github_organization_ruleset" "test" { + name = "%s" + target = "branch" + enforcement = "active" + + conditions { + repository_name { + include = ["~ALL"] + exclude = [] + } + + ref_name { + include = ["~DEFAULT_BRANCH"] + exclude = [] + } + } + + rules { + required_workflows { + do_not_enforce_on_create = false + } + } +} +`, rulesetName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasPaidOrgs(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("github_organization_ruleset.test", "name", rulesetName), + resource.TestCheckResourceAttr("github_organization_ruleset.test", "enforcement", "active"), + resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.required_workflows.0.do_not_enforce_on_create", "false"), + resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.required_workflows.0.required_workflow.#", "0"), + ), + }, + }, + }) + }) + t.Run("create_ruleset_with_repository_property", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) rulesetName := fmt.Sprintf("%s-repo-prop-ruleset-%s", testResourcePrefix, randomID)