Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
428 changes: 288 additions & 140 deletions docs/resources/organization_ruleset.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {
to = github_organization_ruleset.example
id = "12345"
}
1 change: 1 addition & 0 deletions examples/resources/github_organization_ruleset/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import github_organization_ruleset.example 12345
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,3 @@ resource "github_organization_ruleset" "example" {
}
}
}

# Example with push ruleset
# Note: Push targets must NOT have ref_name in conditions, only repository_name or repository_id
resource "github_organization_ruleset" "example_push" {
name = "example_push"
target = "push"
enforcement = "active"

conditions {
repository_name {
include = ["~ALL"]
exclude = []
}
}

rules {
# Push targets only support these rules:
# file_path_restriction, max_file_size, max_file_path_length, file_extension_restriction
file_path_restriction {
restricted_file_paths = [".github/workflows/*", "*.env"]
}

max_file_size {
max_file_size = 100 # 100 MB
}

max_file_path_length {
max_file_path_length = 255
}

file_extension_restriction {
restricted_file_extensions = ["*.exe", "*.dll", "*.so"]
}
}
}
34 changes: 34 additions & 0 deletions examples/resources/github_organization_ruleset/resource_2.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Example with push ruleset
# Note: Push targets must NOT have ref_name in conditions, only repository_name or repository_id
resource "github_organization_ruleset" "example_push" {
name = "example_push"
target = "push"
enforcement = "active"

conditions {
repository_name {
include = ["~ALL"]
exclude = []
}
}

rules {
# Push targets only support these rules:
# file_path_restriction, max_file_size, max_file_path_length, file_extension_restriction
file_path_restriction {
restricted_file_paths = [".github/workflows/*", "*.env"]
}

max_file_size {
max_file_size = 100 # 100 MB
}

max_file_path_length {
max_file_path_length = 255
}

file_extension_restriction {
restricted_file_extensions = ["*.exe", "*.dll", "*.so"]
}
}
}
32 changes: 32 additions & 0 deletions examples/resources/github_organization_ruleset/resource_3.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Example with repository ruleset
# Note: Repository targets must NOT have ref_name in conditions, only repository_name or repository_id
resource "github_organization_ruleset" "example_repository" {
name = "example_repository"
target = "repository"
enforcement = "active"

conditions {
repository_name {
include = ["~ALL"]
exclude = []
}
}

rules {
# Repository targets only support these rules:
# repository_create, repository_delete, repository_name, repository_transfer, repository_visibility
repository_create = true
repository_delete = true
repository_transfer = true

repository_name {
pattern = "^team-"
negate = false
}

repository_visibility {
internal = true
private = true
}
}
}
79 changes: 70 additions & 9 deletions github/resource_github_organization_ruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

var supportedOrgRulesetTargetTypes = []string{string(github.RulesetTargetBranch), string(github.RulesetTargetTag), string(github.RulesetTargetPush)}
var supportedOrgRulesetTargetTypes = []string{
string(github.RulesetTargetBranch),
string(github.RulesetTargetTag),
string(github.RulesetTargetPush),
string(github.RulesetTargetRepository),
}

func resourceGithubOrganizationRuleset() *schema.Resource {
return &schema.Resource{
Description: "Creates a GitHub organization ruleset.",
CreateContext: resourceGithubOrganizationRulesetCreate,
ReadContext: resourceGithubOrganizationRulesetRead,
UpdateContext: resourceGithubOrganizationRulesetUpdate,
Expand All @@ -40,9 +46,8 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
Description: "The name of the ruleset.",
},
"target": {
Type: schema.TypeString,
Required: true,
// The API accepts an `repository` target, but we don't support it yet.
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice(supportedOrgRulesetTargetTypes, false)),
Description: "The target of the ruleset. Possible values are " + strings.Join(supportedOrgRulesetTargetTypes[:len(supportedOrgRulesetTargetTypes)-1], ", ") + " and " + supportedOrgRulesetTargetTypes[len(supportedOrgRulesetTargetTypes)-1] + ".",
},
Expand Down Expand Up @@ -94,7 +99,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Parameters for an organization ruleset condition.The branch and tag rulesets conditions object should contain both repository_name and ref_name properties, or both repository_id and ref_name properties, or both repository_property and ref_name properties. The push rulesets conditions object does not require the ref_name property.",
Description: "Parameters for an organization ruleset condition. Exactly one of `repository_name`, `repository_id` or `repository_property` must be set. For `branch` and `tag` targets, `ref_name` is required alongside it. For `push` and `repository` targets, `ref_name` must not be set.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ref_name": {
Expand Down Expand Up @@ -678,7 +683,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Prevent commits that include changes in specified file paths from being pushed to the commit graph.",
Description: "Prevent commits that include changes in specified file paths from being pushed to the commit graph. Only valid for the `push` target.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"restricted_file_paths": {
Expand All @@ -697,7 +702,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Prevent pushes based on file size.",
Description: "Prevent pushes based on file size. Only valid for the `push` target.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_file_size": {
Expand All @@ -713,7 +718,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Prevent pushes based on file path length.",
Description: "Prevent pushes based on file path length. Only valid for the `push` target.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_file_path_length": {
Expand All @@ -729,7 +734,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Prevent pushes based on file extensions.",
Description: "Prevent pushes based on file extensions. Only valid for the `push` target.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"restricted_file_extensions": {
Expand All @@ -744,6 +749,62 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
},
},
},
"repository_create": {
Type: schema.TypeBool,
Optional: true,
Description: "Only allow users with bypass permission to create matching repositories. Only valid for the `repository` target.",
},
"repository_delete": {
Type: schema.TypeBool,
Optional: true,
Description: "Only allow users with bypass permission to delete matching repositories. Only valid for the `repository` target.",
},
"repository_transfer": {
Type: schema.TypeBool,
Optional: true,
Description: "Only allow users with bypass permission to transfer matching repositories out of the organization. Only valid for the `repository` target.",
},
"repository_name": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Restrict the names matching repositories may have. Only valid for the `repository` target.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"pattern": {
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty),
Description: "The pattern to match against the repository name.",
},
"negate": {
Type: schema.TypeBool,
Optional: true,
Description: "If true, the rule will fail if the pattern matches.",
},
},
},
},
"repository_visibility": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Restrict the visibilities matching repositories may have. Only valid for the `repository` target.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"internal": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow matching repositories to be internal.",
},
"private": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow matching repositories to be private.",
},
},
},
},
},
},
},
Expand Down
Loading
Loading