From 237d79fb1b39f62ba046457375537c3fc8eb53f4 Mon Sep 17 00:00:00 2001 From: Patrick Marabeas Date: Mon, 31 Aug 2020 13:31:50 +1000 Subject: [PATCH] Comment out legacy branch_protection --- github/resource_github_branch_protection.go | 1275 +++++++++-------- .../resource_github_branch_protection_test.go | 1212 ++++++++-------- 2 files changed, 1244 insertions(+), 1243 deletions(-) diff --git a/github/resource_github_branch_protection.go b/github/resource_github_branch_protection.go index 8f79bf779e..a54fab5bfe 100644 --- a/github/resource_github_branch_protection.go +++ b/github/resource_github_branch_protection.go @@ -1,639 +1,640 @@ package github -import ( - "context" - "errors" - "fmt" - "log" - "net/http" - "strings" - - "github.com/google/go-github/v31/github" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" -) - -func resourceGithubBranchProtection() *schema.Resource { - return &schema.Resource{ - Create: resourceGithubBranchProtectionCreate, - Read: resourceGithubBranchProtectionRead, - Update: resourceGithubBranchProtectionUpdate, - Delete: resourceGithubBranchProtectionDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, - - Schema: map[string]*schema.Schema{ - "repository": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "branch": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "required_status_checks": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "include_admins": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Deprecated: "Use enforce_admins instead", - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - return true - }, - }, - "strict": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "contexts": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - }, - "required_pull_request_reviews": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "include_admins": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Deprecated: "Use enforce_admins instead", - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - return true - }, - }, - "dismiss_stale_reviews": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "dismissal_users": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "dismissal_teams": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "require_code_owner_reviews": { - Type: schema.TypeBool, - Optional: true, - }, - "required_approving_review_count": { - Type: schema.TypeInt, - Optional: true, - Default: 1, - ValidateFunc: validation.IntBetween(1, 6), - }, - }, - }, - }, - "restrictions": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "users": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "teams": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "apps": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - }, - }, - }, - "enforce_admins": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "require_signed_commits": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "etag": { - Type: schema.TypeString, - Computed: true, - }, - }, - } -} - -func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface{}) error { - err := checkOrganization(meta) - if err != nil { - return err - } - - client := meta.(*Owner).v3client - - orgName := meta.(*Owner).name - repoName := d.Get("repository").(string) - branch := d.Get("branch").(string) - - protectionRequest, err := buildProtectionRequest(d) - if err != nil { - return err - } - ctx := context.Background() - - log.Printf("[DEBUG] Creating branch protection: %s/%s (%s)", - orgName, repoName, branch) - protection, _, err := client.Repositories.UpdateBranchProtection(ctx, - orgName, - repoName, - branch, - protectionRequest, - ) - if err != nil { - return err - } - - if err := checkBranchRestrictionsUsers(protection.GetRestrictions(), protectionRequest.GetRestrictions()); err != nil { - return err - } - - d.SetId(buildTwoPartID(repoName, branch)) - - if err = requireSignedCommitsUpdate(d, meta); err != nil { - return err - } - - return resourceGithubBranchProtectionRead(d, meta) -} - -func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}) error { - err := checkOrganization(meta) - if err != nil { - return err - } - - client := meta.(*Owner).v3client - - repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") - if err != nil { - return err - } - orgName := meta.(*Owner).name - - ctx := context.WithValue(context.Background(), ctxId, d.Id()) - if !d.IsNewResource() { - ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) - } - - log.Printf("[DEBUG] Reading branch protection: %s/%s (%s)", - orgName, repoName, branch) - githubProtection, resp, err := client.Repositories.GetBranchProtection(ctx, - orgName, repoName, branch) - if err != nil { - if ghErr, ok := err.(*github.ErrorResponse); ok { - if ghErr.Response.StatusCode == http.StatusNotModified { - if err := requireSignedCommitsRead(d, meta); err != nil { - return fmt.Errorf("Error setting signed commit restriction: %v", err) - } - return nil - } - if ghErr.Response.StatusCode == http.StatusNotFound { - log.Printf("[WARN] Removing branch protection %s/%s (%s) from state because it no longer exists in GitHub", - orgName, repoName, branch) - d.SetId("") - return nil - } - } - - return err - } - - d.Set("etag", resp.Header.Get("ETag")) - d.Set("repository", repoName) - d.Set("branch", branch) - d.Set("enforce_admins", githubProtection.GetEnforceAdmins().Enabled) - - if err := flattenAndSetRequiredStatusChecks(d, githubProtection); err != nil { - return fmt.Errorf("Error setting required_status_checks: %v", err) - } - - if err := flattenAndSetRequiredPullRequestReviews(d, githubProtection); err != nil { - return fmt.Errorf("Error setting required_pull_request_reviews: %v", err) - } - - if err := flattenAndSetRestrictions(d, githubProtection); err != nil { - return fmt.Errorf("Error setting restrictions: %v", err) - } - - if err := requireSignedCommitsRead(d, meta); err != nil { - return fmt.Errorf("Error setting signed commit restriction: %v", err) - } - - return nil -} - -func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface{}) error { - err := checkOrganization(meta) - if err != nil { - return err - } - - client := meta.(*Owner).v3client - repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") - if err != nil { - return err - } - - protectionRequest, err := buildProtectionRequest(d) - if err != nil { - return err - } - - orgName := meta.(*Owner).name - ctx := context.WithValue(context.Background(), ctxId, d.Id()) - - log.Printf("[DEBUG] Updating branch protection: %s/%s (%s)", - orgName, repoName, branch) - protection, _, err := client.Repositories.UpdateBranchProtection(ctx, - orgName, - repoName, - branch, - protectionRequest, - ) - if err != nil { - return err - } - - if err := checkBranchRestrictionsUsers(protection.GetRestrictions(), protectionRequest.GetRestrictions()); err != nil { - return err - } - - if protectionRequest.RequiredPullRequestReviews == nil { - _, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, - orgName, - repoName, - branch, - ) - if err != nil { - return err - } - } - - d.SetId(buildTwoPartID(repoName, branch)) - - if err = requireSignedCommitsUpdate(d, meta); err != nil { - return err - } - - return resourceGithubBranchProtectionRead(d, meta) -} - -func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta interface{}) error { - err := checkOrganization(meta) - if err != nil { - return err - } - - client := meta.(*Owner).v3client - repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") - if err != nil { - return err - } - - orgName := meta.(*Owner).name - ctx := context.WithValue(context.Background(), ctxId, d.Id()) - - log.Printf("[DEBUG] Deleting branch protection: %s/%s (%s)", orgName, repoName, branch) - _, err = client.Repositories.RemoveBranchProtection(ctx, - orgName, repoName, branch) - return err -} - -func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest, error) { - req := &github.ProtectionRequest{ - EnforceAdmins: d.Get("enforce_admins").(bool), - } - - rsc, err := expandRequiredStatusChecks(d) - if err != nil { - return nil, err - } - req.RequiredStatusChecks = rsc - - rprr, err := expandRequiredPullRequestReviews(d) - if err != nil { - return nil, err - } - req.RequiredPullRequestReviews = rprr - - res, err := expandRestrictions(d) - if err != nil { - return nil, err - } - req.Restrictions = res - - return req, nil -} - -func flattenAndSetRequiredStatusChecks(d *schema.ResourceData, protection *github.Protection) error { - rsc := protection.GetRequiredStatusChecks() - if rsc != nil { - contexts := make([]interface{}, 0, len(rsc.Contexts)) - for _, c := range rsc.Contexts { - contexts = append(contexts, c) - } - - return d.Set("required_status_checks", []interface{}{ - map[string]interface{}{ - "strict": rsc.Strict, - "contexts": schema.NewSet(schema.HashString, contexts), - }, - }) - } - - return d.Set("required_status_checks", []interface{}{}) -} - -func requireSignedCommitsRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*Owner).v3client - - repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") - if err != nil { - return err - } - orgName := meta.(*Owner).name - - ctx := context.WithValue(context.Background(), ctxId, d.Id()) - if !d.IsNewResource() { - ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) - } - - log.Printf("[DEBUG] Reading branch protection signed commit status: %s/%s (%s)", orgName, repoName, branch) - signedCommitStatus, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, - orgName, repoName, branch) - if err != nil { - log.Printf("[WARN] Not able to read signature protection: %s/%s (%s)", orgName, repoName, branch) - return nil - } - - return d.Set("require_signed_commits", signedCommitStatus.Enabled) -} - -func requireSignedCommitsUpdate(d *schema.ResourceData, meta interface{}) (err error) { - requiredSignedCommit := d.Get("require_signed_commits").(bool) - client := meta.(*Owner).v3client - - repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") - if err != nil { - return err - } - orgName := meta.(*Owner).name - - ctx := context.WithValue(context.Background(), ctxId, d.Id()) - if !d.IsNewResource() { - ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) - } - - if requiredSignedCommit { - log.Printf("[DEBUG] Enabling branch protection signed commit: %s/%s (%s) - $s", orgName, repoName, branch) - _, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, orgName, repoName, branch) - } else { - log.Printf("[DEBUG] Removing branch protection signed commit: %s/%s (%s) - $s", orgName, repoName, branch) - _, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, orgName, repoName, branch) - } - return err -} - -func flattenAndSetRequiredPullRequestReviews(d *schema.ResourceData, protection *github.Protection) error { - rprr := protection.GetRequiredPullRequestReviews() - if rprr != nil { - var users, teams []interface{} - restrictions := rprr.GetDismissalRestrictions() - - if restrictions != nil { - users = make([]interface{}, 0, len(restrictions.Users)) - for _, u := range restrictions.Users { - if u.Login != nil { - users = append(users, *u.Login) - } - } - teams = make([]interface{}, 0, len(restrictions.Teams)) - for _, t := range restrictions.Teams { - if t.Slug != nil { - teams = append(teams, *t.Slug) - } - } - } - - return d.Set("required_pull_request_reviews", []interface{}{ - map[string]interface{}{ - "dismiss_stale_reviews": rprr.DismissStaleReviews, - "dismissal_users": schema.NewSet(schema.HashString, users), - "dismissal_teams": schema.NewSet(schema.HashString, teams), - "require_code_owner_reviews": rprr.RequireCodeOwnerReviews, - "required_approving_review_count": rprr.RequiredApprovingReviewCount, - }, - }) - } - - return d.Set("required_pull_request_reviews", []interface{}{}) -} - -func flattenAndSetRestrictions(d *schema.ResourceData, protection *github.Protection) error { - restrictions := protection.GetRestrictions() - if restrictions != nil { - users := make([]interface{}, 0, len(restrictions.Users)) - for _, u := range restrictions.Users { - if u.Login != nil { - users = append(users, *u.Login) - } - } - - teams := make([]interface{}, 0, len(restrictions.Teams)) - for _, t := range restrictions.Teams { - if t.Slug != nil { - teams = append(teams, *t.Slug) - } - } - - apps := make([]interface{}, 0, len(restrictions.Apps)) - for _, t := range restrictions.Apps { - if t.Slug != nil { - apps = append(apps, *t.Slug) - } - } - - return d.Set("restrictions", []interface{}{ - map[string]interface{}{ - "users": schema.NewSet(schema.HashString, users), - "teams": schema.NewSet(schema.HashString, teams), - "apps": schema.NewSet(schema.HashString, apps), - }, - }) - } - - return d.Set("restrictions", []interface{}{}) -} - -func expandRequiredStatusChecks(d *schema.ResourceData) (*github.RequiredStatusChecks, error) { - if v, ok := d.GetOk("required_status_checks"); ok { - vL := v.([]interface{}) - if len(vL) > 1 { - return nil, errors.New("cannot specify required_status_checks more than one time") - } - rsc := new(github.RequiredStatusChecks) - - for _, v := range vL { - // List can only have one item, safe to early return here - if v == nil { - return nil, nil - } - m := v.(map[string]interface{}) - rsc.Strict = m["strict"].(bool) - - contexts := expandNestedSet(m, "contexts") - rsc.Contexts = contexts - } - return rsc, nil - } - - return nil, nil -} - -func expandRequiredPullRequestReviews(d *schema.ResourceData) (*github.PullRequestReviewsEnforcementRequest, error) { - if v, ok := d.GetOk("required_pull_request_reviews"); ok { - vL := v.([]interface{}) - if len(vL) > 1 { - return nil, errors.New("cannot specify required_pull_request_reviews more than one time") - } - - rprr := new(github.PullRequestReviewsEnforcementRequest) - drr := new(github.DismissalRestrictionsRequest) - - for _, v := range vL { - // List can only have one item, safe to early return here - if v == nil { - return nil, nil - } - m := v.(map[string]interface{}) - - users := expandNestedSet(m, "dismissal_users") - if len(users) > 0 { - drr.Users = &users - } - teams := expandNestedSet(m, "dismissal_teams") - if len(teams) > 0 { - drr.Teams = &teams - } - - rprr.DismissalRestrictionsRequest = drr - rprr.DismissStaleReviews = m["dismiss_stale_reviews"].(bool) - rprr.RequireCodeOwnerReviews = m["require_code_owner_reviews"].(bool) - rprr.RequiredApprovingReviewCount = m["required_approving_review_count"].(int) - } - - return rprr, nil - } - - return nil, nil -} - -func expandRestrictions(d *schema.ResourceData) (*github.BranchRestrictionsRequest, error) { - if v, ok := d.GetOk("restrictions"); ok { - vL := v.([]interface{}) - if len(vL) > 1 { - return nil, errors.New("cannot specify restrictions more than one time") - } - restrictions := new(github.BranchRestrictionsRequest) - - for _, v := range vL { - // Restrictions only have set attributes nested, need to return nil values for these. - // The API won't initialize these as nil - if v == nil { - restrictions.Users = []string{} - restrictions.Teams = []string{} - restrictions.Apps = []string{} - return restrictions, nil - } - m := v.(map[string]interface{}) - - users := expandNestedSet(m, "users") - restrictions.Users = users - teams := expandNestedSet(m, "teams") - restrictions.Teams = teams - apps := expandNestedSet(m, "apps") - restrictions.Apps = apps - } - return restrictions, nil - } - - return nil, nil -} - -func expandNestedSet(m map[string]interface{}, target string) []string { - res := []string{} - if v, ok := m[target]; ok { - vL := v.(*schema.Set).List() - for _, v := range vL { - res = append(res, v.(string)) - } - } - return res -} - -func checkBranchRestrictionsUsers(actual *github.BranchRestrictions, expected *github.BranchRestrictionsRequest) error { - if expected == nil { - return nil - } - - expectedUsers := expected.Users - - if actual == nil { - return fmt.Errorf("unable to add users in restrictions: %s", strings.Join(expectedUsers, ", ")) - } - - actualLoopUp := make(map[string]struct{}, len(actual.Users)) - for _, a := range actual.Users { - actualLoopUp[a.GetLogin()] = struct{}{} - } - - notFounds := make([]string, 0, len(actual.Users)) - - for _, e := range expectedUsers { - if _, ok := actualLoopUp[e]; !ok { - notFounds = append(notFounds, e) - } - } - - if len(notFounds) == 0 { - return nil - } - - return fmt.Errorf("unable to add users in restrictions: %s", strings.Join(notFounds, ", ")) -} +// +//import ( +// "context" +// "errors" +// "fmt" +// "log" +// "net/http" +// "strings" +// +// "github.com/google/go-github/v31/github" +// "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +// "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +//) +// +//func resourceGithubBranchProtection() *schema.Resource { +// return &schema.Resource{ +// Create: resourceGithubBranchProtectionCreate, +// Read: resourceGithubBranchProtectionRead, +// Update: resourceGithubBranchProtectionUpdate, +// Delete: resourceGithubBranchProtectionDelete, +// Importer: &schema.ResourceImporter{ +// State: schema.ImportStatePassthrough, +// }, +// +// Schema: map[string]*schema.Schema{ +// "repository": { +// Type: schema.TypeString, +// Required: true, +// ForceNew: true, +// }, +// "branch": { +// Type: schema.TypeString, +// Required: true, +// ForceNew: true, +// }, +// "required_status_checks": { +// Type: schema.TypeList, +// Optional: true, +// MaxItems: 1, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "include_admins": { +// Type: schema.TypeBool, +// Optional: true, +// Default: false, +// Deprecated: "Use enforce_admins instead", +// DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { +// return true +// }, +// }, +// "strict": { +// Type: schema.TypeBool, +// Optional: true, +// Default: false, +// }, +// "contexts": { +// Type: schema.TypeSet, +// Optional: true, +// Elem: &schema.Schema{ +// Type: schema.TypeString, +// }, +// }, +// }, +// }, +// }, +// "required_pull_request_reviews": { +// Type: schema.TypeList, +// Optional: true, +// MaxItems: 1, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "include_admins": { +// Type: schema.TypeBool, +// Optional: true, +// Default: false, +// Deprecated: "Use enforce_admins instead", +// DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { +// return true +// }, +// }, +// "dismiss_stale_reviews": { +// Type: schema.TypeBool, +// Optional: true, +// Default: false, +// }, +// "dismissal_users": { +// Type: schema.TypeSet, +// Optional: true, +// Elem: &schema.Schema{Type: schema.TypeString}, +// }, +// "dismissal_teams": { +// Type: schema.TypeSet, +// Optional: true, +// Elem: &schema.Schema{Type: schema.TypeString}, +// }, +// "require_code_owner_reviews": { +// Type: schema.TypeBool, +// Optional: true, +// }, +// "required_approving_review_count": { +// Type: schema.TypeInt, +// Optional: true, +// Default: 1, +// ValidateFunc: validation.IntBetween(1, 6), +// }, +// }, +// }, +// }, +// "restrictions": { +// Type: schema.TypeList, +// Optional: true, +// MaxItems: 1, +// Elem: &schema.Resource{ +// Schema: map[string]*schema.Schema{ +// "users": { +// Type: schema.TypeSet, +// Optional: true, +// Elem: &schema.Schema{Type: schema.TypeString}, +// }, +// "teams": { +// Type: schema.TypeSet, +// Optional: true, +// Elem: &schema.Schema{Type: schema.TypeString}, +// }, +// "apps": { +// Type: schema.TypeSet, +// Optional: true, +// Elem: &schema.Schema{Type: schema.TypeString}, +// }, +// }, +// }, +// }, +// "enforce_admins": { +// Type: schema.TypeBool, +// Optional: true, +// Default: false, +// }, +// "require_signed_commits": { +// Type: schema.TypeBool, +// Optional: true, +// Default: false, +// }, +// "etag": { +// Type: schema.TypeString, +// Computed: true, +// }, +// }, +// } +//} +// +//func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface{}) error { +// err := checkOrganization(meta) +// if err != nil { +// return err +// } +// +// client := meta.(*Owner).v3client +// +// orgName := meta.(*Owner).name +// repoName := d.Get("repository").(string) +// branch := d.Get("branch").(string) +// +// protectionRequest, err := buildProtectionRequest(d) +// if err != nil { +// return err +// } +// ctx := context.Background() +// +// log.Printf("[DEBUG] Creating branch protection: %s/%s (%s)", +// orgName, repoName, branch) +// protection, _, err := client.Repositories.UpdateBranchProtection(ctx, +// orgName, +// repoName, +// branch, +// protectionRequest, +// ) +// if err != nil { +// return err +// } +// +// if err := checkBranchRestrictionsUsers(protection.GetRestrictions(), protectionRequest.GetRestrictions()); err != nil { +// return err +// } +// +// d.SetId(buildTwoPartID(repoName, branch)) +// +// if err = requireSignedCommitsUpdate(d, meta); err != nil { +// return err +// } +// +// return resourceGithubBranchProtectionRead(d, meta) +//} +// +//func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}) error { +// err := checkOrganization(meta) +// if err != nil { +// return err +// } +// +// client := meta.(*Owner).v3client +// +// repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") +// if err != nil { +// return err +// } +// orgName := meta.(*Owner).name +// +// ctx := context.WithValue(context.Background(), ctxId, d.Id()) +// if !d.IsNewResource() { +// ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) +// } +// +// log.Printf("[DEBUG] Reading branch protection: %s/%s (%s)", +// orgName, repoName, branch) +// githubProtection, resp, err := client.Repositories.GetBranchProtection(ctx, +// orgName, repoName, branch) +// if err != nil { +// if ghErr, ok := err.(*github.ErrorResponse); ok { +// if ghErr.Response.StatusCode == http.StatusNotModified { +// if err := requireSignedCommitsRead(d, meta); err != nil { +// return fmt.Errorf("Error setting signed commit restriction: %v", err) +// } +// return nil +// } +// if ghErr.Response.StatusCode == http.StatusNotFound { +// log.Printf("[WARN] Removing branch protection %s/%s (%s) from state because it no longer exists in GitHub", +// orgName, repoName, branch) +// d.SetId("") +// return nil +// } +// } +// +// return err +// } +// +// d.Set("etag", resp.Header.Get("ETag")) +// d.Set("repository", repoName) +// d.Set("branch", branch) +// d.Set("enforce_admins", githubProtection.GetEnforceAdmins().Enabled) +// +// if err := flattenAndSetRequiredStatusChecks(d, githubProtection); err != nil { +// return fmt.Errorf("Error setting required_status_checks: %v", err) +// } +// +// if err := flattenAndSetRequiredPullRequestReviews(d, githubProtection); err != nil { +// return fmt.Errorf("Error setting required_pull_request_reviews: %v", err) +// } +// +// if err := flattenAndSetRestrictions(d, githubProtection); err != nil { +// return fmt.Errorf("Error setting restrictions: %v", err) +// } +// +// if err := requireSignedCommitsRead(d, meta); err != nil { +// return fmt.Errorf("Error setting signed commit restriction: %v", err) +// } +// +// return nil +//} +// +//func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface{}) error { +// err := checkOrganization(meta) +// if err != nil { +// return err +// } +// +// client := meta.(*Owner).v3client +// repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") +// if err != nil { +// return err +// } +// +// protectionRequest, err := buildProtectionRequest(d) +// if err != nil { +// return err +// } +// +// orgName := meta.(*Owner).name +// ctx := context.WithValue(context.Background(), ctxId, d.Id()) +// +// log.Printf("[DEBUG] Updating branch protection: %s/%s (%s)", +// orgName, repoName, branch) +// protection, _, err := client.Repositories.UpdateBranchProtection(ctx, +// orgName, +// repoName, +// branch, +// protectionRequest, +// ) +// if err != nil { +// return err +// } +// +// if err := checkBranchRestrictionsUsers(protection.GetRestrictions(), protectionRequest.GetRestrictions()); err != nil { +// return err +// } +// +// if protectionRequest.RequiredPullRequestReviews == nil { +// _, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, +// orgName, +// repoName, +// branch, +// ) +// if err != nil { +// return err +// } +// } +// +// d.SetId(buildTwoPartID(repoName, branch)) +// +// if err = requireSignedCommitsUpdate(d, meta); err != nil { +// return err +// } +// +// return resourceGithubBranchProtectionRead(d, meta) +//} +// +//func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta interface{}) error { +// err := checkOrganization(meta) +// if err != nil { +// return err +// } +// +// client := meta.(*Owner).v3client +// repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") +// if err != nil { +// return err +// } +// +// orgName := meta.(*Owner).name +// ctx := context.WithValue(context.Background(), ctxId, d.Id()) +// +// log.Printf("[DEBUG] Deleting branch protection: %s/%s (%s)", orgName, repoName, branch) +// _, err = client.Repositories.RemoveBranchProtection(ctx, +// orgName, repoName, branch) +// return err +//} +// +//func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest, error) { +// req := &github.ProtectionRequest{ +// EnforceAdmins: d.Get("enforce_admins").(bool), +// } +// +// rsc, err := expandRequiredStatusChecks(d) +// if err != nil { +// return nil, err +// } +// req.RequiredStatusChecks = rsc +// +// rprr, err := expandRequiredPullRequestReviews(d) +// if err != nil { +// return nil, err +// } +// req.RequiredPullRequestReviews = rprr +// +// res, err := expandRestrictions(d) +// if err != nil { +// return nil, err +// } +// req.Restrictions = res +// +// return req, nil +//} +// +//func flattenAndSetRequiredStatusChecks(d *schema.ResourceData, protection *github.Protection) error { +// rsc := protection.GetRequiredStatusChecks() +// if rsc != nil { +// contexts := make([]interface{}, 0, len(rsc.Contexts)) +// for _, c := range rsc.Contexts { +// contexts = append(contexts, c) +// } +// +// return d.Set("required_status_checks", []interface{}{ +// map[string]interface{}{ +// "strict": rsc.Strict, +// "contexts": schema.NewSet(schema.HashString, contexts), +// }, +// }) +// } +// +// return d.Set("required_status_checks", []interface{}{}) +//} +// +//func requireSignedCommitsRead(d *schema.ResourceData, meta interface{}) error { +// client := meta.(*Owner).v3client +// +// repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") +// if err != nil { +// return err +// } +// orgName := meta.(*Owner).name +// +// ctx := context.WithValue(context.Background(), ctxId, d.Id()) +// if !d.IsNewResource() { +// ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) +// } +// +// log.Printf("[DEBUG] Reading branch protection signed commit status: %s/%s (%s)", orgName, repoName, branch) +// signedCommitStatus, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, +// orgName, repoName, branch) +// if err != nil { +// log.Printf("[WARN] Not able to read signature protection: %s/%s (%s)", orgName, repoName, branch) +// return nil +// } +// +// return d.Set("require_signed_commits", signedCommitStatus.Enabled) +//} +// +//func requireSignedCommitsUpdate(d *schema.ResourceData, meta interface{}) (err error) { +// requiredSignedCommit := d.Get("require_signed_commits").(bool) +// client := meta.(*Owner).v3client +// +// repoName, branch, err := parseTwoPartID(d.Id(), "repository", "branch") +// if err != nil { +// return err +// } +// orgName := meta.(*Owner).name +// +// ctx := context.WithValue(context.Background(), ctxId, d.Id()) +// if !d.IsNewResource() { +// ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) +// } +// +// if requiredSignedCommit { +// log.Printf("[DEBUG] Enabling branch protection signed commit: %s/%s (%s) - $s", orgName, repoName, branch) +// _, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, orgName, repoName, branch) +// } else { +// log.Printf("[DEBUG] Removing branch protection signed commit: %s/%s (%s) - $s", orgName, repoName, branch) +// _, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, orgName, repoName, branch) +// } +// return err +//} +// +//func flattenAndSetRequiredPullRequestReviews(d *schema.ResourceData, protection *github.Protection) error { +// rprr := protection.GetRequiredPullRequestReviews() +// if rprr != nil { +// var users, teams []interface{} +// restrictions := rprr.GetDismissalRestrictions() +// +// if restrictions != nil { +// users = make([]interface{}, 0, len(restrictions.Users)) +// for _, u := range restrictions.Users { +// if u.Login != nil { +// users = append(users, *u.Login) +// } +// } +// teams = make([]interface{}, 0, len(restrictions.Teams)) +// for _, t := range restrictions.Teams { +// if t.Slug != nil { +// teams = append(teams, *t.Slug) +// } +// } +// } +// +// return d.Set("required_pull_request_reviews", []interface{}{ +// map[string]interface{}{ +// "dismiss_stale_reviews": rprr.DismissStaleReviews, +// "dismissal_users": schema.NewSet(schema.HashString, users), +// "dismissal_teams": schema.NewSet(schema.HashString, teams), +// "require_code_owner_reviews": rprr.RequireCodeOwnerReviews, +// "required_approving_review_count": rprr.RequiredApprovingReviewCount, +// }, +// }) +// } +// +// return d.Set("required_pull_request_reviews", []interface{}{}) +//} +// +//func flattenAndSetRestrictions(d *schema.ResourceData, protection *github.Protection) error { +// restrictions := protection.GetRestrictions() +// if restrictions != nil { +// users := make([]interface{}, 0, len(restrictions.Users)) +// for _, u := range restrictions.Users { +// if u.Login != nil { +// users = append(users, *u.Login) +// } +// } +// +// teams := make([]interface{}, 0, len(restrictions.Teams)) +// for _, t := range restrictions.Teams { +// if t.Slug != nil { +// teams = append(teams, *t.Slug) +// } +// } +// +// apps := make([]interface{}, 0, len(restrictions.Apps)) +// for _, t := range restrictions.Apps { +// if t.Slug != nil { +// apps = append(apps, *t.Slug) +// } +// } +// +// return d.Set("restrictions", []interface{}{ +// map[string]interface{}{ +// "users": schema.NewSet(schema.HashString, users), +// "teams": schema.NewSet(schema.HashString, teams), +// "apps": schema.NewSet(schema.HashString, apps), +// }, +// }) +// } +// +// return d.Set("restrictions", []interface{}{}) +//} +// +//func expandRequiredStatusChecks(d *schema.ResourceData) (*github.RequiredStatusChecks, error) { +// if v, ok := d.GetOk("required_status_checks"); ok { +// vL := v.([]interface{}) +// if len(vL) > 1 { +// return nil, errors.New("cannot specify required_status_checks more than one time") +// } +// rsc := new(github.RequiredStatusChecks) +// +// for _, v := range vL { +// // List can only have one item, safe to early return here +// if v == nil { +// return nil, nil +// } +// m := v.(map[string]interface{}) +// rsc.Strict = m["strict"].(bool) +// +// contexts := expandNestedSet(m, "contexts") +// rsc.Contexts = contexts +// } +// return rsc, nil +// } +// +// return nil, nil +//} +// +//func expandRequiredPullRequestReviews(d *schema.ResourceData) (*github.PullRequestReviewsEnforcementRequest, error) { +// if v, ok := d.GetOk("required_pull_request_reviews"); ok { +// vL := v.([]interface{}) +// if len(vL) > 1 { +// return nil, errors.New("cannot specify required_pull_request_reviews more than one time") +// } +// +// rprr := new(github.PullRequestReviewsEnforcementRequest) +// drr := new(github.DismissalRestrictionsRequest) +// +// for _, v := range vL { +// // List can only have one item, safe to early return here +// if v == nil { +// return nil, nil +// } +// m := v.(map[string]interface{}) +// +// users := expandNestedSet(m, "dismissal_users") +// if len(users) > 0 { +// drr.Users = &users +// } +// teams := expandNestedSet(m, "dismissal_teams") +// if len(teams) > 0 { +// drr.Teams = &teams +// } +// +// rprr.DismissalRestrictionsRequest = drr +// rprr.DismissStaleReviews = m["dismiss_stale_reviews"].(bool) +// rprr.RequireCodeOwnerReviews = m["require_code_owner_reviews"].(bool) +// rprr.RequiredApprovingReviewCount = m["required_approving_review_count"].(int) +// } +// +// return rprr, nil +// } +// +// return nil, nil +//} +// +//func expandRestrictions(d *schema.ResourceData) (*github.BranchRestrictionsRequest, error) { +// if v, ok := d.GetOk("restrictions"); ok { +// vL := v.([]interface{}) +// if len(vL) > 1 { +// return nil, errors.New("cannot specify restrictions more than one time") +// } +// restrictions := new(github.BranchRestrictionsRequest) +// +// for _, v := range vL { +// // Restrictions only have set attributes nested, need to return nil values for these. +// // The API won't initialize these as nil +// if v == nil { +// restrictions.Users = []string{} +// restrictions.Teams = []string{} +// restrictions.Apps = []string{} +// return restrictions, nil +// } +// m := v.(map[string]interface{}) +// +// users := expandNestedSet(m, "users") +// restrictions.Users = users +// teams := expandNestedSet(m, "teams") +// restrictions.Teams = teams +// apps := expandNestedSet(m, "apps") +// restrictions.Apps = apps +// } +// return restrictions, nil +// } +// +// return nil, nil +//} +// +//func expandNestedSet(m map[string]interface{}, target string) []string { +// res := []string{} +// if v, ok := m[target]; ok { +// vL := v.(*schema.Set).List() +// for _, v := range vL { +// res = append(res, v.(string)) +// } +// } +// return res +//} +// +//func checkBranchRestrictionsUsers(actual *github.BranchRestrictions, expected *github.BranchRestrictionsRequest) error { +// if expected == nil { +// return nil +// } +// +// expectedUsers := expected.Users +// +// if actual == nil { +// return fmt.Errorf("unable to add users in restrictions: %s", strings.Join(expectedUsers, ", ")) +// } +// +// actualLoopUp := make(map[string]struct{}, len(actual.Users)) +// for _, a := range actual.Users { +// actualLoopUp[a.GetLogin()] = struct{}{} +// } +// +// notFounds := make([]string, 0, len(actual.Users)) +// +// for _, e := range expectedUsers { +// if _, ok := actualLoopUp[e]; !ok { +// notFounds = append(notFounds, e) +// } +// } +// +// if len(notFounds) == 0 { +// return nil +// } +// +// return fmt.Errorf("unable to add users in restrictions: %s", strings.Join(notFounds, ", ")) +//} diff --git a/github/resource_github_branch_protection_test.go b/github/resource_github_branch_protection_test.go index 76c90b00cf..e262390a97 100644 --- a/github/resource_github_branch_protection_test.go +++ b/github/resource_github_branch_protection_test.go @@ -1,607 +1,607 @@ package github - -import ( - "context" - "fmt" - "regexp" - "sort" - "testing" - - "github.com/google/go-github/v31/github" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" - "github.com/kylelemons/godebug/pretty" -) - -func TestAccGithubBranchProtection_basic(t *testing.T) { - if err := testAccCheckOrganization(); err != nil { - t.Skipf("Skipping because %s.", err.Error()) - } - - var protection github.Protection - - rn := "github_branch_protection.master" - rString := acctest.RandString(5) - repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccGithubBranchProtectionDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGithubBranchProtectionConfig(repoName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &protection), - testAccCheckGithubBranchProtectionRequiredStatusChecks(&protection, true, []string{"github/foo"}), - testAccCheckGithubBranchProtectionRestrictions(&protection, []string{testUser}, []string{}), - testAccCheckGithubBranchProtectionPullRequestReviews(&protection, true, []string{testUser}, []string{}, true), - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), - resource.TestCheckResourceAttr(rn, "require_signed_commits", "true"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "true"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "1"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "1"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "0"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "true"), - resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "1"), - resource.TestCheckResourceAttr(rn, "restrictions.0.teams.#", "0"), - ), - }, - { - Config: testAccGithubBranchProtectionUpdateConfig(repoName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &protection), - testAccCheckGithubBranchProtectionRequiredStatusChecks(&protection, false, []string{"github/bar"}), - testAccCheckGithubBranchProtectionNoRestrictionsExist(&protection), - testAccCheckGithubBranchProtectionNoPullRequestReviewsExist(&protection), - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "require_signed_commits", "false"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "false"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "1"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "0"), - resource.TestCheckResourceAttr(rn, "restrictions.#", "0"), - ), - }, - { - ResourceName: rn, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGithubBranchProtection_users(t *testing.T) { - if err := testAccCheckOrganization(); err != nil { - t.Skipf("Skipping because %s.", err.Error()) - } - - rn := "github_branch_protection.master" - rString := acctest.RandString(5) - repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccGithubBranchProtectionDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGithubBranchProtectionConfigUser(repoName, "user_with_underscore"), - ExpectError: regexp.MustCompile("unable to add users in restrictions: user_with_underscore"), - }, - { - Config: testAccGithubBranchProtectionConfigUser(repoName, testUser), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), - resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "1"), - ), - }, - { - ResourceName: rn, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGithubBranchProtection_teams(t *testing.T) { - if err := testAccCheckOrganization(); err != nil { - t.Skipf("Skipping because %s.", err.Error()) - } - - var firstP, secondP, thirdP github.Protection - - rn := "github_branch_protection.master" - rString := acctest.RandString(5) - repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) - firstTeamName := fmt.Sprintf("team 1 %s", rString) - firstTeamSlug := fmt.Sprintf("team-1-%s", rString) - secondTeamName := fmt.Sprintf("team 2 %s", rString) - secondTeamSlug := fmt.Sprintf("team-2-%s", rString) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccGithubBranchProtectionDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGithubBranchProtectionConfigTeams(repoName, firstTeamName, secondTeamName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &firstP), - testAccCheckGithubBranchProtectionRequiredStatusChecks(&firstP, false, []string{}), - testAccCheckGithubBranchProtectionRestrictions(&firstP, []string{}, []string{firstTeamSlug, secondTeamSlug}), - testAccCheckGithubBranchProtectionPullRequestReviews(&firstP, true, []string{}, []string{firstTeamSlug, secondTeamSlug}, false), - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "false"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "0"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "0"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "2"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "false"), - resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "0"), - resource.TestCheckResourceAttr(rn, "restrictions.0.teams.#", "2"), - ), - }, - { - Config: testAccGithubBranchProtectionConfigEmptyItems(repoName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &secondP), - testAccCheckGithubBranchProtectionRequiredStatusChecks(&secondP, false, []string{}), - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), - resource.TestCheckResourceAttr(rn, "require_signed_commits", "false"), - resource.TestCheckResourceAttr(rn, "required_status_checks.#", "1"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "1"), - resource.TestCheckResourceAttr(rn, "restrictions.#", "1"), - ), - }, - { - Config: testAccGithubBranchProtectionConfigTeams(repoName, firstTeamName, secondTeamName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &thirdP), - testAccCheckGithubBranchProtectionRequiredStatusChecks(&thirdP, false, []string{}), - testAccCheckGithubBranchProtectionRestrictions(&thirdP, []string{}, []string{firstTeamSlug, secondTeamSlug}), - testAccCheckGithubBranchProtectionPullRequestReviews(&thirdP, true, []string{}, []string{firstTeamSlug, secondTeamSlug}, false), - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "false"), - resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "0"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "0"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "2"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "false"), - resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "0"), - resource.TestCheckResourceAttr(rn, "restrictions.0.teams.#", "2"), - ), - }, - { - ResourceName: rn, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -// See https://github.com/terraform-providers/terraform-provider-github/issues/8 -func TestAccGithubBranchProtection_emptyItems(t *testing.T) { - if err := testAccCheckOrganization(); err != nil { - t.Skipf("Skipping because %s.", err.Error()) - } - - var protection github.Protection - - rn := "github_branch_protection.master" - rString := acctest.RandString(5) - repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccGithubBranchProtectionDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGithubBranchProtectionConfigEmptyItems(repoName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists("github_branch_protection.master", repoName+":master", &protection), - resource.TestCheckResourceAttr(rn, "repository", repoName), - resource.TestCheckResourceAttr(rn, "branch", "master"), - resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), - resource.TestCheckResourceAttr(rn, "require_signed_commits", "false"), - resource.TestCheckResourceAttr(rn, "required_status_checks.#", "1"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "1"), - resource.TestCheckResourceAttr(rn, "restrictions.#", "1"), - ), - }, - { - ResourceName: rn, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGithubBranchProtection_emptyDismissalRestrictions(t *testing.T) { - if err := testAccCheckOrganization(); err != nil { - t.Skipf("Skipping because %s.", err.Error()) - } - - var protection github.Protection - rn := "github_branch_protection.master" - repoName := acctest.RandomWithPrefix("tf-acc-test-branch-prot-") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccGithubBranchProtectionDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGithubBranchProtectionEmptyDismissalsConfig(repoName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGithubProtectedBranchExists("github_branch_protection.master", repoName+":master", &protection), - testAccCheckGithubBranchProtectionPullRequestReviews(&protection, true, []string{}, []string{}, true), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "1"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "true"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "0"), - resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "0"), - ), - }, - { - ResourceName: rn, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccCheckGithubProtectedBranchExists(n, id string, protection *github.Protection) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not Found: %s", n) - } - - if rs.Primary.ID != id { - return fmt.Errorf("Expected ID to be %v, got %v", id, rs.Primary.ID) - } - - conn := testAccProvider.Meta().(*Owner).v3client - o := testAccProvider.Meta().(*Owner).name - r, b, err := parseTwoPartID(rs.Primary.ID, "repository", "branch") - if err != nil { - return err - } - - githubProtection, _, err := conn.Repositories.GetBranchProtection(context.TODO(), o, r, b) - if err != nil { - return err - } - - *protection = *githubProtection - return nil - } -} - -func testAccCheckGithubBranchProtectionRequiredStatusChecks(protection *github.Protection, expectedStrict bool, expectedContexts []string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rsc := protection.GetRequiredStatusChecks() - if rsc == nil { - return fmt.Errorf("Expected RequiredStatusChecks to be present, but was nil") - } - - if rsc.Strict != expectedStrict { - return fmt.Errorf("Expected RequiredStatusChecks.Strict to be %v, got %v", expectedStrict, rsc.Strict) - } - - if diff := pretty.Compare(rsc.Contexts, expectedContexts); diff != "" { - return fmt.Errorf("diff %q: (-got +want)\n%s", "contexts", diff) - } - - return nil - } -} - -func testAccCheckGithubBranchProtectionRestrictions(protection *github.Protection, expectedUserLogins []string, expectedTeamNames []string) resource.TestCheckFunc { - return func(s *terraform.State) error { - restrictions := protection.GetRestrictions() - if restrictions == nil { - return fmt.Errorf("Expected Restrictions to be present, but was nil") - } - - userLogins := []string{} - for _, u := range restrictions.Users { - userLogins = append(userLogins, u.GetLogin()) - } - if diff := pretty.Compare(userLogins, expectedUserLogins); diff != "" { - return fmt.Errorf("diff %q: (-got +want)\n%s", "restrictions.users", diff) - } - - teamLogins := []string{} - for _, t := range restrictions.Teams { - teamLogins = append(teamLogins, t.GetSlug()) - } - sort.Strings(teamLogins) - sort.Strings(expectedTeamNames) - if diff := pretty.Compare(teamLogins, expectedTeamNames); diff != "" { - return fmt.Errorf("diff %q: (-got +want)\n%s", "restrictions.teams", diff) - } - - return nil - } -} - -func testAccCheckGithubBranchProtectionPullRequestReviews(protection *github.Protection, expectedStale bool, expectedUsers, expectedTeams []string, expectedCodeOwners bool) resource.TestCheckFunc { - return func(s *terraform.State) error { - reviews := protection.GetRequiredPullRequestReviews() - if reviews == nil { - return fmt.Errorf("Expected Pull Request Reviews to be present, but was nil") - } - - if reviews.DismissStaleReviews != expectedStale { - return fmt.Errorf("Expected `dismiss_state_reviews` to be %t, got %t", expectedStale, reviews.DismissStaleReviews) - } - - var users, teams []string - if reviews.DismissalRestrictions != nil { - if len(expectedUsers) == 0 && len(expectedTeams) == 0 { - return fmt.Errorf("Expected Dismissal Restrictions to be nil but was present") - } - for _, u := range reviews.GetDismissalRestrictions().Users { - users = append(users, u.GetLogin()) - } - - for _, t := range reviews.GetDismissalRestrictions().Teams { - teams = append(teams, t.GetSlug()) - } - } - - if diff := pretty.Compare(users, expectedUsers); diff != "" { - return fmt.Errorf("diff %q: (-got +want)\n%s", "required_pull_request_reviews.dismissal_users", diff) - } - - sort.Strings(teams) - sort.Strings(expectedTeams) - if diff := pretty.Compare(teams, expectedTeams); diff != "" { - return fmt.Errorf("diff %q: (-got +want)\n%s", "required_pull_request_reviews.dismissal_teams", diff) - } - - if reviews.RequireCodeOwnerReviews != expectedCodeOwners { - return fmt.Errorf("Expected `require_code_owner_reviews` to be %t, got %t", expectedCodeOwners, reviews.RequireCodeOwnerReviews) - } - - return nil - } -} - -func testAccCheckGithubBranchProtectionNoRestrictionsExist(protection *github.Protection) resource.TestCheckFunc { - return func(s *terraform.State) error { - if restrictions := protection.GetRestrictions(); restrictions != nil { - return fmt.Errorf("Expected Restrictions to be nil, but was %v", restrictions) - } - - return nil - - } -} - -func testAccCheckGithubBranchProtectionNoPullRequestReviewsExist(protection *github.Protection) resource.TestCheckFunc { - return func(s *terraform.State) error { - if requiredPullRequestReviews := protection.GetRequiredPullRequestReviews(); requiredPullRequestReviews != nil { - return fmt.Errorf("Expected Pull Request reviews to be nil, but was %v", requiredPullRequestReviews) - } - - return nil - } -} - -func testAccGithubBranchProtectionDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*Owner).v3client - - for _, rs := range s.RootModule().Resources { - if rs.Type != "github_branch_protection" { - continue - } - - o := testAccProvider.Meta().(*Owner).name - r, b, err := parseTwoPartID(rs.Primary.ID, "repository", "branch") - if err != nil { - return err - } - - protection, res, err := conn.Repositories.GetBranchProtection(context.TODO(), o, r, b) - - if err == nil { - if protection != nil { - return fmt.Errorf("Branch protection still exists") - } - } - if res.StatusCode != 404 { - return err - } - return nil - } - return nil -} - -func testAccGithubBranchProtectionConfig(repoName string) string { - return fmt.Sprintf(` -resource "github_repository" "test" { - name = "%s" - description = "Terraform Acceptance Test %s" - auto_init = true -} - -resource "github_branch_protection" "master" { - repository = "${github_repository.test.name}" - branch = "master" - enforce_admins = true - require_signed_commits = true - - required_status_checks { - strict = true - contexts = ["github/foo"] - } - - required_pull_request_reviews { - dismiss_stale_reviews = true - dismissal_users = ["%s"] - require_code_owner_reviews = true - } - - restrictions { - users = ["%s"] - } -} -`, repoName, repoName, testUser, testUser) -} - -func testAccGithubBranchProtectionUpdateConfig(repoName string) string { - return fmt.Sprintf(` -resource "github_repository" "test" { - name = "%s" - description = "Terraform Acceptance Test %s" - auto_init = true -} - -resource "github_branch_protection" "master" { - repository = "${github_repository.test.name}" - branch = "master" - - required_status_checks { - strict = false - contexts = ["github/bar"] - } -} -`, repoName, repoName) -} - -func testAccGithubBranchProtectionConfigEmptyItems(repoName string) string { - return fmt.Sprintf(` -resource "github_repository" "test" { - name = "%s" - description = "Terraform Acceptance Test %s" - auto_init = true -} - -resource "github_branch_protection" "master" { - repository = "${github_repository.test.name}" - branch = "master" - enforce_admins = true - - required_status_checks { - } - - required_pull_request_reviews { - } - - restrictions { - } -} -`, repoName, repoName) -} - -func testAccGithubBranchProtectionConfigTeams(repoName, firstTeamName, secondTeamName string) string { - return fmt.Sprintf(` -resource "github_repository" "test" { - name = "%s" - description = "Terraform Acceptance Test %s" - auto_init = true -} - -resource "github_team" "first" { - name = "%s" -} - -resource "github_team_repository" "first" { - team_id = "${github_team.first.id}" - repository = "${github_repository.test.name}" - permission = "push" -} - -resource "github_team" "second" { - name = "%s" -} - -resource "github_team_repository" "second" { - team_id = "${github_team.second.id}" - repository = "${github_repository.test.name}" - permission = "push" -} - -resource "github_branch_protection" "master" { - depends_on = ["github_team_repository.first", "github_team_repository.second"] - repository = "${github_repository.test.name}" - branch = "master" - enforce_admins = true - - required_status_checks { - } - - required_pull_request_reviews { - dismiss_stale_reviews = true - dismissal_teams = ["${github_team.first.slug}", "${github_team.second.slug}"] - } - - restrictions { - teams = ["${github_team.first.slug}", "${github_team.second.slug}"] - } -} -`, repoName, repoName, firstTeamName, secondTeamName) -} - -func testAccGithubBranchProtectionConfigUser(repoName, user string) string { - return fmt.Sprintf(` -resource "github_repository" "test" { - name = "%s" - description = "Terraform Acceptance Test %s" - auto_init = true -} - -resource "github_branch_protection" "master" { - repository = "${github_repository.test.name}" - branch = "master" - enforce_admins = true - - restrictions { - users = ["%s"] - } -} -`, repoName, repoName, user) -} - -func testAccGithubBranchProtectionEmptyDismissalsConfig(repoName string) string { - return fmt.Sprintf(` - -resource "github_repository" "test" { - name = "%s" - description = "Terraform Acceptance Test %s" - auto_init = true -} - -resource "github_branch_protection" "master" { - repository = "${github_repository.test.name}" - branch = "master" - enforce_admins = true - - required_pull_request_reviews { - dismiss_stale_reviews = true - require_code_owner_reviews = true - } -} -`, repoName, repoName) -} +// +//import ( +// "context" +// "fmt" +// "regexp" +// "sort" +// "testing" +// +// "github.com/google/go-github/v31/github" +// "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" +// "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +// "github.com/hashicorp/terraform-plugin-sdk/terraform" +// "github.com/kylelemons/godebug/pretty" +//) +// +//func TestAccGithubBranchProtection_basic(t *testing.T) { +// if err := testAccCheckOrganization(); err != nil { +// t.Skipf("Skipping because %s.", err.Error()) +// } +// +// var protection github.Protection +// +// rn := "github_branch_protection.master" +// rString := acctest.RandString(5) +// repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) +// +// resource.ParallelTest(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// Providers: testAccProviders, +// CheckDestroy: testAccGithubBranchProtectionDestroy, +// Steps: []resource.TestStep{ +// { +// Config: testAccGithubBranchProtectionConfig(repoName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &protection), +// testAccCheckGithubBranchProtectionRequiredStatusChecks(&protection, true, []string{"github/foo"}), +// testAccCheckGithubBranchProtectionRestrictions(&protection, []string{testUser}, []string{}), +// testAccCheckGithubBranchProtectionPullRequestReviews(&protection, true, []string{testUser}, []string{}, true), +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), +// resource.TestCheckResourceAttr(rn, "require_signed_commits", "true"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "true"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "1"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "1"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "0"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "true"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "1"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.teams.#", "0"), +// ), +// }, +// { +// Config: testAccGithubBranchProtectionUpdateConfig(repoName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &protection), +// testAccCheckGithubBranchProtectionRequiredStatusChecks(&protection, false, []string{"github/bar"}), +// testAccCheckGithubBranchProtectionNoRestrictionsExist(&protection), +// testAccCheckGithubBranchProtectionNoPullRequestReviewsExist(&protection), +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "require_signed_commits", "false"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "false"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "1"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "0"), +// resource.TestCheckResourceAttr(rn, "restrictions.#", "0"), +// ), +// }, +// { +// ResourceName: rn, +// ImportState: true, +// ImportStateVerify: true, +// }, +// }, +// }) +//} +// +//func TestAccGithubBranchProtection_users(t *testing.T) { +// if err := testAccCheckOrganization(); err != nil { +// t.Skipf("Skipping because %s.", err.Error()) +// } +// +// rn := "github_branch_protection.master" +// rString := acctest.RandString(5) +// repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) +// +// resource.ParallelTest(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// Providers: testAccProviders, +// CheckDestroy: testAccGithubBranchProtectionDestroy, +// Steps: []resource.TestStep{ +// { +// Config: testAccGithubBranchProtectionConfigUser(repoName, "user_with_underscore"), +// ExpectError: regexp.MustCompile("unable to add users in restrictions: user_with_underscore"), +// }, +// { +// Config: testAccGithubBranchProtectionConfigUser(repoName, testUser), +// Check: resource.ComposeTestCheckFunc( +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "1"), +// ), +// }, +// { +// ResourceName: rn, +// ImportState: true, +// ImportStateVerify: true, +// }, +// }, +// }) +//} +// +//func TestAccGithubBranchProtection_teams(t *testing.T) { +// if err := testAccCheckOrganization(); err != nil { +// t.Skipf("Skipping because %s.", err.Error()) +// } +// +// var firstP, secondP, thirdP github.Protection +// +// rn := "github_branch_protection.master" +// rString := acctest.RandString(5) +// repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) +// firstTeamName := fmt.Sprintf("team 1 %s", rString) +// firstTeamSlug := fmt.Sprintf("team-1-%s", rString) +// secondTeamName := fmt.Sprintf("team 2 %s", rString) +// secondTeamSlug := fmt.Sprintf("team-2-%s", rString) +// +// resource.ParallelTest(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// Providers: testAccProviders, +// CheckDestroy: testAccGithubBranchProtectionDestroy, +// Steps: []resource.TestStep{ +// { +// Config: testAccGithubBranchProtectionConfigTeams(repoName, firstTeamName, secondTeamName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &firstP), +// testAccCheckGithubBranchProtectionRequiredStatusChecks(&firstP, false, []string{}), +// testAccCheckGithubBranchProtectionRestrictions(&firstP, []string{}, []string{firstTeamSlug, secondTeamSlug}), +// testAccCheckGithubBranchProtectionPullRequestReviews(&firstP, true, []string{}, []string{firstTeamSlug, secondTeamSlug}, false), +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "false"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "0"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "0"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "2"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "false"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "0"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.teams.#", "2"), +// ), +// }, +// { +// Config: testAccGithubBranchProtectionConfigEmptyItems(repoName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &secondP), +// testAccCheckGithubBranchProtectionRequiredStatusChecks(&secondP, false, []string{}), +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), +// resource.TestCheckResourceAttr(rn, "require_signed_commits", "false"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.#", "1"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "1"), +// resource.TestCheckResourceAttr(rn, "restrictions.#", "1"), +// ), +// }, +// { +// Config: testAccGithubBranchProtectionConfigTeams(repoName, firstTeamName, secondTeamName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists(rn, repoName+":master", &thirdP), +// testAccCheckGithubBranchProtectionRequiredStatusChecks(&thirdP, false, []string{}), +// testAccCheckGithubBranchProtectionRestrictions(&thirdP, []string{}, []string{firstTeamSlug, secondTeamSlug}), +// testAccCheckGithubBranchProtectionPullRequestReviews(&thirdP, true, []string{}, []string{firstTeamSlug, secondTeamSlug}, false), +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.strict", "false"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.0.contexts.#", "0"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "0"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "2"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "false"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.users.#", "0"), +// resource.TestCheckResourceAttr(rn, "restrictions.0.teams.#", "2"), +// ), +// }, +// { +// ResourceName: rn, +// ImportState: true, +// ImportStateVerify: true, +// }, +// }, +// }) +//} +// +//// See https://github.com/terraform-providers/terraform-provider-github/issues/8 +//func TestAccGithubBranchProtection_emptyItems(t *testing.T) { +// if err := testAccCheckOrganization(); err != nil { +// t.Skipf("Skipping because %s.", err.Error()) +// } +// +// var protection github.Protection +// +// rn := "github_branch_protection.master" +// rString := acctest.RandString(5) +// repoName := fmt.Sprintf("tf-acc-test-branch-prot-%s", rString) +// +// resource.ParallelTest(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// Providers: testAccProviders, +// CheckDestroy: testAccGithubBranchProtectionDestroy, +// Steps: []resource.TestStep{ +// { +// Config: testAccGithubBranchProtectionConfigEmptyItems(repoName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists("github_branch_protection.master", repoName+":master", &protection), +// resource.TestCheckResourceAttr(rn, "repository", repoName), +// resource.TestCheckResourceAttr(rn, "branch", "master"), +// resource.TestCheckResourceAttr(rn, "enforce_admins", "true"), +// resource.TestCheckResourceAttr(rn, "require_signed_commits", "false"), +// resource.TestCheckResourceAttr(rn, "required_status_checks.#", "1"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "1"), +// resource.TestCheckResourceAttr(rn, "restrictions.#", "1"), +// ), +// }, +// { +// ResourceName: rn, +// ImportState: true, +// ImportStateVerify: true, +// }, +// }, +// }) +//} +// +//func TestAccGithubBranchProtection_emptyDismissalRestrictions(t *testing.T) { +// if err := testAccCheckOrganization(); err != nil { +// t.Skipf("Skipping because %s.", err.Error()) +// } +// +// var protection github.Protection +// rn := "github_branch_protection.master" +// repoName := acctest.RandomWithPrefix("tf-acc-test-branch-prot-") +// +// resource.ParallelTest(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// Providers: testAccProviders, +// CheckDestroy: testAccGithubBranchProtectionDestroy, +// Steps: []resource.TestStep{ +// { +// Config: testAccGithubBranchProtectionEmptyDismissalsConfig(repoName), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckGithubProtectedBranchExists("github_branch_protection.master", repoName+":master", &protection), +// testAccCheckGithubBranchProtectionPullRequestReviews(&protection, true, []string{}, []string{}, true), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.#", "1"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismiss_stale_reviews", "true"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.require_code_owner_reviews", "true"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_users.#", "0"), +// resource.TestCheckResourceAttr(rn, "required_pull_request_reviews.0.dismissal_teams.#", "0"), +// ), +// }, +// { +// ResourceName: rn, +// ImportState: true, +// ImportStateVerify: true, +// }, +// }, +// }) +//} +// +//func testAccCheckGithubProtectedBranchExists(n, id string, protection *github.Protection) resource.TestCheckFunc { +// return func(s *terraform.State) error { +// rs, ok := s.RootModule().Resources[n] +// if !ok { +// return fmt.Errorf("Not Found: %s", n) +// } +// +// if rs.Primary.ID != id { +// return fmt.Errorf("Expected ID to be %v, got %v", id, rs.Primary.ID) +// } +// +// conn := testAccProvider.Meta().(*Owner).v3client +// o := testAccProvider.Meta().(*Owner).name +// r, b, err := parseTwoPartID(rs.Primary.ID, "repository", "branch") +// if err != nil { +// return err +// } +// +// githubProtection, _, err := conn.Repositories.GetBranchProtection(context.TODO(), o, r, b) +// if err != nil { +// return err +// } +// +// *protection = *githubProtection +// return nil +// } +//} +// +//func testAccCheckGithubBranchProtectionRequiredStatusChecks(protection *github.Protection, expectedStrict bool, expectedContexts []string) resource.TestCheckFunc { +// return func(s *terraform.State) error { +// rsc := protection.GetRequiredStatusChecks() +// if rsc == nil { +// return fmt.Errorf("Expected RequiredStatusChecks to be present, but was nil") +// } +// +// if rsc.Strict != expectedStrict { +// return fmt.Errorf("Expected RequiredStatusChecks.Strict to be %v, got %v", expectedStrict, rsc.Strict) +// } +// +// if diff := pretty.Compare(rsc.Contexts, expectedContexts); diff != "" { +// return fmt.Errorf("diff %q: (-got +want)\n%s", "contexts", diff) +// } +// +// return nil +// } +//} +// +//func testAccCheckGithubBranchProtectionRestrictions(protection *github.Protection, expectedUserLogins []string, expectedTeamNames []string) resource.TestCheckFunc { +// return func(s *terraform.State) error { +// restrictions := protection.GetRestrictions() +// if restrictions == nil { +// return fmt.Errorf("Expected Restrictions to be present, but was nil") +// } +// +// userLogins := []string{} +// for _, u := range restrictions.Users { +// userLogins = append(userLogins, u.GetLogin()) +// } +// if diff := pretty.Compare(userLogins, expectedUserLogins); diff != "" { +// return fmt.Errorf("diff %q: (-got +want)\n%s", "restrictions.users", diff) +// } +// +// teamLogins := []string{} +// for _, t := range restrictions.Teams { +// teamLogins = append(teamLogins, t.GetSlug()) +// } +// sort.Strings(teamLogins) +// sort.Strings(expectedTeamNames) +// if diff := pretty.Compare(teamLogins, expectedTeamNames); diff != "" { +// return fmt.Errorf("diff %q: (-got +want)\n%s", "restrictions.teams", diff) +// } +// +// return nil +// } +//} +// +//func testAccCheckGithubBranchProtectionPullRequestReviews(protection *github.Protection, expectedStale bool, expectedUsers, expectedTeams []string, expectedCodeOwners bool) resource.TestCheckFunc { +// return func(s *terraform.State) error { +// reviews := protection.GetRequiredPullRequestReviews() +// if reviews == nil { +// return fmt.Errorf("Expected Pull Request Reviews to be present, but was nil") +// } +// +// if reviews.DismissStaleReviews != expectedStale { +// return fmt.Errorf("Expected `dismiss_state_reviews` to be %t, got %t", expectedStale, reviews.DismissStaleReviews) +// } +// +// var users, teams []string +// if reviews.DismissalRestrictions != nil { +// if len(expectedUsers) == 0 && len(expectedTeams) == 0 { +// return fmt.Errorf("Expected Dismissal Restrictions to be nil but was present") +// } +// for _, u := range reviews.GetDismissalRestrictions().Users { +// users = append(users, u.GetLogin()) +// } +// +// for _, t := range reviews.GetDismissalRestrictions().Teams { +// teams = append(teams, t.GetSlug()) +// } +// } +// +// if diff := pretty.Compare(users, expectedUsers); diff != "" { +// return fmt.Errorf("diff %q: (-got +want)\n%s", "required_pull_request_reviews.dismissal_users", diff) +// } +// +// sort.Strings(teams) +// sort.Strings(expectedTeams) +// if diff := pretty.Compare(teams, expectedTeams); diff != "" { +// return fmt.Errorf("diff %q: (-got +want)\n%s", "required_pull_request_reviews.dismissal_teams", diff) +// } +// +// if reviews.RequireCodeOwnerReviews != expectedCodeOwners { +// return fmt.Errorf("Expected `require_code_owner_reviews` to be %t, got %t", expectedCodeOwners, reviews.RequireCodeOwnerReviews) +// } +// +// return nil +// } +//} +// +//func testAccCheckGithubBranchProtectionNoRestrictionsExist(protection *github.Protection) resource.TestCheckFunc { +// return func(s *terraform.State) error { +// if restrictions := protection.GetRestrictions(); restrictions != nil { +// return fmt.Errorf("Expected Restrictions to be nil, but was %v", restrictions) +// } +// +// return nil +// +// } +//} +// +//func testAccCheckGithubBranchProtectionNoPullRequestReviewsExist(protection *github.Protection) resource.TestCheckFunc { +// return func(s *terraform.State) error { +// if requiredPullRequestReviews := protection.GetRequiredPullRequestReviews(); requiredPullRequestReviews != nil { +// return fmt.Errorf("Expected Pull Request reviews to be nil, but was %v", requiredPullRequestReviews) +// } +// +// return nil +// } +//} +// +//func testAccGithubBranchProtectionDestroy(s *terraform.State) error { +// conn := testAccProvider.Meta().(*Owner).v3client +// +// for _, rs := range s.RootModule().Resources { +// if rs.Type != "github_branch_protection" { +// continue +// } +// +// o := testAccProvider.Meta().(*Owner).name +// r, b, err := parseTwoPartID(rs.Primary.ID, "repository", "branch") +// if err != nil { +// return err +// } +// +// protection, res, err := conn.Repositories.GetBranchProtection(context.TODO(), o, r, b) +// +// if err == nil { +// if protection != nil { +// return fmt.Errorf("Branch protection still exists") +// } +// } +// if res.StatusCode != 404 { +// return err +// } +// return nil +// } +// return nil +//} +// +//func testAccGithubBranchProtectionConfig(repoName string) string { +// return fmt.Sprintf(` +//resource "github_repository" "test" { +// name = "%s" +// description = "Terraform Acceptance Test %s" +// auto_init = true +//} +// +//resource "github_branch_protection" "master" { +// repository = "${github_repository.test.name}" +// branch = "master" +// enforce_admins = true +// require_signed_commits = true +// +// required_status_checks { +// strict = true +// contexts = ["github/foo"] +// } +// +// required_pull_request_reviews { +// dismiss_stale_reviews = true +// dismissal_users = ["%s"] +// require_code_owner_reviews = true +// } +// +// restrictions { +// users = ["%s"] +// } +//} +//`, repoName, repoName, testUser, testUser) +//} +// +//func testAccGithubBranchProtectionUpdateConfig(repoName string) string { +// return fmt.Sprintf(` +//resource "github_repository" "test" { +// name = "%s" +// description = "Terraform Acceptance Test %s" +// auto_init = true +//} +// +//resource "github_branch_protection" "master" { +// repository = "${github_repository.test.name}" +// branch = "master" +// +// required_status_checks { +// strict = false +// contexts = ["github/bar"] +// } +//} +//`, repoName, repoName) +//} +// +//func testAccGithubBranchProtectionConfigEmptyItems(repoName string) string { +// return fmt.Sprintf(` +//resource "github_repository" "test" { +// name = "%s" +// description = "Terraform Acceptance Test %s" +// auto_init = true +//} +// +//resource "github_branch_protection" "master" { +// repository = "${github_repository.test.name}" +// branch = "master" +// enforce_admins = true +// +// required_status_checks { +// } +// +// required_pull_request_reviews { +// } +// +// restrictions { +// } +//} +//`, repoName, repoName) +//} +// +//func testAccGithubBranchProtectionConfigTeams(repoName, firstTeamName, secondTeamName string) string { +// return fmt.Sprintf(` +//resource "github_repository" "test" { +// name = "%s" +// description = "Terraform Acceptance Test %s" +// auto_init = true +//} +// +//resource "github_team" "first" { +// name = "%s" +//} +// +//resource "github_team_repository" "first" { +// team_id = "${github_team.first.id}" +// repository = "${github_repository.test.name}" +// permission = "push" +//} +// +//resource "github_team" "second" { +// name = "%s" +//} +// +//resource "github_team_repository" "second" { +// team_id = "${github_team.second.id}" +// repository = "${github_repository.test.name}" +// permission = "push" +//} +// +//resource "github_branch_protection" "master" { +// depends_on = ["github_team_repository.first", "github_team_repository.second"] +// repository = "${github_repository.test.name}" +// branch = "master" +// enforce_admins = true +// +// required_status_checks { +// } +// +// required_pull_request_reviews { +// dismiss_stale_reviews = true +// dismissal_teams = ["${github_team.first.slug}", "${github_team.second.slug}"] +// } +// +// restrictions { +// teams = ["${github_team.first.slug}", "${github_team.second.slug}"] +// } +//} +//`, repoName, repoName, firstTeamName, secondTeamName) +//} +// +//func testAccGithubBranchProtectionConfigUser(repoName, user string) string { +// return fmt.Sprintf(` +//resource "github_repository" "test" { +// name = "%s" +// description = "Terraform Acceptance Test %s" +// auto_init = true +//} +// +//resource "github_branch_protection" "master" { +// repository = "${github_repository.test.name}" +// branch = "master" +// enforce_admins = true +// +// restrictions { +// users = ["%s"] +// } +//} +//`, repoName, repoName, user) +//} +// +//func testAccGithubBranchProtectionEmptyDismissalsConfig(repoName string) string { +// return fmt.Sprintf(` +// +//resource "github_repository" "test" { +// name = "%s" +// description = "Terraform Acceptance Test %s" +// auto_init = true +//} +// +//resource "github_branch_protection" "master" { +// repository = "${github_repository.test.name}" +// branch = "master" +// enforce_admins = true +// +// required_pull_request_reviews { +// dismiss_stale_reviews = true +// require_code_owner_reviews = true +// } +//} +//`, repoName, repoName) +//}