Skip to content

Commit 88958c6

Browse files
committed
refactor: migrate resource_github_issue_label to context-aware CRUD and tflog
1 parent 9870fc6 commit 88958c6

1 file changed

Lines changed: 100 additions & 103 deletions

File tree

github/resource_github_issue_label.go

Lines changed: 100 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@ package github
33
import (
44
"context"
55
"errors"
6-
"log"
76
"net/http"
87

98
"github.com/google/go-github/v88/github"
9+
"github.com/hashicorp/terraform-plugin-log/tflog"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
)
1213

1314
func resourceGithubIssueLabel() *schema.Resource {
1415
return &schema.Resource{
15-
Create: resourceGithubIssueLabelCreateOrUpdate,
16-
Read: resourceGithubIssueLabelRead,
17-
Update: resourceGithubIssueLabelCreateOrUpdate,
18-
Delete: resourceGithubIssueLabelDelete,
16+
CreateContext: resourceGithubIssueLabelCreate,
17+
ReadContext: resourceGithubIssueLabelRead,
18+
UpdateContext: resourceGithubIssueLabelUpdate,
19+
DeleteContext: resourceGithubIssueLabelDelete,
1920
Importer: &schema.ResourceImporter{
20-
StateContext: schema.ImportStatePassthroughContext,
21+
StateContext: resourceGithubIssueLabelImport,
2122
},
2223

2324
Schema: map[string]*schema.Schema{
@@ -60,19 +61,11 @@ func resourceGithubIssueLabel() *schema.Resource {
6061
}
6162
}
6263

63-
// resourceGithubIssueLabelCreateOrUpdate idempotently creates or updates an
64-
// issue label. Issue labels are keyed off of their "name", so pre-existing
65-
// issue labels result in a 422 HTTP error if they exist outside of Terraform.
66-
// Normally this would not be an issue, except new repositories are created with
67-
// a "default" set of labels, and those labels easily conflict with custom ones.
68-
//
69-
// This function will first check if the label exists, and then issue an update,
70-
// otherwise it will create. This is also advantageous in that we get to use the
71-
// same function for two schema funcs.
72-
73-
func resourceGithubIssueLabelCreateOrUpdate(d *schema.ResourceData, meta any) error {
74-
client := meta.(*Owner).v3client
75-
orgName := meta.(*Owner).name
64+
// resourceGithubIssueLabelCreate creates an issue label.
65+
func resourceGithubIssueLabelCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
66+
meta := m.(*Owner)
67+
client := meta.v3client
68+
orgName := meta.name
7669
repoName := d.Get("repository").(string)
7770
name := d.Get("name").(string)
7871
color := d.Get("color").(string)
@@ -81,129 +74,133 @@ func resourceGithubIssueLabelCreateOrUpdate(d *schema.ResourceData, meta any) er
8174
Name: new(name),
8275
Color: new(color),
8376
}
84-
ctx := context.Background()
85-
if !d.IsNewResource() {
86-
ctx = context.WithValue(ctx, ctxId, d.Id())
87-
}
88-
89-
// Pull out the original name. If we already have a resource, this is the
90-
// parsed ID. If not, it's the value given to the resource.
91-
var originalName string
92-
if d.Id() == "" {
93-
originalName = name
94-
} else {
95-
var err error
96-
_, originalName, err = parseID2(d.Id())
97-
if err != nil {
98-
return err
99-
}
100-
}
10177

102-
existing, resp, err := client.Issues.GetLabel(ctx,
103-
orgName, repoName, originalName)
104-
if err != nil && resp.StatusCode != http.StatusNotFound {
105-
return err
78+
if v, ok := d.GetOk("description"); ok {
79+
label.Description = new(v.(string))
10680
}
10781

108-
if existing != nil {
109-
label.Description = new(d.Get("description").(string))
110-
111-
// Pull out the original name. If we already have a resource, this is the
112-
// parsed ID. If not, it's the value given to the resource.
113-
var originalName string
114-
if d.Id() == "" {
115-
originalName = name
116-
} else {
117-
var err error
118-
_, originalName, err = parseID2(d.Id())
119-
if err != nil {
120-
return err
121-
}
122-
}
123-
124-
_, _, err := client.Issues.EditLabel(ctx,
125-
orgName, repoName, originalName, label)
126-
if err != nil {
127-
return err
128-
}
129-
} else {
130-
if v, ok := d.GetOk("description"); ok {
131-
label.Description = new(v.(string))
132-
}
133-
134-
_, _, err := client.Issues.CreateLabel(ctx,
135-
orgName, repoName, label)
136-
if err != nil {
137-
return err
138-
}
82+
githubLabel, resp, err := client.Issues.CreateLabel(ctx, orgName, repoName, label)
83+
if err != nil {
84+
return diag.FromErr(err)
85+
}
86+
id, err := buildID(repoName, name)
87+
if err != nil {
88+
return diag.FromErr(err)
89+
}
90+
d.SetId(id)
91+
if err := d.Set("url", githubLabel.GetURL()); err != nil {
92+
return diag.FromErr(err)
13993
}
14094

141-
d.SetId(buildTwoPartID(repoName, name))
142-
143-
return resourceGithubIssueLabelRead(d, meta)
95+
if err := d.Set("etag", resp.Header.Get("ETag")); err != nil {
96+
return diag.FromErr(err)
97+
}
98+
return nil
14499
}
145100

146-
func resourceGithubIssueLabelRead(d *schema.ResourceData, meta any) error {
147-
client := meta.(*Owner).v3client
148-
repoName, name, err := parseID2(d.Id())
149-
if err != nil {
150-
return err
151-
}
101+
func resourceGithubIssueLabelRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
102+
meta := m.(*Owner)
103+
client := meta.v3client
104+
repoName := d.Get("repository").(string)
105+
name := d.Get("name").(string)
152106

153-
orgName := meta.(*Owner).name
154-
ctx := context.WithValue(context.Background(), ctxId, d.Id())
107+
orgName := meta.name
155108
if !d.IsNewResource() {
156109
ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string))
157110
}
158111

159-
githubLabel, resp, err := client.Issues.GetLabel(ctx,
160-
orgName, repoName, name)
112+
githubLabel, resp, err := client.Issues.GetLabel(ctx, orgName, repoName, name)
161113
if err != nil {
162114
var ghErr *github.ErrorResponse
163115
if errors.As(err, &ghErr) {
164116
if ghErr.Response.StatusCode == http.StatusNotModified {
165117
return nil
166118
}
167119
if ghErr.Response.StatusCode == http.StatusNotFound {
168-
log.Printf("[INFO] Removing label %s (%s/%s) from state because it no longer exists in GitHub",
169-
name, orgName, repoName)
120+
tflog.Info(ctx, "Removing label from state because it no longer exists in GitHub", map[string]any{"name": name, "org_name": orgName, "repo_name": repoName})
170121
d.SetId("")
171122
return nil
172123
}
173124
}
174-
return err
125+
return diag.FromErr(err)
175126
}
176127

177128
if err = d.Set("etag", resp.Header.Get("ETag")); err != nil {
178-
return err
129+
return diag.FromErr(err)
179130
}
180-
if err = d.Set("repository", repoName); err != nil {
181-
return err
131+
if err = d.Set("url", githubLabel.GetURL()); err != nil {
132+
return diag.FromErr(err)
182133
}
183-
if err = d.Set("name", name); err != nil {
184-
return err
134+
135+
return nil
136+
}
137+
138+
func resourceGithubIssueLabelUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
139+
meta := m.(*Owner)
140+
client := meta.v3client
141+
orgName := meta.name
142+
repoName := d.Get("repository").(string)
143+
name := d.Get("name").(string)
144+
color := d.Get("color").(string)
145+
146+
originalName := name
147+
if d.HasChange("name") {
148+
oldName, _ := d.GetChange("name")
149+
originalName = oldName.(string)
185150
}
186-
if err = d.Set("color", githubLabel.GetColor()); err != nil {
187-
return err
151+
label := &github.Label{
152+
Name: new(name),
153+
Color: new(color),
188154
}
189-
if err = d.Set("description", githubLabel.GetDescription()); err != nil {
190-
return err
155+
if v, ok := d.GetOk("description"); ok {
156+
label.Description = new(v.(string))
191157
}
192-
if err = d.Set("url", githubLabel.GetURL()); err != nil {
193-
return err
158+
githubLabel, resp, err := client.Issues.EditLabel(ctx, orgName, repoName, originalName, label)
159+
if err != nil {
160+
return diag.FromErr(err)
161+
}
162+
id, err := buildID(repoName, name)
163+
if err != nil {
164+
return diag.FromErr(err)
165+
}
166+
d.SetId(id)
167+
168+
if err := d.Set("url", githubLabel.GetURL()); err != nil {
169+
return diag.FromErr(err)
170+
}
171+
172+
if err := d.Set("etag", resp.Header.Get("ETag")); err != nil {
173+
return diag.FromErr(err)
194174
}
195175

196176
return nil
197177
}
198178

199-
func resourceGithubIssueLabelDelete(d *schema.ResourceData, meta any) error {
200-
client := meta.(*Owner).v3client
179+
func resourceGithubIssueLabelDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
180+
meta := m.(*Owner)
181+
client := meta.v3client
201182

202-
orgName := meta.(*Owner).name
183+
orgName := meta.name
203184
repoName := d.Get("repository").(string)
204185
name := d.Get("name").(string)
205-
ctx := context.WithValue(context.Background(), ctxId, d.Id())
206186

207187
_, err := client.Issues.DeleteLabel(ctx, orgName, repoName, name)
208-
return handleArchivedRepoDelete(err, "issue label", name, orgName, repoName)
188+
return diag.FromErr(handleArchivedRepoDelete(err, "issue label", name, orgName, repoName))
189+
}
190+
191+
func resourceGithubIssueLabelImport(_ context.Context, d *schema.ResourceData, _ any) ([]*schema.ResourceData, error) {
192+
repoName, name, err := parseID2(d.Id())
193+
if err != nil {
194+
return nil, err
195+
}
196+
197+
if err := d.Set("repository", repoName); err != nil {
198+
return nil, err
199+
}
200+
201+
if err := d.Set("name", name); err != nil {
202+
return nil, err
203+
}
204+
205+
return []*schema.ResourceData{d}, nil
209206
}

0 commit comments

Comments
 (0)