Skip to content

Commit

Permalink
Provide "require signed commits" on github_branch_protection
Browse files Browse the repository at this point in the history
This commit provides changing the toggle to require signed commits on
branch protection.

The [API for signed commits](https://developer.github.com/v3/repos/branches/#get-required-signatures-of-protected-branch)
is separate endpoint from the branch protection url, and does not come on the same payload.
This means that we need to make an extra request to read and modify it.

This changes requires `go-github` at least v19.

Need:
 - [ ] Update `go-github` version: https://github.com/terraform-providers/terraform-provider-github/pull/207
 - [ ] Provide default required reviewers count to avoid GitHub update error: https://github.com/terraform-providers/terraform-provider-github/pull/211
Closes https://github.com/terraform-providers/terraform-provider-github/issues/87
  • Loading branch information
bltavares committed May 2, 2019
1 parent e745c7f commit eaa247d
Showing 1 changed file with 70 additions and 0 deletions.
70 changes: 70 additions & 0 deletions github/resource_github_branch_protection.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ func resourceGithubBranchProtection() *schema.Resource {
Optional: true,
Default: false,
},
"require_signed_commits": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"etag": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -165,6 +170,10 @@ func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface

d.SetId(buildTwoPartID(&repoName, &branch))

if err = requireSignedCommitsUpdate(d, meta); err != nil {
return err
}

return resourceGithubBranchProtectionRead(d, meta)
}

Expand All @@ -189,6 +198,9 @@ func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}
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 {
Expand Down Expand Up @@ -219,6 +231,10 @@ func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}
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
}

Expand Down Expand Up @@ -262,6 +278,10 @@ func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface

d.SetId(buildTwoPartID(&repoName, &branch))

if err = requireSignedCommitsUpdate(d, meta); err != nil {
return err
}

return resourceGithubBranchProtectionRead(d, meta)
}

Expand Down Expand Up @@ -326,6 +346,56 @@ func flattenAndSetRequiredStatusChecks(d *schema.ResourceData, protection *githu
return d.Set("required_status_checks", []interface{}{})
}

func requireSignedCommitsRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client

repoName, branch, err := parseTwoPartID(d.Id())
if err != nil {
return err
}
orgName := meta.(*Organization).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.(*Organization).client

repoName, branch, err := parseTwoPartID(d.Id())
if err != nil {
return err
}
orgName := meta.(*Organization).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.RequiredPullRequestReviews
if rprr != nil {
Expand Down

0 comments on commit eaa247d

Please sign in to comment.