diff --git a/github/resource_github_branch_protection_v3.go b/github/resource_github_branch_protection_v3.go index 50f0f6d5c6..d653856cac 100644 --- a/github/resource_github_branch_protection_v3.go +++ b/github/resource_github_branch_protection_v3.go @@ -110,6 +110,12 @@ func resourceGithubBranchProtectionV3() *schema.Resource { Description: "The list of team slugs with dismissal access. Always use slug of the team, not its name. Each team already has to have access to the repository.", Elem: &schema.Schema{Type: schema.TypeString}, }, + "dismissal_apps": { + Type: schema.TypeSet, + Optional: true, + Description: "The list of apps slugs with dismissal access. Always use slug of the app, not its name. Each app already has to have access to the repository.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, "require_code_owner_reviews": { Type: schema.TypeBool, Optional: true, diff --git a/github/resource_github_branch_protection_v3_test.go b/github/resource_github_branch_protection_v3_test.go index 9f673662d2..80d7ab1c16 100644 --- a/github/resource_github_branch_protection_v3_test.go +++ b/github/resource_github_branch_protection_v3_test.go @@ -301,6 +301,16 @@ func TestAccGithubBranchProtectionV3_required_pull_request_reviews(t *testing.T) auto_init = true } + resource "github_team" "test" { + name = "tf-acc-test-%[1]s" + } + + resource "github_team_repository" "test" { + team_id = github_team.test.id + repository = github_repository.test.name + permission = "admin" + } + resource "github_branch_protection_v3" "test" { repository = github_repository.test.name @@ -309,10 +319,19 @@ func TestAccGithubBranchProtectionV3_required_pull_request_reviews(t *testing.T) required_pull_request_reviews { dismiss_stale_reviews = true require_code_owner_reviews = true + required_approving_review_count = 1 + dismissal_users = ["a"] + dismissal_teams = ["b"] + dismissal_apps = ["c"] + bypass_pull_request_allowances { + users = ["d"] + teams = [github_team.test.slug] + apps = ["e"] + } } + depends_on = [github_team_repository.test] } - `, randomID) check := resource.ComposeAggregateTestCheckFunc( @@ -328,6 +347,27 @@ func TestAccGithubBranchProtectionV3_required_pull_request_reviews(t *testing.T) resource.TestCheckResourceAttr( "github_branch_protection_v3.test", "required_pull_request_reviews.0.required_approving_review_count", "1", ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.dismissal_users.#", "1", + ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.dismissal_teams.#", "1", + ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.dismissal_apps.#", "1", + ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.bypass_pull_request_allowances.#", "1", + ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.bypass_pull_request_allowances.0.users.#", "1", + ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.bypass_pull_request_allowances.0.teams.#", "1", + ), + resource.TestCheckResourceAttr( + "github_branch_protection_v3.test", "required_pull_request_reviews.0.bypass_pull_request_allowances.0.apps.#", "1", + ), ) testCase := func(t *testing.T, mode string) { diff --git a/github/resource_github_branch_protection_v3_utils.go b/github/resource_github_branch_protection_v3_utils.go index 440ccabfb9..596933e115 100644 --- a/github/resource_github_branch_protection_v3_utils.go +++ b/github/resource_github_branch_protection_v3_utils.go @@ -162,7 +162,7 @@ func flattenBypassPullRequestAllowances(bpra *github.BypassPullRequestAllowances func flattenAndSetRequiredPullRequestReviews(d *schema.ResourceData, protection *github.Protection) error { rprr := protection.GetRequiredPullRequestReviews() if rprr != nil { - var users, teams []interface{} + var users, teams, apps []interface{} restrictions := rprr.GetDismissalRestrictions() if restrictions != nil { @@ -178,6 +178,12 @@ func flattenAndSetRequiredPullRequestReviews(d *schema.ResourceData, protection 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) + } + } } bpra := flattenBypassPullRequestAllowances(rprr.GetBypassPullRequestAllowances()) @@ -187,6 +193,7 @@ func flattenAndSetRequiredPullRequestReviews(d *schema.ResourceData, protection "dismiss_stale_reviews": rprr.DismissStaleReviews, "dismissal_users": schema.NewSet(schema.HashString, users), "dismissal_teams": schema.NewSet(schema.HashString, teams), + "dismissal_apps": schema.NewSet(schema.HashString, apps), "require_code_owner_reviews": rprr.RequireCodeOwnerReviews, "required_approving_review_count": rprr.RequiredApprovingReviewCount, "bypass_pull_request_allowances": bpra, @@ -330,6 +337,11 @@ func expandRequiredPullRequestReviews(d *schema.ResourceData) (*github.PullReque drr.Teams = &teams } + apps := expandNestedSet(m, "dismissal_apps") + if len(apps) > 0 { + drr.Apps = &apps + } + bpra, err := expandBypassPullRequestAllowances(m) if err != nil { return nil, err diff --git a/website/docs/r/branch_protection_v3.html.markdown b/website/docs/r/branch_protection_v3.html.markdown index 1f99d18399..7a23f37941 100644 --- a/website/docs/r/branch_protection_v3.html.markdown +++ b/website/docs/r/branch_protection_v3.html.markdown @@ -48,6 +48,7 @@ resource "github_branch_protection_v3" "example" { dismiss_stale_reviews = true dismissal_users = ["foo-user"] dismissal_teams = [github_team.example.slug] + dismissal_app = ["foo-app] bypass_pull_request_allowances { users = ["foo-user"] @@ -107,6 +108,7 @@ The following arguments are supported: * `dismissal_users`: (Optional) The list of user logins with dismissal access * `dismissal_teams`: (Optional) The list of team slugs with dismissal access. Always use `slug` of the team, **not** its name. Each team already **has** to have access to the repository. +* `dismissal_apps`: (Optional) The list of app slugs with dismissal access. * `require_code_owner_reviews`: (Optional) Require an approved review in pull requests including files with a designated code owner. Defaults to `false`. * `required_approving_review_count`: (Optional) Require x number of approvals to satisfy branch protection requirements. If this is specified it must be a number between 0-6. This requirement matches GitHub's API, see the upstream [documentation](https://developer.github.com/v3/repos/branches/#parameters-1) for more information. * `bypass_pull_request_allowances`: (Optional) Allow specific users, teams, or apps to bypass pull request requirements. See [Bypass Pull Request Allowances](#bypass-pull-request-allowances) below for details.