Skip to content

Commit 2fb4213

Browse files
committed
feat: Add file path protection to rulesets and tests
1 parent 8cda414 commit 2fb4213

File tree

5 files changed

+91
-2
lines changed

5 files changed

+91
-2
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ export GITHUB_OWNER=
149149
# enable testing of enterprise appliances
150150
export GITHUB_BASE_URL=
151151

152+
# enable testing of GitHub Paid features, these normally also require an organization e.g. repository push rulesets
153+
export GITHUB_PAID_FEATURES=true
154+
152155
# leverage helper accounts for tests requiring them
153156
# examples include:
154157
# - https://github.com/github-terraform-test-user

github/provider_utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
var testCollaborator = os.Getenv("GITHUB_TEST_COLLABORATOR")
1111
var isEnterprise = os.Getenv("ENTERPRISE_ACCOUNT")
12+
var isPaidPlan = os.Getenv("GITHUB_PAID_FEATURES")
1213
var testEnterprise = os.Getenv("ENTERPRISE_SLUG")
1314
var testOrganization = testOrganizationFunc()
1415
var testOwner = os.Getenv("GITHUB_OWNER")

github/resource_github_repository_ruleset.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func resourceGithubRepositoryRuleset() *schema.Resource {
3434
"target": {
3535
Type: schema.TypeString,
3636
Required: true,
37-
ValidateFunc: validation.StringInSlice([]string{"branch", "tag"}, false),
38-
Description: "Possible values are `branch` and `tag`.",
37+
ValidateFunc: validation.StringInSlice([]string{"branch", "push", "tag"}, false),
38+
Description: "Possible values are `branch`, `push` and `tag`.",
3939
},
4040
"repository": {
4141
Type: schema.TypeString,

github/resource_github_repository_ruleset_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,67 @@ func TestGithubRepositoryRulesets(t *testing.T) {
363363
})
364364

365365
})
366+
t.Run("Creates repository rulesets with paid features without errors", func(t *testing.T) {
367+
if isPaidPlan != "true" {
368+
t.Skip("Skipping because `GITHUB_PAID_FEATURES` is not set to true")
369+
}
370+
config := fmt.Sprintf(`
371+
resource "github_repository" "test" {
372+
name = "tf-acc-test-%s"
373+
auto_init = false
374+
visibility = "internal"
375+
vulnerability_alerts = true
376+
}
377+
378+
resource "github_repository_ruleset" "test_push" {
379+
name = "test-push"
380+
repository = github_repository.test.id
381+
target = "push"
382+
enforcement = "active"
383+
384+
rules {
385+
file_path_restriction {
386+
restricted_file_paths = ["test.txt"]
387+
}
388+
}
389+
}
390+
`, randomID)
391+
check := resource.ComposeTestCheckFunc(
392+
resource.TestCheckResourceAttr(
393+
"github_repository_ruleset.test_push", "name",
394+
"test-push",
395+
),
396+
resource.TestCheckResourceAttr(
397+
"github_repository_ruleset.test_push", "target",
398+
"push",
399+
),
400+
resource.TestCheckResourceAttr(
401+
"github_repository_ruleset.test_push", "rules.0.file_path_restriction.0.restricted_file_paths.0",
402+
"test.txt",
403+
),
404+
)
405+
testCase := func(t *testing.T, mode string) {
406+
resource.Test(t, resource.TestCase{
407+
PreCheck: func() { skipUnlessMode(t, mode) },
408+
Providers: testAccProviders,
409+
Steps: []resource.TestStep{
410+
{
411+
Config: config,
412+
Check: check,
413+
},
414+
},
415+
})
416+
}
417+
t.Run("with an anonymous account", func(t *testing.T) {
418+
t.Skip("anonymous account not supported for this operation")
419+
})
420+
t.Run("with an individual account", func(t *testing.T) {
421+
t.Skip("individual account not supported for this operation")
422+
})
423+
t.Run("with a paid plan in an organization", func(t *testing.T) {
424+
testCase(t, organization)
425+
})
426+
})
366427

367428
}
368429

github/respository_rules_utils.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,19 @@ func expandRules(input []interface{}, org bool) []*github.RepositoryRule {
362362
rulesSlice = append(rulesSlice, github.NewRequiredWorkflowsRule(params))
363363
}
364364

365+
// file_path_restriction rule
366+
if v, ok := rulesMap["file_path_restriction"].([]interface{}); ok && len(v) != 0 {
367+
filePathRestrictionMap := v[0].(map[string]interface{})
368+
restrictedFilePaths := make([]string, 0)
369+
for _, path := range filePathRestrictionMap["restricted_file_paths"].([]interface{}) {
370+
restrictedFilePaths = append(restrictedFilePaths, path.(string))
371+
}
372+
params := &github.RuleFileParameters{
373+
RestrictedFilePaths: &restrictedFilePaths,
374+
}
375+
rulesSlice = append(rulesSlice, github.NewFilePathRestrictionRule(params))
376+
}
377+
365378
return rulesSlice
366379
}
367380

@@ -472,6 +485,17 @@ func flattenRules(rules []*github.RepositoryRule, org bool) []interface{} {
472485
rule["required_check"] = requiredStatusChecksSlice
473486
rule["strict_required_status_checks_policy"] = params.StrictRequiredStatusChecksPolicy
474487
rulesMap[v.Type] = []map[string]interface{}{rule}
488+
489+
case "file_path_restriction":
490+
var params github.RuleFileParameters
491+
err := json.Unmarshal(*v.Parameters, &params)
492+
if err != nil {
493+
log.Printf("[INFO] Unexpected error unmarshalling rule %s with parameters: %v",
494+
v.Type, v.Parameters)
495+
}
496+
rule := make(map[string]interface{})
497+
rule["restricted_file_paths"] = params.GetRestrictedFilePaths()
498+
rulesMap[v.Type] = []map[string]interface{}{rule}
475499
}
476500
}
477501

0 commit comments

Comments
 (0)