Skip to content

Commit a12c312

Browse files
bpaquetkfcampbell
andauthored
Handle deployment branch policies for repositories: resources and datasource (#1715)
* Add new resource github_repository_deployment_branch_policy * Implement data source * Add link * Fix bad merge --------- Co-authored-by: Keegan Campbell <me@kfcampbell.com>
1 parent f5c8a7a commit a12c312

8 files changed

+497
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"strconv"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
8+
)
9+
10+
func dataSourceGithubRepositoryDeploymentBranchPolicies() *schema.Resource {
11+
return &schema.Resource{
12+
Read: dataSourceGithubRepositoryDeploymentBranchPoliciesRead,
13+
14+
Schema: map[string]*schema.Schema{
15+
"repository": {
16+
Type: schema.TypeString,
17+
Required: true,
18+
ForceNew: true,
19+
Description: "The GitHub repository name.",
20+
},
21+
"environment_name": {
22+
Type: schema.TypeString,
23+
Required: true,
24+
ForceNew: true,
25+
Description: "The target environment name.",
26+
},
27+
"deployment_branch_policies": {
28+
Type: schema.TypeList,
29+
Computed: true,
30+
Elem: &schema.Resource{
31+
Schema: map[string]*schema.Schema{
32+
"id": {
33+
Type: schema.TypeString,
34+
Computed: true,
35+
},
36+
"name": {
37+
Type: schema.TypeString,
38+
Computed: true,
39+
},
40+
},
41+
},
42+
},
43+
},
44+
}
45+
}
46+
47+
func dataSourceGithubRepositoryDeploymentBranchPoliciesRead(d *schema.ResourceData, meta interface{}) error {
48+
client := meta.(*Owner).v3client
49+
owner := meta.(*Owner).name
50+
repoName := d.Get("repository").(string)
51+
environmentName := d.Get("environment_name").(string)
52+
53+
policies, _, err := client.Repositories.ListDeploymentBranchPolicies(context.Background(), owner, repoName, environmentName)
54+
if err != nil {
55+
return nil
56+
}
57+
58+
results := make([]map[string]interface{}, 0)
59+
60+
for _, policy := range policies.BranchPolicies {
61+
policyMap := make(map[string]interface{})
62+
policyMap["id"] = strconv.FormatInt(*policy.ID, 10)
63+
policyMap["name"] = policy.Name
64+
results = append(results, policyMap)
65+
}
66+
67+
d.SetId(repoName + ":" + environmentName)
68+
d.Set("deployment_branch_policies", results)
69+
70+
return nil
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
9+
)
10+
11+
func TestAccGithubRepositoryDeploymentBranchPolicies(t *testing.T) {
12+
13+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
14+
15+
t.Run("queries deployment branch policies", func(t *testing.T) {
16+
17+
config := fmt.Sprintf(`
18+
resource "github_repository" "test" {
19+
name = "tf-acc-test-%s"
20+
auto_init = true
21+
}
22+
23+
resource "github_repository_environment" "env" {
24+
repository = github_repository.test.name
25+
environment = "my_env"
26+
deployment_branch_policy {
27+
protected_branches = false
28+
custom_branch_policies = true
29+
}
30+
}
31+
32+
resource "github_repository_deployment_branch_policy" "br" {
33+
repository = github_repository.test.name
34+
environment_name = github_repository_environment.env.environment
35+
name = "foo"
36+
}
37+
`, randomID)
38+
39+
config2 := config + `
40+
data "github_repository_deployment_branch_policies" "all" {
41+
repository = github_repository.test.name
42+
environment_name = github_repository_environment.env.environment
43+
}
44+
`
45+
check := resource.ComposeTestCheckFunc(
46+
resource.TestCheckResourceAttr("data.github_repository_deployment_branch_policies.all", "deployment_branch_policies.#", "1"),
47+
resource.TestCheckResourceAttr("data.github_repository_deployment_branch_policies.all", "deployment_branch_policies.0.name", "foo"),
48+
resource.TestCheckResourceAttrSet("data.github_repository_deployment_branch_policies.all", "deployment_branch_policies.0.id"),
49+
)
50+
51+
testCase := func(t *testing.T, mode string) {
52+
resource.Test(t, resource.TestCase{
53+
PreCheck: func() { skipUnlessMode(t, mode) },
54+
Providers: testAccProviders,
55+
Steps: []resource.TestStep{
56+
{
57+
Config: config,
58+
},
59+
{
60+
Config: config2,
61+
Check: check,
62+
},
63+
},
64+
})
65+
}
66+
67+
t.Run("with an anonymous account", func(t *testing.T) {
68+
t.Skip("anonymous account not supported for this operation")
69+
})
70+
71+
t.Run("with an individual account", func(t *testing.T) {
72+
testCase(t, individual)
73+
})
74+
75+
t.Run("with an organization account", func(t *testing.T) {
76+
testCase(t, organization)
77+
})
78+
79+
})
80+
}

github/provider.go

+2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ func Provider() terraform.ResourceProvider {
134134
"github_repository_collaborator": resourceGithubRepositoryCollaborator(),
135135
"github_repository_collaborators": resourceGithubRepositoryCollaborators(),
136136
"github_repository_deploy_key": resourceGithubRepositoryDeployKey(),
137+
"github_repository_deployment_branch_policy": resourceGithubRepositoryDeploymentBranchPolicy(),
137138
"github_repository_environment": resourceGithubRepositoryEnvironment(),
138139
"github_repository_file": resourceGithubRepositoryFile(),
139140
"github_repository_milestone": resourceGithubRepositoryMilestone(),
@@ -192,6 +193,7 @@ func Provider() terraform.ResourceProvider {
192193
"github_repository_branches": dataSourceGithubRepositoryBranches(),
193194
"github_repository_environments": dataSourceGithubRepositoryEnvironments(),
194195
"github_repository_deploy_keys": dataSourceGithubRepositoryDeployKeys(),
196+
"github_repository_deployment_branch_policies": dataSourceGithubRepositoryDeploymentBranchPolicies(),
195197
"github_repository_file": dataSourceGithubRepositoryFile(),
196198
"github_repository_milestone": dataSourceGithubRepositoryMilestone(),
197199
"github_repository_pull_request": dataSourceGithubRepositoryPullRequest(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"strconv"
6+
7+
"github.com/google/go-github/v53/github"
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
9+
)
10+
11+
func resourceGithubRepositoryDeploymentBranchPolicy() *schema.Resource {
12+
return &schema.Resource{
13+
Create: resourceGithubRepositoryDeploymentBranchPolicyCreate,
14+
Read: resourceGithubRepositoryDeploymentBranchPolicyRead,
15+
Update: resourceGithubRepositoryDeploymentBranchPolicyUpdate,
16+
Delete: resourceGithubRepositoryDeploymentBranchPolicyDelete,
17+
Importer: &schema.ResourceImporter{
18+
State: resourceGithubRepositoryDeploymentBranchPolicyImport,
19+
},
20+
21+
Schema: map[string]*schema.Schema{
22+
"repository": {
23+
Type: schema.TypeString,
24+
Required: true,
25+
ForceNew: true,
26+
Description: "The GitHub repository name.",
27+
},
28+
"environment_name": {
29+
Type: schema.TypeString,
30+
Required: true,
31+
ForceNew: true,
32+
Description: "The target environment name.",
33+
},
34+
"name": {
35+
Type: schema.TypeString,
36+
Required: true,
37+
Description: "The name of the branch",
38+
},
39+
"etag": {
40+
Type: schema.TypeString,
41+
Computed: true,
42+
Description: "An etag representing the Branch object.",
43+
},
44+
},
45+
}
46+
}
47+
48+
func resourceGithubRepositoryDeploymentBranchPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
49+
ctx := context.Background()
50+
client := meta.(*Owner).v3client
51+
owner := meta.(*Owner).name
52+
repoName := d.Get("repository").(string)
53+
environmentName := d.Get("environment_name").(string)
54+
name := d.Get("name").(string)
55+
56+
id, err := strconv.Atoi(d.Id())
57+
if err != nil {
58+
return err
59+
}
60+
61+
_, _, err = client.Repositories.UpdateDeploymentBranchPolicy(ctx, owner, repoName, environmentName, int64(id), &github.DeploymentBranchPolicyRequest{Name: &name})
62+
if err != nil {
63+
return err
64+
}
65+
66+
return resourceGithubRepositoryDeploymentBranchPolicyRead(d, meta)
67+
}
68+
69+
func resourceGithubRepositoryDeploymentBranchPolicyCreate(d *schema.ResourceData, meta interface{}) error {
70+
ctx := context.Background()
71+
if !d.IsNewResource() {
72+
ctx = context.WithValue(ctx, ctxId, d.Id())
73+
}
74+
75+
client := meta.(*Owner).v3client
76+
owner := meta.(*Owner).name
77+
repoName := d.Get("repository").(string)
78+
environmentName := d.Get("environment_name").(string)
79+
name := d.Get("name").(string)
80+
81+
policy, _, err := client.Repositories.CreateDeploymentBranchPolicy(ctx, owner, repoName, environmentName, &github.DeploymentBranchPolicyRequest{Name: &name})
82+
if err != nil {
83+
return err
84+
}
85+
86+
d.SetId(strconv.FormatInt(*policy.ID, 10))
87+
88+
return resourceGithubRepositoryDeploymentBranchPolicyRead(d, meta)
89+
}
90+
91+
func resourceGithubRepositoryDeploymentBranchPolicyRead(d *schema.ResourceData, meta interface{}) error {
92+
ctx := context.WithValue(context.Background(), ctxId, d.Id())
93+
if !d.IsNewResource() {
94+
ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string))
95+
}
96+
97+
client := meta.(*Owner).v3client
98+
owner := meta.(*Owner).name
99+
repoName := d.Get("repository").(string)
100+
environmentName := d.Get("environment_name").(string)
101+
102+
id, err := strconv.Atoi(d.Id())
103+
if err != nil {
104+
return err
105+
}
106+
107+
policy, resp, err := client.Repositories.GetDeploymentBranchPolicy(ctx, owner, repoName, environmentName, int64(id))
108+
if err != nil && resp.StatusCode == 304 {
109+
return nil
110+
}
111+
if err != nil {
112+
return err
113+
}
114+
115+
d.Set("etag", resp.Header.Get("ETag"))
116+
d.Set("repository", repoName)
117+
d.Set("environment_name", environmentName)
118+
d.Set("name", policy.Name)
119+
120+
return nil
121+
}
122+
123+
func resourceGithubRepositoryDeploymentBranchPolicyDelete(d *schema.ResourceData, meta interface{}) error {
124+
ctx := context.WithValue(context.Background(), ctxId, d.Id())
125+
126+
client := meta.(*Owner).v3client
127+
owner := meta.(*Owner).name
128+
repoName := d.Get("repository").(string)
129+
environmentName := d.Get("environment_name").(string)
130+
131+
id, err := strconv.Atoi(d.Id())
132+
if err != nil {
133+
return err
134+
}
135+
136+
_, error := client.Repositories.DeleteDeploymentBranchPolicy(ctx, owner, repoName, environmentName, int64(id))
137+
if error != nil {
138+
return error
139+
}
140+
return nil
141+
}
142+
143+
func resourceGithubRepositoryDeploymentBranchPolicyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
144+
repoName, environmentName, id, err := parseThreePartID(d.Id(), "repository", "environment_name", "id")
145+
if err != nil {
146+
return nil, err
147+
}
148+
149+
d.SetId(id)
150+
d.Set("repository", repoName)
151+
d.Set("environment_name", environmentName)
152+
153+
err = resourceGithubBranchRead(d, meta)
154+
if err != nil {
155+
return nil, err
156+
}
157+
158+
return []*schema.ResourceData{d}, nil
159+
}

0 commit comments

Comments
 (0)