Skip to content

Commit c5133e4

Browse files
committed
fix: Correct private forking implementation
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
1 parent d5f775e commit c5133e4

File tree

2 files changed

+78
-42
lines changed

2 files changed

+78
-42
lines changed

github/resource_github_repository.go

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func resourceGithubRepository() *schema.Resource {
249249
"allow_forking": {
250250
Type: schema.TypeBool,
251251
Optional: true,
252-
Default: false,
252+
Computed: true,
253253
Description: "Set to 'true' to allow private forking on the repository; this is only relevant if the repository is owned by an organization and is private or internal.",
254254
},
255255
"squash_merge_commit_title": {
@@ -580,11 +580,13 @@ func calculateSecurityAndAnalysis(d *schema.ResourceData) *github.SecurityAndAna
580580
}
581581

582582
func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository {
583+
visibility := calculateVisibility(d)
584+
583585
repository := &github.Repository{
584586
Name: github.Ptr(d.Get("name").(string)),
585587
Description: github.Ptr(d.Get("description").(string)),
586588
Homepage: github.Ptr(d.Get("homepage_url").(string)),
587-
Visibility: github.Ptr(calculateVisibility(d)),
589+
Visibility: github.Ptr(visibility),
588590
HasDownloads: github.Ptr(d.Get("has_downloads").(bool)),
589591
HasIssues: github.Ptr(d.Get("has_issues").(bool)),
590592
HasDiscussions: github.Ptr(d.Get("has_discussions").(bool)),
@@ -595,7 +597,6 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository {
595597
AllowSquashMerge: github.Ptr(d.Get("allow_squash_merge").(bool)),
596598
AllowRebaseMerge: github.Ptr(d.Get("allow_rebase_merge").(bool)),
597599
AllowAutoMerge: github.Ptr(d.Get("allow_auto_merge").(bool)),
598-
AllowForking: github.Ptr(d.Get("allow_forking").(bool)),
599600
DeleteBranchOnMerge: github.Ptr(d.Get("delete_branch_on_merge").(bool)),
600601
WebCommitSignoffRequired: github.Ptr(d.Get("web_commit_signoff_required").(bool)),
601602
AutoInit: github.Ptr(d.Get("auto_init").(bool)),
@@ -625,6 +626,12 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository {
625626
}
626627
}
627628

629+
// only configure allow forking if repository is not public
630+
allowForking, ok := d.Get("allow_forking").(bool)
631+
if ok && visibility != "public" {
632+
repository.AllowForking = github.Ptr(allowForking)
633+
}
634+
628635
return repository
629636
}
630637

@@ -637,27 +644,10 @@ func resourceGithubRepositoryCreate(ctx context.Context, d *schema.ResourceData,
637644

638645
repoReq := resourceGithubRepositoryObject(d)
639646
owner := meta.(*Owner).name
640-
641647
repoName := repoReq.GetName()
642648

643-
// determine if repository should be private. assume public to start
644-
isPrivate := false
645-
646-
// prefer visibility to private flag since private flag is deprecated
647-
privateKeyword, ok := d.Get("private").(bool)
648-
if ok {
649-
isPrivate = privateKeyword
650-
}
651-
652-
visibility, ok := d.Get("visibility").(string)
653-
if ok {
654-
if visibility == "private" || visibility == "internal" {
655-
isPrivate = true
656-
}
657-
}
658-
649+
isPrivate := repoReq.GetVisibility() == "private"
659650
repoReq.Private = github.Ptr(isPrivate)
660-
661651
if template, ok := d.GetOk("template"); ok {
662652
templateConfigBlocks := template.([]any)
663653

@@ -928,8 +918,15 @@ func resourceGithubRepositoryUpdate(ctx context.Context, d *schema.ResourceData,
928918
repoReq := resourceGithubRepositoryObject(d)
929919

930920
// handle visibility updates separately from other fields
921+
visibility := repoReq.GetVisibility()
931922
repoReq.Visibility = nil
932923

924+
// This change needs to be made with the correct visibility
925+
allowForking := repoReq.AllowForking
926+
if d.HasChanges("visibility", "private") {
927+
repoReq.AllowForking = nil
928+
}
929+
933930
if !d.HasChange("security_and_analysis") {
934931
repoReq.SecurityAndAnalysis = nil
935932
log.Print("[DEBUG] No security_and_analysis update required. Removing this field from the payload.")
@@ -1015,32 +1012,17 @@ func resourceGithubRepositoryUpdate(ctx context.Context, d *schema.ResourceData,
10151012
}
10161013
}
10171014

1018-
if d.HasChange("visibility") {
1019-
o, n := d.GetChange("visibility")
1020-
repoReq.Visibility = github.Ptr(n.(string))
1021-
log.Printf("[DEBUG] Updating repository visibility from %s to %s", o, n)
1022-
_, resp, err := client.Repositories.Edit(ctx, owner, repoName, repoReq)
1023-
if err != nil {
1024-
if resp.StatusCode != 422 || !strings.Contains(err.Error(), fmt.Sprintf("Visibility is already %s", n.(string))) {
1025-
return diag.FromErr(err)
1026-
}
1027-
}
1028-
} else {
1029-
log.Printf("[DEBUG] No visibility update required. visibility: %s", d.Get("visibility"))
1030-
}
1015+
if d.HasChanges("visibility", "private") {
1016+
repoReq.Visibility = github.Ptr(visibility)
1017+
repoReq.AllowForking = allowForking
10311018

1032-
if d.HasChange("private") {
1033-
o, n := d.GetChange("private")
1034-
repoReq.Private = github.Ptr(n.(bool))
1035-
log.Printf("[DEBUG] Updating repository privacy from %v to %v", o, n)
1036-
_, _, err = client.Repositories.Edit(ctx, owner, repoName, repoReq)
1019+
log.Printf("[DEBUG] Updating repository visibility from %s to %s", repo.GetVisibility(), visibility)
1020+
_, resp, err := client.Repositories.Edit(ctx, owner, repoName, repoReq)
10371021
if err != nil {
1038-
if !strings.Contains(err.Error(), "422 Privacy is already set") {
1022+
if resp.StatusCode != 422 || !strings.Contains(err.Error(), fmt.Sprintf("Visibility is already %s", visibility)) {
10391023
return diag.FromErr(err)
10401024
}
10411025
}
1042-
} else {
1043-
log.Printf("[DEBUG] No privacy update required. private: %v", d.Get("private"))
10441026
}
10451027

10461028
return resourceGithubRepositoryRead(ctx, d, meta)

github/resource_github_repository_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,60 @@ func TestAccGithubRepository(t *testing.T) {
10611061
})
10621062
})
10631063

1064+
t.Run("update_public_to_private_allow_forking", func(t *testing.T) {
1065+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
1066+
config := fmt.Sprintf(`
1067+
resource "github_repository" "test" {
1068+
name = "tf-acc-test-%s"
1069+
visibility = "public"
1070+
}
1071+
`, randomID)
1072+
1073+
configPrivate := fmt.Sprintf(`
1074+
resource "github_repository" "test" {
1075+
name = "tf-acc-test-%s"
1076+
visibility = "private"
1077+
allow_forking = false
1078+
}
1079+
`, randomID)
1080+
1081+
configPrivateForking := fmt.Sprintf(`
1082+
resource "github_repository" "test" {
1083+
name = "tf-acc-test-%s"
1084+
visibility = "private"
1085+
allow_forking = true
1086+
}
1087+
`, randomID)
1088+
1089+
resource.Test(t, resource.TestCase{
1090+
PreCheck: func() { skipUnauthenticated(t) },
1091+
ProviderFactories: providerFactories,
1092+
Steps: []resource.TestStep{
1093+
{
1094+
Config: config,
1095+
Check: resource.ComposeTestCheckFunc(
1096+
resource.TestCheckResourceAttr("github_repository.test", "visibility", "public"),
1097+
resource.TestCheckResourceAttr("github_repository.test", "allow_forking", "true"),
1098+
),
1099+
},
1100+
{
1101+
Config: configPrivate,
1102+
Check: resource.ComposeTestCheckFunc(
1103+
resource.TestCheckResourceAttr("github_repository.test", "visibility", "private"),
1104+
resource.TestCheckResourceAttr("github_repository.test", "allow_forking", "false"),
1105+
),
1106+
},
1107+
{
1108+
Config: configPrivateForking,
1109+
Check: resource.ComposeTestCheckFunc(
1110+
resource.TestCheckResourceAttr("github_repository.test", "visibility", "private"),
1111+
resource.TestCheckResourceAttr("github_repository.test", "allow_forking", "true"),
1112+
),
1113+
},
1114+
},
1115+
})
1116+
})
1117+
10641118
t.Run("updates repos to public visibility", func(t *testing.T) {
10651119
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
10661120
config := fmt.Sprintf(`

0 commit comments

Comments
 (0)