From 73311c7fc84e9328b31ad5a9507ef234ffd4cba8 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Tue, 24 Mar 2026 15:13:41 +0800 Subject: [PATCH 1/2] fix: add nil check for ref_name element in expandConditions When creating an org ruleset without ref_name specified, Terraform passes []any{nil} which passes existing length checks but panics at the type assertion on line 194. Add v[0] != nil guard. Fixes #3299 Signed-off-by: majiayu000 <1835304752@qq.com> --- github/util_rules.go | 2 +- github/util_rules_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/github/util_rules.go b/github/util_rules.go index 36075831f2..5e3821a767 100644 --- a/github/util_rules.go +++ b/github/util_rules.go @@ -190,7 +190,7 @@ func expandConditions(input []any, org bool) *github.RepositoryRulesetConditions inputConditions := input[0].(map[string]any) // ref_name is available for both repo and org rulesets - if v, ok := inputConditions["ref_name"].([]any); ok && v != nil && len(v) != 0 { + if v, ok := inputConditions["ref_name"].([]any); ok && v != nil && len(v) != 0 && v[0] != nil { inputRefName := v[0].(map[string]any) include := make([]string, 0) exclude := make([]string, 0) diff --git a/github/util_rules_test.go b/github/util_rules_test.go index 5a8253cc95..3811736740 100644 --- a/github/util_rules_test.go +++ b/github/util_rules_test.go @@ -1066,6 +1066,25 @@ func TestExpandRepositoryPropertyConditions_NilPropertyValues(t *testing.T) { } } +func TestExpandConditions_NilRefName(t *testing.T) { + // When ref_name contains a nil element (e.g. org ruleset without ref_name specified), + // expandConditions should not panic and should return conditions with nil RefName. + input := []any{ + map[string]any{ + "ref_name": []any{nil}, + }, + } + + result := expandConditions(input, true) + + if result == nil { + t.Fatal("Expected result to not be nil") + } + if result.RefName != nil { + t.Errorf("Expected RefName to be nil, got %+v", result.RefName) + } +} + func TestFlattenRulesetRepositoryPropertyTargetParameters(t *testing.T) { input := []*github.RepositoryRulesetRepositoryPropertyTargetParameters{ { From 820bd512f06df15d13dab5d0664f6b52604c4c4b Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Tue, 24 Mar 2026 17:21:00 +0800 Subject: [PATCH 2/2] fix: convert TestExpandConditions to table-driven test Address review feedback on PR #3300: refactor the single TestExpandConditions_NilRefName test into a table-driven TestExpandConditions with broader coverage. Signed-off-by: majiayu000 <1835304752@qq.com> --- github/util_rules_test.go | 59 ++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/github/util_rules_test.go b/github/util_rules_test.go index 3811736740..caad4e0b44 100644 --- a/github/util_rules_test.go +++ b/github/util_rules_test.go @@ -3,6 +3,7 @@ package github import ( "testing" + "github.com/google/go-cmp/cmp" "github.com/google/go-github/v84/github" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -1066,22 +1067,54 @@ func TestExpandRepositoryPropertyConditions_NilPropertyValues(t *testing.T) { } } -func TestExpandConditions_NilRefName(t *testing.T) { - // When ref_name contains a nil element (e.g. org ruleset without ref_name specified), - // expandConditions should not panic and should return conditions with nil RefName. - input := []any{ - map[string]any{ - "ref_name": []any{nil}, +func TestExpandConditions(t *testing.T) { + t.Parallel() + + for _, d := range []struct { + testName string + input []any + want *github.RepositoryRulesetConditions + }{ + { + testName: "returns_nil_for_empty_input", + input: []any{}, + want: nil, }, - } + { + testName: "returns_nil_for_empty_input_slice", + input: []any{nil}, + want: nil, + }, + { + testName: "returns_empty_conditions_for_empty_input_slice", + input: []any{map[string]any{}}, + want: &github.RepositoryRulesetConditions{}, + }, + { + testName: "returns_empty_conditions_for_empty_ref_name", + input: []any{map[string]any{"ref_name": []any{}}}, + want: &github.RepositoryRulesetConditions{}, + }, + { + testName: "returns_empty_conditions_for_empty_ref_name_arrays", + input: []any{map[string]any{"ref_name": []any{map[string]any{"include": []any{}, "exclude": []any{}}}}}, + want: &github.RepositoryRulesetConditions{RefName: &github.RepositoryRulesetRefConditionParameters{Include: []string{}, Exclude: []string{}}}, + }, + { + testName: "returns_empty_conditions_for_nil_ref_name_arrays", + input: []any{map[string]any{"ref_name": []any{nil}}}, + want: &github.RepositoryRulesetConditions{}, + }, + } { + t.Run(d.testName, func(t *testing.T) { + t.Parallel() - result := expandConditions(input, true) + got := expandConditions(d.input, false) - if result == nil { - t.Fatal("Expected result to not be nil") - } - if result.RefName != nil { - t.Errorf("Expected RefName to be nil, got %+v", result.RefName) + if diff := cmp.Diff(got, d.want); diff != "" { + t.Fatalf("got %+v, want %+v", got, d.want) + } + }) } }