Handle the case when issue labels already exist

This fixes GH-13163
This commit is contained in:
Seth Vargo 2017-03-29 18:26:54 -04:00
parent 6ed873b72d
commit c44487caee
No known key found for this signature in database
GPG Key ID: C921994F9C27E0FF
2 changed files with 57 additions and 32 deletions

View File

@ -10,9 +10,9 @@ import (
func resourceGithubIssueLabel() *schema.Resource { func resourceGithubIssueLabel() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
Create: resourceGithubIssueLabelCreate, Create: resourceGithubIssueLabelCreateOrUpdate,
Read: resourceGithubIssueLabelRead, Read: resourceGithubIssueLabelRead,
Update: resourceGithubIssueLabelUpdate, Update: resourceGithubIssueLabelCreateOrUpdate,
Delete: resourceGithubIssueLabelDelete, Delete: resourceGithubIssueLabelDelete,
Importer: &schema.ResourceImporter{ Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough, State: schema.ImportStatePassthrough,
@ -40,22 +40,55 @@ 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 client := meta.(*Organization).client
o := meta.(*Organization).name
r := d.Get("repository").(string) r := d.Get("repository").(string)
n := d.Get("name").(string) n := d.Get("name").(string)
c := d.Get("color").(string) c := d.Get("color").(string)
label := github.Label{
label := &github.Label{
Name: &n, Name: &n,
Color: &c, Color: &c,
} }
log.Printf("[DEBUG] Creating label: %#v", label) log.Printf("[DEBUG] Querying label existence %s/%s (%s)", o, r, n)
_, resp, err := client.Issues.CreateLabel(context.TODO(), meta.(*Organization).name, r, &label) 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) log.Printf("[DEBUG] Response from creating label: %s", *resp)
if err != nil { if err != nil {
return err return err
} }
}
d.SetId(buildTwoPartID(&r, &n)) d.SetId(buildTwoPartID(&r, &n))
@ -66,6 +99,7 @@ func resourceGithubIssueLabelRead(d *schema.ResourceData, meta interface{}) erro
client := meta.(*Organization).client client := meta.(*Organization).client
r, n := parseTwoPartID(d.Id()) 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) githubLabel, _, err := client.Issues.GetLabel(context.TODO(), meta.(*Organization).name, r, n)
if err != nil { if err != nil {
d.SetId("") d.SetId("")
@ -80,31 +114,12 @@ func resourceGithubIssueLabelRead(d *schema.ResourceData, meta interface{}) erro
return nil 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 { func resourceGithubIssueLabelDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client client := meta.(*Organization).client
r := d.Get("repository").(string) r := d.Get("repository").(string)
n := d.Get("name").(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) _, err := client.Issues.DeleteLabel(context.TODO(), meta.(*Organization).name, r, n)
return err return err
} }

View File

@ -6,16 +6,24 @@ description: |-
Provides a GitHub issue label resource. Provides a GitHub issue label resource.
--- ---
# github\_issue_label # github_issue_label
Provides a GitHub issue label resource. Provides a GitHub issue label resource.
This resource allows you to create and manage issue labels within your This resource allows you to create and manage issue labels within your
Github organization. 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 ## Example Usage
``` ```hcl
# Create a new, red colored label # Create a new, red colored label
resource "github_issue_label" "test_repo" { resource "github_issue_label" "test_repo" {
repository = "test-repo" repository = "test-repo"
@ -29,5 +37,7 @@ resource "github_issue_label" "test_repo" {
The following arguments are supported: The following arguments are supported:
* `repository` - (Required) The GitHub repository * `repository` - (Required) The GitHub repository
* `name` - (Required) The name of the label. * `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.