@@ -442,7 +442,7 @@ func TestAccGithubRepositoryRulesets(t *testing.T) {
442442 restricted_file_paths = ["test.txt"]
443443 }
444444 max_file_size {
445- max_file_size = 1048576
445+ max_file_size = 10 # Value is in megabytes (MB), valid range is 1-100
446446 }
447447 file_extension_restriction {
448448 restricted_file_extensions = ["*.zip"]
@@ -466,7 +466,7 @@ func TestAccGithubRepositoryRulesets(t *testing.T) {
466466 ),
467467 resource .TestCheckResourceAttr (
468468 "github_repository_ruleset.test_push" , "rules.0.max_file_size.0.max_file_size" ,
469- "1048576 " ,
469+ "10 " ,
470470 ),
471471 resource .TestCheckResourceAttr (
472472 "github_repository_ruleset.test_push" , "rules.0.file_extension_restriction.0.restricted_file_extensions.0" ,
@@ -1187,6 +1187,238 @@ func TestAccGithubRepositoryRulesetArchived(t *testing.T) {
11871187 })
11881188}
11891189
1190+ func TestAccGithubRepositoryRulesetValidation (t * testing.T ) {
1191+ randomID := acctest .RandStringFromCharSet (5 , acctest .CharSetAlphaNum )
1192+
1193+ t .Run ("Validates push target rejects ref_name condition" , func (t * testing.T ) {
1194+ if isPaidPlan != "true" {
1195+ t .Skip ("Skipping because `GITHUB_PAID_FEATURES` is not set to true" )
1196+ }
1197+
1198+ config := fmt .Sprintf (`
1199+ resource "github_repository" "test" {
1200+ name = "tf-acc-test-push-ref-%s"
1201+ auto_init = true
1202+ visibility = "internal"
1203+ vulnerability_alerts = true
1204+ }
1205+
1206+ resource "github_repository_ruleset" "test" {
1207+ name = "test-push-with-ref"
1208+ repository = github_repository.test.id
1209+ target = "push"
1210+ enforcement = "active"
1211+
1212+ conditions {
1213+ ref_name {
1214+ include = ["~ALL"]
1215+ exclude = []
1216+ }
1217+ }
1218+
1219+ rules {
1220+ max_file_size {
1221+ max_file_size = 100
1222+ }
1223+ }
1224+ }
1225+ ` , randomID )
1226+
1227+ testCase := func (t * testing.T , mode string ) {
1228+ resource .Test (t , resource.TestCase {
1229+ PreCheck : func () { skipUnlessMode (t , mode ) },
1230+ Providers : testAccProviders ,
1231+ Steps : []resource.TestStep {
1232+ {
1233+ Config : config ,
1234+ ExpectError : regexp .MustCompile ("ref_name must not be set for push target" ),
1235+ },
1236+ },
1237+ })
1238+ }
1239+
1240+ t .Run ("with an anonymous account" , func (t * testing.T ) {
1241+ t .Skip ("anonymous account not supported for this operation" )
1242+ })
1243+
1244+ t .Run ("with an individual account" , func (t * testing.T ) {
1245+ t .Skip ("individual account not supported for push rulesets" )
1246+ })
1247+
1248+ t .Run ("with an organization account" , func (t * testing.T ) {
1249+ testCase (t , organization )
1250+ })
1251+ })
1252+
1253+ t .Run ("Validates push target rejects branch/tag rules" , func (t * testing.T ) {
1254+ if isPaidPlan != "true" {
1255+ t .Skip ("Skipping because `GITHUB_PAID_FEATURES` is not set to true" )
1256+ }
1257+
1258+ config := fmt .Sprintf (`
1259+ resource "github_repository" "test" {
1260+ name = "tf-acc-test-push-rules-%s"
1261+ auto_init = true
1262+ visibility = "internal"
1263+ vulnerability_alerts = true
1264+ }
1265+
1266+ resource "github_repository_ruleset" "test" {
1267+ name = "test-push-branch-rule"
1268+ repository = github_repository.test.id
1269+ target = "push"
1270+ enforcement = "active"
1271+
1272+ rules {
1273+ # 'creation' is a branch/tag rule, not valid for push target
1274+ creation = true
1275+ }
1276+ }
1277+ ` , randomID )
1278+
1279+ testCase := func (t * testing.T , mode string ) {
1280+ resource .Test (t , resource.TestCase {
1281+ PreCheck : func () { skipUnlessMode (t , mode ) },
1282+ Providers : testAccProviders ,
1283+ Steps : []resource.TestStep {
1284+ {
1285+ Config : config ,
1286+ ExpectError : regexp .MustCompile ("rule .* is not valid for push target" ),
1287+ },
1288+ },
1289+ })
1290+ }
1291+
1292+ t .Run ("with an anonymous account" , func (t * testing.T ) {
1293+ t .Skip ("anonymous account not supported for this operation" )
1294+ })
1295+
1296+ t .Run ("with an individual account" , func (t * testing.T ) {
1297+ t .Skip ("individual account not supported for push rulesets" )
1298+ })
1299+
1300+ t .Run ("with an organization account" , func (t * testing.T ) {
1301+ testCase (t , organization )
1302+ })
1303+ })
1304+
1305+ t .Run ("Validates branch target rejects push-only rules" , func (t * testing.T ) {
1306+ config := fmt .Sprintf (`
1307+ resource "github_repository" "test" {
1308+ name = "tf-acc-test-branch-push-%s"
1309+ auto_init = true
1310+ vulnerability_alerts = true
1311+
1312+ visibility = "private"
1313+ }
1314+
1315+ resource "github_repository_ruleset" "test" {
1316+ name = "test-branch-push-rule"
1317+ repository = github_repository.test.id
1318+ target = "branch"
1319+ enforcement = "active"
1320+
1321+ conditions {
1322+ ref_name {
1323+ include = ["~ALL"]
1324+ exclude = []
1325+ }
1326+ }
1327+
1328+ rules {
1329+ # 'max_file_size' is a push-only rule, not valid for branch target
1330+ max_file_size {
1331+ max_file_size = 100
1332+ }
1333+ }
1334+ }
1335+ ` , randomID )
1336+
1337+ testCase := func (t * testing.T , mode string ) {
1338+ resource .Test (t , resource.TestCase {
1339+ PreCheck : func () { skipUnlessMode (t , mode ) },
1340+ Providers : testAccProviders ,
1341+ Steps : []resource.TestStep {
1342+ {
1343+ Config : config ,
1344+ ExpectError : regexp .MustCompile ("rule .* is only valid for push target" ),
1345+ },
1346+ },
1347+ })
1348+ }
1349+
1350+ t .Run ("with an anonymous account" , func (t * testing.T ) {
1351+ t .Skip ("anonymous account not supported for this operation" )
1352+ })
1353+
1354+ t .Run ("with an individual account" , func (t * testing.T ) {
1355+ testCase (t , individual )
1356+ })
1357+
1358+ t .Run ("with an organization account" , func (t * testing.T ) {
1359+ testCase (t , organization )
1360+ })
1361+ })
1362+
1363+ t .Run ("Validates tag target rejects push-only rules" , func (t * testing.T ) {
1364+ config := fmt .Sprintf (`
1365+ resource "github_repository" "test" {
1366+ name = "tf-acc-test-tag-push-%s"
1367+ auto_init = true
1368+ vulnerability_alerts = true
1369+
1370+ visibility = "private"
1371+ }
1372+
1373+ resource "github_repository_ruleset" "test" {
1374+ name = "test-tag-push-rule"
1375+ repository = github_repository.test.id
1376+ target = "tag"
1377+ enforcement = "active"
1378+
1379+ conditions {
1380+ ref_name {
1381+ include = ["~ALL"]
1382+ exclude = []
1383+ }
1384+ }
1385+
1386+ rules {
1387+ # 'file_path_restriction' is a push-only rule, not valid for tag target
1388+ file_path_restriction {
1389+ restricted_file_paths = ["secrets/"]
1390+ }
1391+ }
1392+ }
1393+ ` , randomID )
1394+
1395+ testCase := func (t * testing.T , mode string ) {
1396+ resource .Test (t , resource.TestCase {
1397+ PreCheck : func () { skipUnlessMode (t , mode ) },
1398+ Providers : testAccProviders ,
1399+ Steps : []resource.TestStep {
1400+ {
1401+ Config : config ,
1402+ ExpectError : regexp .MustCompile ("rule .* is only valid for push target" ),
1403+ },
1404+ },
1405+ })
1406+ }
1407+
1408+ t .Run ("with an anonymous account" , func (t * testing.T ) {
1409+ t .Skip ("anonymous account not supported for this operation" )
1410+ })
1411+
1412+ t .Run ("with an individual account" , func (t * testing.T ) {
1413+ testCase (t , individual )
1414+ })
1415+
1416+ t .Run ("with an organization account" , func (t * testing.T ) {
1417+ testCase (t , organization )
1418+ })
1419+ })
1420+ }
1421+
11901422func importRepositoryRulesetByResourcePaths (repoLogicalName , rulesetLogicalName string ) resource.ImportStateIdFunc {
11911423 // test importing using an ID of the form <repo-node-id>:<ruleset-id>
11921424 return func (s * terraform.State ) (string , error ) {
0 commit comments