@@ -10,6 +10,8 @@ import (
1010 "strconv"
1111
1212 "github.com/google/go-github/v77/github"
13+ "github.com/hashicorp/terraform-plugin-log/tflog"
14+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
1315 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1416 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1517)
@@ -26,6 +28,11 @@ func resourceGithubRepositoryRuleset() *schema.Resource {
2628
2729 SchemaVersion : 1 ,
2830
31+ CustomizeDiff : customdiff .All (
32+ validateRepositoryRulesetConditions ,
33+ validateRepositoryRulesetRules ,
34+ ),
35+
2936 Schema : map [string ]* schema.Schema {
3037 "name" : {
3138 Type : schema .TypeString ,
@@ -783,3 +790,84 @@ func resourceGithubRepositoryRulesetImport(d *schema.ResourceData, meta any) ([]
783790
784791 return []* schema.ResourceData {d }, nil
785792}
793+
794+ // validateRepositoryRulesetConditions validates conditions based on target type.
795+ // For push targets, ref_name must not be set.
796+ // For branch/tag targets, ref_name can be set in conditions.
797+ func validateRepositoryRulesetConditions (ctx context.Context , d * schema.ResourceDiff , _ any ) error {
798+ target := d .Get ("target" ).(string )
799+ tflog .Debug (ctx , "Validating repository ruleset conditions" , map [string ]any {"target" : target })
800+
801+ conditionsRaw := d .Get ("conditions" ).([]any )
802+ if len (conditionsRaw ) == 0 {
803+ tflog .Debug (ctx , "No conditions block, skipping validation" )
804+ return nil
805+ }
806+
807+ conditions := conditionsRaw [0 ].(map [string ]any )
808+
809+ if target == "push" {
810+ if conditions ["ref_name" ] != nil && len (conditions ["ref_name" ].([]any )) > 0 {
811+ tflog .Debug (ctx , "Invalid ref_name for push target" )
812+ return fmt .Errorf ("ref_name must not be set for push target" )
813+ }
814+ }
815+
816+ tflog .Debug (ctx , "Conditions validation passed" , map [string ]any {"target" : target })
817+ return nil
818+ }
819+
820+ // validateRepositoryRulesetRules validates rules based on target type.
821+ // Push targets can only use push-specific rules (file_path_restriction, max_file_size, etc.).
822+ // Branch/tag targets cannot use push-only rules.
823+ //
824+ // Note: This function reuses branchTagOnlyRules and pushOnlyRules from
825+ // resource_github_organization_ruleset.go since they're in the same package.
826+ func validateRepositoryRulesetRules (ctx context.Context , d * schema.ResourceDiff , _ any ) error {
827+ target := d .Get ("target" ).(string )
828+ tflog .Debug (ctx , "Validating repository ruleset rules" , map [string ]any {"target" : target })
829+
830+ rulesRaw := d .Get ("rules" ).([]any )
831+ if len (rulesRaw ) == 0 {
832+ tflog .Debug (ctx , "No rules block, skipping validation" )
833+ return nil
834+ }
835+
836+ rules := rulesRaw [0 ].(map [string ]any )
837+
838+ switch target {
839+ case "push" :
840+ for _ , ruleName := range branchTagOnlyRules {
841+ ruleValue := rules [ruleName ]
842+ if ruleValue == nil {
843+ continue
844+ }
845+ switch v := ruleValue .(type ) {
846+ case bool :
847+ if v {
848+ tflog .Debug (ctx , "Invalid rule for push target" , map [string ]any {"rule" : ruleName , "value" : v })
849+ return fmt .Errorf ("rule %q is not valid for push target; push targets only support: %v" , ruleName , pushOnlyRules )
850+ }
851+ case []any :
852+ if len (v ) > 0 {
853+ tflog .Debug (ctx , "Invalid rule for push target" , map [string ]any {"rule" : ruleName , "value" : v })
854+ return fmt .Errorf ("rule %q is not valid for push target; push targets only support: %v" , ruleName , pushOnlyRules )
855+ }
856+ }
857+ }
858+ case "branch" , "tag" :
859+ for _ , ruleName := range pushOnlyRules {
860+ ruleValue := rules [ruleName ]
861+ if ruleValue == nil {
862+ continue
863+ }
864+ if ruleList , ok := ruleValue .([]any ); ok && len (ruleList ) > 0 {
865+ tflog .Debug (ctx , "Invalid rule for branch/tag target" , map [string ]any {"rule" : ruleName , "target" : target })
866+ return fmt .Errorf ("rule %q is only valid for push target, not for %s target" , ruleName , target )
867+ }
868+ }
869+ }
870+
871+ tflog .Debug (ctx , "Rules validation passed" , map [string ]any {"target" : target })
872+ return nil
873+ }
0 commit comments