diff --git a/github/util_v4.go b/github/util_v4.go index 4d9260a14c..82ea878e4d 100644 --- a/github/util_v4.go +++ b/github/util_v4.go @@ -1,7 +1,8 @@ package github import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "context" + "github.com/shurcooL/githubv4" ) @@ -10,33 +11,108 @@ type PageInfo struct { HasNextPage bool } -func expandNestedSet(m map[string]interface{}, target string) []string { - res := make([]string, 0) - if v, ok := m[target]; ok { - vL := v.(*schema.Set).List() - for _, v := range vL { - res = append(res, v.(string)) - } +func getRepositoryID(name string, meta interface{}) (githubv4.ID, error) { + var query struct { + Repository struct { + ID githubv4.ID + } `graphql:"repository(owner:$owner, name:$name)"` + } + variables := map[string]interface{}{ + "owner": githubv4.String(meta.(*Owner).name), + "name": githubv4.String(name), + } + ctx := context.Background() + client := meta.(*Owner).v4client + err := client.Query(ctx, &query, variables) + if err != nil { + return nil, err } - return res + + return query.Repository.ID, nil } -func githubv4StringSlice(ss []string) []githubv4.String { - var vGh4 []githubv4.String - for _, s := range ss { - vGh4 = append(vGh4, githubv4.String(s)) +func getRepositoryName(id string, meta interface{}) (githubv4.String, error) { + + // { + // node(id: "MDEwOlJlcG9zaXRvcnkzMDkxNjc3NjY=") { + // ... on Repository { + // name + // } + // } + // } + + var query struct { + Node struct { + Repository struct { + Name githubv4.String + } `graphql:"... on Repository"` + } `graphql:"node(id:$id)"` + } + + variables := map[string]interface{}{ + "id": githubv4.ID(id), } - return vGh4 -} -func githubv4IDSlice(ss []string) []githubv4.ID { - var vGh4 []githubv4.ID - for _, s := range ss { - vGh4 = append(vGh4, githubv4.ID(s)) + ctx := context.Background() + client := meta.(*Owner).v4client + err := client.Query(ctx, &query, variables) + if err != nil { + return "", err } - return vGh4 + + return query.Node.Repository.Name, nil } -func githubv4NewStringSlice(v []githubv4.String) *[]githubv4.String { return &v } +func getBranchProtectionID(name string, pattern string, meta interface{}) (githubv4.ID, error) { + var query struct { + Node struct { + Repository struct { + BranchProtectionRules struct { + Nodes []struct { + ID string + Pattern string + } + PageInfo PageInfo + } `graphql:"branchProtectionRules(first: $first, after: $cursor)"` + ID string + } `graphql:"... on Repository"` + } `graphql:"repository(owner: $owner, name: $name)"` + } + variables := map[string]interface{}{ + "owner": githubv4.String(meta.(*Owner).name), + "name": githubv4.String(name), + "first": githubv4.Int(100), + "cursor": (*githubv4.String)(nil), + } -func githubv4NewIDSlice(v []githubv4.ID) *[]githubv4.ID { return &v } + ctx := context.Background() + client := meta.(*Owner).v4client + + var allRules []struct { + ID string + Pattern string + } + for { + err := client.Query(ctx, &query, variables) + if err != nil { + return nil, err + } + + allRules = append(allRules, query.Node.Repository.BranchProtectionRules.Nodes...) + + if !query.Node.Repository.BranchProtectionRules.PageInfo.HasNextPage { + break + } + variables["cursor"] = githubv4.NewString(query.Node.Repository.BranchProtectionRules.PageInfo.EndCursor) + } + + var id string + for i := range allRules { + if allRules[i].Pattern == pattern { + id = allRules[i].ID + break + } + } + + return id, nil +} diff --git a/github/util_v4_branch_protection.go b/github/util_v4_branch_protection.go deleted file mode 100644 index f7b601740d..0000000000 --- a/github/util_v4_branch_protection.go +++ /dev/null @@ -1,271 +0,0 @@ -package github - -import ( - "context" - "fmt" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/shurcooL/githubv4" -) - -type Actor struct { - ID githubv4.ID - Name githubv4.String -} - -type ActorTypes struct { - Actor struct { - Team Actor `graphql:"... on Team"` - User Actor `graphql:"... on User"` - } -} - -type BranchProtectionRule struct { - Repository struct { - ID githubv4.String - Name githubv4.String - } - PushAllowances struct { - Nodes []ActorTypes - } `graphql:"pushAllowances(first: 100)"` - ReviewDismissalAllowances struct { - Nodes []ActorTypes - } `graphql:"reviewDismissalAllowances(first: 100)"` - DismissesStaleReviews githubv4.Boolean - ID githubv4.ID - IsAdminEnforced githubv4.Boolean - Pattern githubv4.String - RequiredApprovingReviewCount githubv4.Int - RequiredStatusCheckContexts []githubv4.String - RequiresApprovingReviews githubv4.Boolean - RequiresCodeOwnerReviews githubv4.Boolean - RequiresCommitSignatures githubv4.Boolean - RequiresStatusChecks githubv4.Boolean - RequiresStrictStatusChecks githubv4.Boolean - RestrictsPushes githubv4.Boolean - RestrictsReviewDismissals githubv4.Boolean -} - -type BranchProtectionResourceData struct { - BranchProtectionRuleID string - DismissesStaleReviews bool - IsAdminEnforced bool - Pattern string - PushActorIDs []string - RepositoryID string - RequiredApprovingReviewCount int - RequiredStatusCheckContexts []string - RequiresApprovingReviews bool - RequiresCodeOwnerReviews bool - RequiresCommitSignatures bool - RequiresStatusChecks bool - RequiresStrictStatusChecks bool - RestrictsPushes bool - RestrictsReviewDismissals bool - ReviewDismissalActorIDs []string -} - -func branchProtectionResourceData(d *schema.ResourceData, meta interface{}) (BranchProtectionResourceData, error) { - data := BranchProtectionResourceData{} - - if v, ok := d.GetOk(REPOSITORY_ID); ok { - data.RepositoryID = v.(string) - } - - if v, ok := d.GetOk(PROTECTION_PATTERN); ok { - data.Pattern = v.(string) - } - - if v, ok := d.GetOk(PROTECTION_IS_ADMIN_ENFORCED); ok { - data.IsAdminEnforced = v.(bool) - } - - if v, ok := d.GetOk(PROTECTION_REQUIRES_COMMIT_SIGNATURES); ok { - data.RequiresCommitSignatures = v.(bool) - } - - if v, ok := d.GetOk(PROTECTION_REQUIRES_APPROVING_REVIEWS); ok { - vL := v.([]interface{}) - if len(vL) > 1 { - return BranchProtectionResourceData{}, - fmt.Errorf("error multiple %s declarations", PROTECTION_REQUIRES_APPROVING_REVIEWS) - } - for _, v := range vL { - if v == nil { - break - } - - data.RequiresApprovingReviews = true - - m := v.(map[string]interface{}) - if v, ok := m[PROTECTION_REQUIRED_APPROVING_REVIEW_COUNT]; ok { - data.RequiredApprovingReviewCount = v.(int) - } - if v, ok := m[PROTECTION_DISMISSES_STALE_REVIEWS]; ok { - data.DismissesStaleReviews = v.(bool) - } - if v, ok := m[PROTECTION_REQUIRES_CODE_OWNER_REVIEWS]; ok { - data.RequiresCodeOwnerReviews = v.(bool) - } - if v, ok := m[PROTECTION_RESTRICTS_REVIEW_DISMISSALS]; ok { - reviewDismissalActorIDs := make([]string, 0) - vL := v.(*schema.Set).List() - for _, v := range vL { - reviewDismissalActorIDs = append(reviewDismissalActorIDs, v.(string)) - } - if len(reviewDismissalActorIDs) > 0 { - data.ReviewDismissalActorIDs = reviewDismissalActorIDs - data.RestrictsReviewDismissals = true - } - } - } - } - - if v, ok := d.GetOk(PROTECTION_REQUIRES_STATUS_CHECKS); ok { - vL := v.([]interface{}) - if len(vL) > 1 { - return BranchProtectionResourceData{}, - fmt.Errorf("error multiple %s declarations", PROTECTION_REQUIRES_STATUS_CHECKS) - } - for _, v := range vL { - if v == nil { - break - } - - m := v.(map[string]interface{}) - if v, ok := m[PROTECTION_REQUIRES_STRICT_STATUS_CHECKS]; ok { - data.RequiresStrictStatusChecks = v.(bool) - } - - data.RequiredStatusCheckContexts = expandNestedSet(m, PROTECTION_REQUIRED_STATUS_CHECK_CONTEXTS) - if len(data.RequiredStatusCheckContexts) > 0 { - data.RequiresStatusChecks = true - } - } - } - - if v, ok := d.GetOk(PROTECTION_RESTRICTS_PUSHES); ok { - pushActorIDs := make([]string, 0) - vL := v.(*schema.Set).List() - for _, v := range vL { - pushActorIDs = append(pushActorIDs, v.(string)) - } - if len(pushActorIDs) > 0 { - data.PushActorIDs = pushActorIDs - data.RestrictsPushes = true - } - } - - return data, nil -} - -func setActorIDs(actors []ActorTypes) []string { - pushActors := make([]string, 0, len(actors)) - for _, a := range actors { - if a.Actor.Team != (Actor{}) { - pushActors = append(pushActors, a.Actor.Team.ID.(string)) - } - if a.Actor.User != (Actor{}) { - pushActors = append(pushActors, a.Actor.Team.ID.(string)) - } - } - - return pushActors -} - -func setApprovingReviews(protection BranchProtectionRule) interface{} { - if !protection.RequiresApprovingReviews { - return nil - } - - dismissalAllowances := protection.ReviewDismissalAllowances.Nodes - dismissalActors := setActorIDs(dismissalAllowances) - approvalReviews := []interface{}{ - map[string]interface{}{ - PROTECTION_REQUIRED_APPROVING_REVIEW_COUNT: protection.RequiredApprovingReviewCount, - PROTECTION_REQUIRES_CODE_OWNER_REVIEWS: protection.RequiresCodeOwnerReviews, - PROTECTION_DISMISSES_STALE_REVIEWS: protection.DismissesStaleReviews, - PROTECTION_RESTRICTS_REVIEW_DISMISSALS: dismissalActors, - }, - } - - return approvalReviews -} - -func setStatusChecks(protection BranchProtectionRule) interface{} { - if !protection.RequiresStatusChecks { - return nil - } - - statusChecks := []interface{}{ - map[string]interface{}{ - PROTECTION_REQUIRES_STRICT_STATUS_CHECKS: protection.RequiresStrictStatusChecks, - PROTECTION_REQUIRED_STATUS_CHECK_CONTEXTS: protection.RequiredStatusCheckContexts, - }, - } - - return statusChecks -} - -func setPushes(protection BranchProtectionRule) []string { - if !protection.RestrictsPushes { - return nil - } - pushAllowances := protection.PushAllowances.Nodes - pushActors := setActorIDs(pushAllowances) - - return pushActors -} - -func getBranchProtectionID(name string, pattern string, meta interface{}) (githubv4.ID, error) { - var query struct { - Node struct { - Repository struct { - BranchProtectionRules struct { - Nodes []struct { - ID string - Pattern string - } - PageInfo PageInfo - } `graphql:"branchProtectionRules(first: $first, after: $cursor)"` - ID string - } `graphql:"... on Repository"` - } `graphql:"repository(owner: $owner, name: $name)"` - } - variables := map[string]interface{}{ - "owner": githubv4.String(meta.(*Owner).name), - "name": githubv4.String(name), - "first": githubv4.Int(100), - "cursor": (*githubv4.String)(nil), - } - - ctx := context.Background() - client := meta.(*Owner).v4client - - var allRules []struct { - ID string - Pattern string - } - for { - err := client.Query(ctx, &query, variables) - if err != nil { - return nil, err - } - - allRules = append(allRules, query.Node.Repository.BranchProtectionRules.Nodes...) - - if !query.Node.Repository.BranchProtectionRules.PageInfo.HasNextPage { - break - } - variables["cursor"] = githubv4.NewString(query.Node.Repository.BranchProtectionRules.PageInfo.EndCursor) - } - - var id string - for i := range allRules { - if allRules[i].Pattern == pattern { - id = allRules[i].ID - break - } - } - - return id, nil -} diff --git a/github/util_v4_consts.go b/github/util_v4_consts.go deleted file mode 100644 index adfe74585c..0000000000 --- a/github/util_v4_consts.go +++ /dev/null @@ -1,18 +0,0 @@ -package github - -const ( - PROTECTION_DISMISSES_STALE_REVIEWS = "dismiss_stale_reviews" - PROTECTION_IS_ADMIN_ENFORCED = "enforce_admins" - PROTECTION_PATTERN = "pattern" - PROTECTION_REQUIRED_APPROVING_REVIEW_COUNT = "required_approving_review_count" - PROTECTION_REQUIRED_STATUS_CHECK_CONTEXTS = "contexts" - PROTECTION_REQUIRES_APPROVING_REVIEWS = "required_pull_request_reviews" - PROTECTION_REQUIRES_CODE_OWNER_REVIEWS = "require_code_owner_reviews" - PROTECTION_REQUIRES_COMMIT_SIGNATURES = "require_signed_commits" - PROTECTION_REQUIRES_STATUS_CHECKS = "required_status_checks" - PROTECTION_REQUIRES_STRICT_STATUS_CHECKS = "strict" - PROTECTION_RESTRICTS_PUSHES = "push_restrictions" - PROTECTION_RESTRICTS_REVIEW_DISMISSALS = "dismissal_restrictions" - - REPOSITORY_ID = "repository_id" -) diff --git a/github/util_v4_repository.go b/github/util_v4_repository.go deleted file mode 100644 index 3866e04676..0000000000 --- a/github/util_v4_repository.go +++ /dev/null @@ -1,26 +0,0 @@ -package github - -import ( - "context" - "github.com/shurcooL/githubv4" -) - -func getRepositoryID(name string, meta interface{}) (githubv4.ID, error) { - var query struct { - Repository struct { - ID githubv4.ID - } `graphql:"repository(owner:$owner, name:$name)"` - } - variables := map[string]interface{}{ - "owner": githubv4.String(meta.(*Owner).name), - "name": githubv4.String(name), - } - ctx := context.Background() - client := meta.(*Owner).v4client - err := client.Query(ctx, &query, variables) - if err != nil { - return nil, err - } - - return query.Repository.ID, nil -}