Merge pull request #13182 from hashicorp/sethvargo/create_or_update

Handle the case when issue labels already exist
This commit is contained in:
Seth Vargo 2017-03-31 16:38:51 -04:00 committed by GitHub
commit e1be539868
3 changed files with 77 additions and 32 deletions

View File

@ -10,9 +10,9 @@ import (
func resourceGithubIssueLabel() *schema.Resource {
return &schema.Resource{
Create: resourceGithubIssueLabelCreate,
Create: resourceGithubIssueLabelCreateOrUpdate,
Read: resourceGithubIssueLabelRead,
Update: resourceGithubIssueLabelUpdate,
Update: resourceGithubIssueLabelCreateOrUpdate,
Delete: resourceGithubIssueLabelDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
@ -40,21 +40,54 @@ func resourceGithubIssueLabel() *schema.Resource {
}
}
func resourceGithubIssueLabelCreate(d *schema.ResourceData, meta interface{}) error {
// resourceGithubIssueLabelCreateOrUpdate idempotently creates or updates an
// issue label. Issue labels are keyed off of their "name", so pre-existing
// issue labels result in a 422 HTTP error if they exist outside of Terraform.
// Normally this would not be an issue, except new repositories are created with
// a "default" set of labels, and those labels easily conflict with custom ones.
//
// This function will first check if the label exists, and then issue an update,
// otherwise it will create. This is also advantageous in that we get to use the
// same function for two schema funcs.
func resourceGithubIssueLabelCreateOrUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
o := meta.(*Organization).name
r := d.Get("repository").(string)
n := d.Get("name").(string)
c := d.Get("color").(string)
label := github.Label{
label := &github.Label{
Name: &n,
Color: &c,
}
log.Printf("[DEBUG] Creating label: %#v", label)
_, resp, err := client.Issues.CreateLabel(context.TODO(), meta.(*Organization).name, r, &label)
log.Printf("[DEBUG] Response from creating label: %s", *resp)
if err != nil {
return err
log.Printf("[DEBUG] Querying label existence %s/%s (%s)", o, r, n)
existing, _, _ := client.Issues.GetLabel(context.TODO(), o, r, n)
if existing != nil {
log.Printf("[DEBUG] Updating label: %s/%s (%s: %s)", o, r, n, c)
// Pull out the original name. If we already have a resource, this is the
// parsed ID. If not, it's the value given to the resource.
var oname string
if d.Id() == "" {
oname = n
} else {
_, oname = parseTwoPartID(d.Id())
}
_, _, err := client.Issues.EditLabel(context.TODO(), o, r, oname, label)
if err != nil {
return err
}
} else {
log.Printf("[DEBUG] Creating label: %s/%s (%s: %s)", o, r, n, c)
_, resp, err := client.Issues.CreateLabel(context.TODO(), o, r, label)
log.Printf("[DEBUG] Response from creating label: %s", *resp)
if err != nil {
return err
}
}
d.SetId(buildTwoPartID(&r, &n))
@ -66,6 +99,7 @@ func resourceGithubIssueLabelRead(d *schema.ResourceData, meta interface{}) erro
client := meta.(*Organization).client
r, n := parseTwoPartID(d.Id())
log.Printf("[DEBUG] Reading label: %s/%s", r, n)
githubLabel, _, err := client.Issues.GetLabel(context.TODO(), meta.(*Organization).name, r, n)
if err != nil {
d.SetId("")
@ -80,31 +114,12 @@ func resourceGithubIssueLabelRead(d *schema.ResourceData, meta interface{}) erro
return nil
}
func resourceGithubIssueLabelUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r := d.Get("repository").(string)
n := d.Get("name").(string)
c := d.Get("color").(string)
_, originalName := parseTwoPartID(d.Id())
_, _, err := client.Issues.EditLabel(context.TODO(), meta.(*Organization).name, r, originalName, &github.Label{
Name: &n,
Color: &c,
})
if err != nil {
return err
}
d.SetId(buildTwoPartID(&r, &n))
return resourceGithubIssueLabelRead(d, meta)
}
func resourceGithubIssueLabelDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r := d.Get("repository").(string)
n := d.Get("name").(string)
log.Printf("[DEBUG] Deleting label: %s/%s", r, n)
_, err := client.Issues.DeleteLabel(context.TODO(), meta.(*Organization).name, r, n)
return err
}

View File

@ -32,6 +32,13 @@ func TestAccGithubIssueLabel_basic(t *testing.T) {
testAccCheckGithubIssueLabelAttributes(&label, "bar", "FFFFFF"),
),
},
{
Config: testAccGitHubIssueLabelExistsConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubIssueLabelExists("github_issue_label.test", &label),
testAccCheckGithubIssueLabelAttributes(&label, "enhancement", "FF00FF"),
),
},
},
})
}
@ -134,3 +141,16 @@ resource "github_issue_label" "test" {
color = "FFFFFF"
}
`, testRepo)
var testAccGitHubIssueLabelExistsConfig string = fmt.Sprintf(`
// Create a repository which has the default labels
resource "github_repository" "test" {
name = "tf-acc-repo-label-abc1234"
}
resource "github_issue_label" "test" {
repository = "${github_repository.test.name}"
name = "enhancement" // Important! This is a pre-created label
color = "FF00FF"
}
`)

View File

@ -6,16 +6,24 @@ description: |-
Provides a GitHub issue label resource.
---
# github\_issue_label
# github_issue_label
Provides a GitHub issue label resource.
This resource allows you to create and manage issue labels within your
Github organization.
Issue labels are keyed off of their "name", so pre-existing issue labels result
in a 422 HTTP error if they exist outside of Terraform. Normally this would not
be an issue, except new repositories are created with a "default" set of labels,
and those labels easily conflict with custom ones.
This resource will first check if the label exists, and then issue an update,
otherwise it will create.
## Example Usage
```
```hcl
# Create a new, red colored label
resource "github_issue_label" "test_repo" {
repository = "test-repo"
@ -29,5 +37,7 @@ resource "github_issue_label" "test_repo" {
The following arguments are supported:
* `repository` - (Required) The GitHub repository
* `name` - (Required) The name of the label.
* `color` - (Required) A 6 character hex code, without the leading #, identifying the color of the label.
* `color` - (Required) A 6 character hex code, **without the leading #**, identifying the color of the label.