Skip to content

Commit a782a23

Browse files
TheQueenIsDeaddavid-bainkfcampbellwwsean08trentmillar
authored
feature/985 branch protection checks (integrations#1415)
* feat: add new schema for check block resource under required_status_checks * feat: iterate provided `check` blocks and build array of RequiredStatusCheck * feat: set default app_id to -1 * feat: implement checks flattening for required status checks * Add resource github_app_installation_repositories (integrations#1376) * Add resource github_app_installation_repositories This resource allows multiple repositories to be passed in; which greatly improves the performance of the resource compared to the single repository version when needing to control state of multiple app installations with multiple repos, required in larger organisations. The optimisation occurs as only a single call to get the list of repos is required per installation per read, regardless of the number of respositories being added. - Add resource_github_app_installation_repositories - Add tests * Update docs and link Co-authored-by: Keegan Campbell <me@kfcampbell.com> * feat: adds new branch protection options for last reviewer and locking branch (integrations#1407) Co-authored-by: Keegan Campbell <me@kfcampbell.com> * feat(github_release): adding github_release resource and tests (integrations#1122) * feat(github_release): adding github_release resource and tests * feat(docs) adding github_release page to website docs * chore: update changelog with this pr's new resource * fix: adding node_id and release_id to resource attributes * Update CHANGELOG.md * Fix broken merge/build Co-authored-by: Keegan Campbell <me@kfcampbell.com> * 🚧 Workflows have changed Workflow changes have been made in the Octokit org repo. This PR is propagating those changes. * Issue template tweak (integrations#1422) * Don't link to a real PR * Wording tweak * feat: allow branch protection check app_id to be null * chore: change branch protection flatten function to use GetAppID sdk method * feat: change branch protection v3 utils to flatten and expand contexts into checks * feat: change checks from it's own resource to a list of strings * chore: resolve incorrect merge of main * chore: update deprecation notice on contexts array * chore(docs): Update branch_protection_v3 docs to mention the new `checks` functionality * fix: Initialise literal empty slice of RequiredStatusCheck to mitigate errors when passing nil to the sdk * chore(lint): resolve gosimple S1082 violation (errors.New => fmt.Errorf) * chore: remove unused code comment Co-authored-by: David Bain <97858950+david-bain@users.noreply.github.com> Co-authored-by: Keegan Campbell <me@kfcampbell.com> Co-authored-by: Sean Smith <sean@wwsean08.com> Co-authored-by: Trent Millar <trent.millar@gmail.com> Co-authored-by: Nick Floyd <139819+nickfloyd@users.noreply.github.com>
1 parent a655e2a commit a782a23

File tree

3 files changed

+87
-10
lines changed

3 files changed

+87
-10
lines changed

github/resource_github_branch_protection_v3.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ func resourceGithubBranchProtectionV3() *schema.Resource {
5353
Default: false,
5454
},
5555
"contexts": {
56+
Type: schema.TypeSet,
57+
Optional: true,
58+
Deprecated: "GitHub is deprecating the use of `contexts`. Use a `checks` array instead.",
59+
Elem: &schema.Schema{
60+
Type: schema.TypeString,
61+
},
62+
},
63+
"checks": {
5664
Type: schema.TypeSet,
5765
Optional: true,
5866
Elem: &schema.Schema{

github/resource_github_branch_protection_v3_utils.go

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"log"
8-
"strings"
9-
107
"github.com/google/go-github/v49/github"
118
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
9+
"log"
10+
"strconv"
11+
"strings"
1212
)
1313

1414
func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest, error) {
@@ -40,16 +40,34 @@ func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest,
4040

4141
func flattenAndSetRequiredStatusChecks(d *schema.ResourceData, protection *github.Protection) error {
4242
rsc := protection.GetRequiredStatusChecks()
43+
4344
if rsc != nil {
44-
contexts := make([]interface{}, 0, len(rsc.Contexts))
45+
46+
// Contexts and Checks arrays to flatten into
47+
var contexts []interface{}
48+
var checks []interface{}
49+
50+
// TODO: Remove once contexts is fully deprecated.
51+
// Flatten contexts
4552
for _, c := range rsc.Contexts {
53+
// Parse into contexts
4654
contexts = append(contexts, c)
55+
checks = append(contexts, c)
56+
}
57+
58+
// Flatten checks
59+
for _, chk := range rsc.Checks {
60+
// Parse into contexts
61+
contexts = append(contexts, chk.Context)
62+
checks = append(contexts, fmt.Sprintf("%s:%d", chk.Context, chk.AppID))
4763
}
4864

4965
return d.Set("required_status_checks", []interface{}{
5066
map[string]interface{}{
51-
"strict": rsc.Strict,
67+
"strict": rsc.Strict,
68+
// TODO: Remove once contexts is fully deprecated.
5269
"contexts": schema.NewSet(schema.HashString, contexts),
70+
"checks": schema.NewSet(schema.HashString, checks),
5371
},
5472
})
5573
}
@@ -191,8 +209,56 @@ func expandRequiredStatusChecks(d *schema.ResourceData) (*github.RequiredStatusC
191209
m := v.(map[string]interface{})
192210
rsc.Strict = m["strict"].(bool)
193211

212+
// Initialise empty literal to ensure an empty array is passed mitigating schema errors like so:
213+
// For 'anyOf/1', {"strict"=>true, "checks"=>nil} is not a null. []
214+
rscChecks := []*github.RequiredStatusCheck{}
215+
216+
// TODO: Remove once contexts is deprecated
217+
// Iterate and parse contexts into checks using -1 as default to allow checks from all apps.
194218
contexts := expandNestedSet(m, "contexts")
195-
rsc.Contexts = contexts
219+
for _, c := range contexts {
220+
appID := int64(-1) // Default
221+
rscChecks = append(rscChecks, &github.RequiredStatusCheck{
222+
Context: c,
223+
AppID: &appID,
224+
})
225+
}
226+
227+
// Iterate and parse checks
228+
checks := expandNestedSet(m, "checks")
229+
for _, c := range checks {
230+
231+
// Expect a string of "context:app_id", allowing for the absence of "app_id"
232+
parts := strings.SplitN(c, ":", 2)
233+
var cContext, cAppId string
234+
switch len(parts) {
235+
case 1:
236+
cContext, cAppId = parts[0], ""
237+
case 2:
238+
cContext, cAppId = parts[0], parts[1]
239+
default:
240+
return nil, fmt.Errorf("Could not parse check '%s'. Expected `context:app_id` or `context`", c)
241+
}
242+
243+
var rscCheck *github.RequiredStatusCheck
244+
if cAppId != "" {
245+
// If we have a valid app_id, include it in the RSC
246+
rscAppId, err := strconv.Atoi(cAppId)
247+
if err != nil {
248+
return nil, fmt.Errorf("Could not parse %v as valid app_id", cAppId)
249+
}
250+
rscAppId64 := int64(rscAppId)
251+
rscCheck = &github.RequiredStatusCheck{Context: cContext, AppID: &rscAppId64}
252+
} else {
253+
// Else simply provide the context
254+
rscCheck = &github.RequiredStatusCheck{Context: cContext}
255+
}
256+
257+
// Append
258+
rscChecks = append(rscChecks, rscCheck)
259+
}
260+
// Assign after looping both checks and contexts
261+
rsc.Checks = rscChecks
196262
}
197263
return rsc, nil
198264
}

website/docs/r/branch_protection_v3.html.markdown

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ resource "github_branch_protection_v3" "example" {
2929

3030
```hcl
3131
# Protect the main branch of the foo repository. Additionally, require that
32-
# the "ci/travis" context to be passing and only allow the engineers team merge
33-
# to the branch.
32+
# the "ci/check" check ran by the Github Actions app is passing and only allow
33+
# the engineers team merge to the branch.
3434
3535
resource "github_branch_protection_v3" "example" {
3636
repository = github_repository.example.name
@@ -39,7 +39,9 @@ resource "github_branch_protection_v3" "example" {
3939
4040
required_status_checks {
4141
strict = false
42-
contexts = ["ci/travis"]
42+
checks = [
43+
"ci/check:824642007264"
44+
]
4345
}
4446
4547
required_pull_request_reviews {
@@ -88,7 +90,8 @@ The following arguments are supported:
8890
`required_status_checks` supports the following arguments:
8991

9092
* `strict`: (Optional) Require branches to be up to date before merging. Defaults to `false`.
91-
* `contexts`: (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default.
93+
* `contexts`: [**DEPRECATED**] (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default.
94+
* `checks`: (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. Checks should be strings containing the context and app_id like so "context:app_id".
9295

9396
### Required Pull Request Reviews
9497

0 commit comments

Comments
 (0)