Skip to content

Commit 3bee2ba

Browse files
johncblandiiclaude
andauthored
Add repository fork, GitHub Pages, and push ruleset support (#16)
* Add repository fork, GitHub Pages, and push ruleset support - Add fork configuration to enable creating forked repositories - Add GitHub Pages configuration with build type, CNAME, and source options - Enable required_code_scanning ruleset rules (drift issue resolved) - Add push ruleset target with file restrictions and size limits - Add new ruleset rule types: required_linear_history, required_signatures, update - Expand bypass modes and actor types for rulesets - Add comprehensive validations for all new ruleset features - Update GitHub provider version to 6.9.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <[email protected]> * Remove unsupported security_and_analysis options Remove secret_scanning_ai_detection and secret_scanning_non_provider_patterns as these block types are not supported by the current GitHub Terraform provider. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * Update examples/complete with all new features - Add fork variable for repository forking support - Add pages variable for GitHub Pages configuration - Update security_and_analysis with code_security option - Update rulesets variable with all new options: - Push ruleset target with file restrictions - required_linear_history, required_signatures, update rules - required_code_scanning support - New bypass modes (exempt) and actor types (DeployKey) - Add comprehensive tfvars examples: - GitHub Pages configuration - Tag protection ruleset - Push restrictions ruleset with file/size limits - Code scanning requirements 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * Update examples/complete provider version to >= 6.9.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * Require provider >= 6.9.0 and restore all security features - Update provider version requirement from >= 6.6.0 to >= 6.9.0 - Re-add code_security to security_and_analysis block - Re-add secret_scanning_ai_detection to security_and_analysis block - Re-add secret_scanning_non_provider_patterns to security_and_analysis block - Update examples/complete with all security options - Update README documentation The fork, code_security, secret_scanning_ai_detection, and secret_scanning_non_provider_patterns features require provider version 6.9.0 or later. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * Fix push ruleset conditions - ref_name not supported for push target Push rulesets in GitHub do not support ref_name conditions like branch and tag rulesets do. This change makes the conditions block optional and adds validations to ensure proper usage per ruleset target type. * Fix file_extension_restriction format - extensions must start with *. GitHub API requires file extensions to use the *. prefix format (e.g., *.exe) instead of just the extension (e.g., .exe). * Comment out push ruleset example - only supported on private repos Push rulesets are not supported on public repositories. Since CI tests use public repos, the push_restrictions example is now commented out with documentation. Updated test assertions to expect 2 rulesets (branch + tag) instead of 1. * Fix environment count test - GitHub Pages auto-creates environment When GitHub Pages is enabled, GitHub automatically creates a "github-pages" environment. Updated test to expect 4 environments (staging, development, production, github-pages). --------- Co-authored-by: Claude Haiku 4.5 <[email protected]>
1 parent a80d8a0 commit 3bee2ba

9 files changed

Lines changed: 422 additions & 102 deletions

File tree

README.md

Lines changed: 6 additions & 4 deletions
Large diffs are not rendered by default.

examples/complete/fixtures.us-east-2.tfvars

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,21 @@ ignore_vulnerability_alerts_during_read = true
2828
allow_update_branch = true
2929

3030
security_and_analysis = {
31-
advanced_security = false
32-
secret_scanning = true
33-
secret_scanning_push_protection = true
31+
advanced_security = false
32+
code_security = true
33+
secret_scanning = true
34+
secret_scanning_push_protection = true
35+
secret_scanning_ai_detection = true
36+
secret_scanning_non_provider_patterns = true
37+
}
38+
39+
# GitHub Pages configuration
40+
pages = {
41+
build_type = "workflow"
42+
source = {
43+
branch = "main"
44+
path = "/docs"
45+
}
3446
}
3547

3648
archive_on_destroy = false
@@ -112,6 +124,9 @@ environments = {
112124
}
113125
}
114126

127+
# Note: Push rulesets (target = "push") are only supported on private repositories.
128+
# The CI tests use public repositories, so push rulesets cannot be tested there.
129+
# See the commented-out push_restrictions example below for push ruleset configuration.
115130
rulesets = {
116131
default = {
117132
name = "Default protection"
@@ -172,9 +187,13 @@ rulesets = {
172187
name = "Test committer email"
173188
negate = false
174189
}
175-
creation = true
176-
deletion = false
177-
non_fast_forward = true
190+
creation = true
191+
deletion = false
192+
non_fast_forward = true
193+
required_linear_history = true
194+
required_signatures = false
195+
update = true
196+
update_allows_fetch_and_merge = true
178197
pull_request = {
179198
dismiss_stale_reviews_on_push = true
180199
require_code_owner_review = true
@@ -197,6 +216,77 @@ rulesets = {
197216
strict_required_status_checks_policy = true
198217
do_not_enforce_on_create = true
199218
}
219+
required_code_scanning = {
220+
required_code_scanning_tool = [
221+
{
222+
alerts_threshold = "errors"
223+
security_alerts_threshold = "high_or_higher"
224+
tool = "CodeQL"
225+
}
226+
]
227+
}
228+
}
229+
}
230+
tag_protection = {
231+
name = "Tag protection"
232+
enforcement = "active"
233+
target = "tag"
234+
conditions = {
235+
ref_name = {
236+
include = ["~ALL"]
237+
exclude = []
238+
}
239+
}
240+
bypass_actors = [
241+
{
242+
bypass_mode = "always"
243+
actor_type = "OrganizationAdmin"
244+
}
245+
]
246+
rules = {
247+
tag_name_pattern = {
248+
operator = "starts_with"
249+
pattern = "v"
250+
name = "Semantic version tags"
251+
negate = false
252+
}
253+
creation = true
254+
deletion = true
200255
}
201256
}
257+
# Push rulesets are only available for private repositories.
258+
# Uncomment the following for private repos:
259+
# push_restrictions = {
260+
# name = "Push restrictions"
261+
# enforcement = "evaluate"
262+
# target = "push"
263+
# # Note: conditions with ref_name is not supported for push rulesets
264+
# bypass_actors = [
265+
# {
266+
# bypass_mode = "always"
267+
# actor_type = "OrganizationAdmin"
268+
# }
269+
# ]
270+
# rules = {
271+
# file_path_restriction = {
272+
# restricted_file_paths = [
273+
# ".github/workflows/*",
274+
# "terraform/*"
275+
# ]
276+
# }
277+
# max_file_size = {
278+
# max_file_size = 50
279+
# }
280+
# max_file_path_length = {
281+
# max_file_path_length = 256
282+
# }
283+
# file_extension_restriction = {
284+
# restricted_file_extensions = [
285+
# "*.exe",
286+
# "*.dll",
287+
# "*.so"
288+
# ]
289+
# }
290+
# }
291+
# }
202292
}

examples/complete/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module "example" {
88
visibility = var.visibility
99

1010
template = var.template
11+
fork = var.fork
1112

1213
homepage_url = var.homepage_url
1314
topics = var.topics
@@ -50,6 +51,7 @@ module "example" {
5051
default_branch = var.default_branch
5152
enable_vulnerability_alerts = var.enable_vulnerability_alerts
5253
security_and_analysis = var.security_and_analysis
54+
pages = var.pages
5355

5456
custom_properties = var.custom_properties
5557
environments = var.environments

examples/complete/variables.tf

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ variable "template" {
1313
default = null
1414
}
1515

16+
variable "fork" {
17+
description = "Configuration for forking an existing repository"
18+
type = object({
19+
source_owner = string
20+
source_repo = string
21+
})
22+
default = null
23+
}
24+
1625
variable "description" {
1726
description = "Description of the repository"
1827
type = string
@@ -209,9 +218,25 @@ variable "allow_update_branch" {
209218
variable "security_and_analysis" {
210219
description = "Security and analysis settings"
211220
type = object({
212-
advanced_security = bool
213-
secret_scanning = bool
214-
secret_scanning_push_protection = bool
221+
advanced_security = optional(bool, false)
222+
code_security = optional(bool, false)
223+
secret_scanning = optional(bool, false)
224+
secret_scanning_push_protection = optional(bool, false)
225+
secret_scanning_ai_detection = optional(bool, false)
226+
secret_scanning_non_provider_patterns = optional(bool, false)
227+
})
228+
default = null
229+
}
230+
231+
variable "pages" {
232+
description = "GitHub Pages configuration for the repository"
233+
type = object({
234+
source = optional(object({
235+
branch = string
236+
path = optional(string, "/")
237+
}), null)
238+
build_type = optional(string, "workflow")
239+
cname = optional(string, null)
215240
})
216241
default = null
217242
}
@@ -400,49 +425,54 @@ variable "rulesets" {
400425
description = "A map of rulesets to configure for the repository"
401426
type = map(object({
402427
name = string
403-
enforcement = string // disabled, active
404-
target = string // branch, tag
428+
enforcement = string // disabled, active, evaluate
429+
target = string // branch, tag, push
405430
bypass_actors = optional(list(object({
406-
// always, pull_request
431+
// always, pull_request, exempt
407432
bypass_mode = string
408433
actor_id = optional(string, null)
409-
// RepositoryRole, Team, Integration, OrganizationAdmin
434+
// RepositoryRole, Team, Integration, OrganizationAdmin, DeployKey
410435
actor_type = string
411436
})), [])
412-
conditions = object({
437+
// conditions is required for branch and tag rulesets, but not supported for push rulesets
438+
conditions = optional(object({
413439
ref_name = object({
414440
include = optional(list(string), []) // ~DEFAULT_BRANCH to include the default branch or ~ALL
415441
exclude = optional(list(string), []) // ~DEFAULT_BRANCH to exclude the default branch or ~ALL
416442
})
417-
})
443+
}), null)
418444
rules = object({
419445
branch_name_pattern = optional(object({
420-
operator = string // starts_with, ends_with, contains, equals
446+
operator = string // starts_with, ends_with, contains, regex
421447
pattern = string
422448
name = optional(string, null)
423449
negate = optional(bool, false)
424450
}), null),
425451
commit_author_email_pattern = optional(object({
426-
operator = string // starts_with, ends_with, contains, equals
452+
operator = string // starts_with, ends_with, contains, regex
427453
pattern = string
428454
name = optional(string, null)
429455
negate = optional(bool, false)
430456
}), null),
431-
creation = optional(bool, false),
432-
deletion = optional(bool, false),
433-
non_fast_forward = optional(bool, false),
457+
creation = optional(bool, false),
458+
deletion = optional(bool, false),
459+
non_fast_forward = optional(bool, false),
460+
required_linear_history = optional(bool, false),
461+
required_signatures = optional(bool, false),
462+
update = optional(bool, false),
463+
update_allows_fetch_and_merge = optional(bool, false),
434464
required_pull_request_reviews = optional(object({
435465
dismiss_stale_reviews = bool
436466
required_approving_review_count = number
437467
}), null),
438468
commit_message_pattern = optional(object({
439-
operator = string // starts_with, ends_with, contains, equals
469+
operator = string // starts_with, ends_with, contains, regex
440470
pattern = string
441471
name = optional(string, null)
442472
negate = optional(bool, false)
443473
}), null),
444474
committer_email_pattern = optional(object({
445-
operator = string // starts_with, ends_with, contains, equals
475+
operator = string // starts_with, ends_with, contains, regex
446476
pattern = string
447477
name = optional(string, null)
448478
negate = optional(bool, false)
@@ -475,19 +505,31 @@ variable "rulesets" {
475505
do_not_enforce_on_create = optional(bool, false)
476506
}), null),
477507
tag_name_pattern = optional(object({
478-
operator = string // starts_with, ends_with, contains, equals
508+
operator = string // starts_with, ends_with, contains, regex
479509
pattern = string
480510
name = optional(string, null)
481511
negate = optional(bool, false)
482512
}), null),
483-
// Unsupported due to drift. https://github.com/integrations/terraform-provider-github/pull/2701
484-
# required_code_scanning = optional(object({
485-
# required_code_scanning_tool = list(object({
486-
# alerts_threshold = string // none, errors, errors_and_warnings, all
487-
# security_alerts_threshold = string // none, critical, high_or_higher, medium_or_higher, all
488-
# tool = string
489-
# }))
490-
# }), null),
513+
required_code_scanning = optional(object({
514+
required_code_scanning_tool = list(object({
515+
alerts_threshold = string // none, errors, errors_and_warnings, all
516+
security_alerts_threshold = string // none, critical, high_or_higher, medium_or_higher, all
517+
tool = string
518+
}))
519+
}), null),
520+
// Push ruleset rules (only valid when target = "push")
521+
file_path_restriction = optional(object({
522+
restricted_file_paths = list(string)
523+
}), null),
524+
max_file_size = optional(object({
525+
max_file_size = number // 1-100 MB
526+
}), null),
527+
max_file_path_length = optional(object({
528+
max_file_path_length = number
529+
}), null),
530+
file_extension_restriction = optional(object({
531+
restricted_file_extensions = list(string)
532+
}), null),
491533
}),
492534
}))
493535
default = {}

examples/complete/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44
required_providers {
55
github = {
66
source = "integrations/github"
7-
version = ">= 6.6.0"
7+
version = ">= 6.9.0"
88
}
99
}
1010
}

0 commit comments

Comments
 (0)