@@ -3,21 +3,22 @@ package github
33import (
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
1314func 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,150 +61,187 @@ 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
76- repoName := d .Get ("repository" ).(string )
77- name := d .Get ("name" ).(string )
78- color := d .Get ("color" ).(string )
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
69+ repoName , ok := d .Get ("repository" ).(string )
70+ if ! ok {
71+ return diag .Errorf (`expected "repository" to be string` )
72+ }
73+ name , ok := d .Get ("name" ).(string )
74+ if ! ok {
75+ return diag .Errorf (`expected "name" to be string` )
76+ }
77+ color , ok := d .Get ("color" ).(string )
78+ if ! ok {
79+ return diag .Errorf (`expected "color" to be string` )
80+ }
7981
8082 label := & github.Label {
8183 Name : new (name ),
8284 Color : new (color ),
8385 }
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
86+
87+ if v , ok := d .GetOk ("description" ); ok {
88+ description , ok := v .(string )
89+ if ! ok {
90+ return diag .Errorf (`expected "description" to be string` )
9991 }
92+ label .Description = & description
10093 }
10194
102- existing , resp , err := client .Issues .GetLabel (ctx ,
103- orgName , repoName , originalName )
104- if err != nil && resp .StatusCode != http .StatusNotFound {
105- return err
95+ githubLabel , resp , err := client .Issues .CreateLabel (ctx , orgName , repoName , label )
96+ if err != nil {
97+ return diag .FromErr (err )
10698 }
107-
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- }
99+ id , err := buildID (repoName , name )
100+ if err != nil {
101+ return diag .FromErr (err )
102+ }
103+ d .SetId (id )
104+ if err := d .Set ("url" , githubLabel .GetURL ()); err != nil {
105+ return diag .FromErr (err )
139106 }
140107
141- d .SetId (buildTwoPartID (repoName , name ))
142-
143- return resourceGithubIssueLabelRead (d , meta )
108+ if err := d .Set ("etag" , resp .Header .Get ("ETag" )); err != nil {
109+ return diag .FromErr (err )
110+ }
111+ return nil
144112}
145113
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
114+ func resourceGithubIssueLabelRead (ctx context.Context , d * schema.ResourceData , m any ) diag.Diagnostics {
115+ meta , _ := m .(* Owner )
116+ client := meta .v3client
117+ repoName , ok := d .Get ("repository" ).(string )
118+ if ! ok {
119+ return diag .Errorf (`expected "repository" to be string` )
120+ }
121+ name , ok := d .Get ("name" ).(string )
122+ if ! ok {
123+ return diag .Errorf (`expected "name" to be string` )
151124 }
152125
153- orgName := meta .(* Owner ).name
154- ctx := context .WithValue (context .Background (), ctxId , d .Id ())
126+ orgName := meta .name
155127 if ! d .IsNewResource () {
156128 ctx = context .WithValue (ctx , ctxEtag , d .Get ("etag" ).(string ))
157129 }
158130
159- githubLabel , resp , err := client .Issues .GetLabel (ctx ,
160- orgName , repoName , name )
131+ githubLabel , resp , err := client .Issues .GetLabel (ctx , orgName , repoName , name )
161132 if err != nil {
162133 var ghErr * github.ErrorResponse
163134 if errors .As (err , & ghErr ) {
164135 if ghErr .Response .StatusCode == http .StatusNotModified {
165136 return nil
166137 }
167138 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 )
139+ 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 })
170140 d .SetId ("" )
171141 return nil
172142 }
173143 }
174- return err
144+ return diag . FromErr ( err )
175145 }
176146
177147 if err = d .Set ("etag" , resp .Header .Get ("ETag" )); err != nil {
178- return err
148+ return diag . FromErr ( err )
179149 }
180- if err = d .Set ("repository " , repoName ); err != nil {
181- return err
150+ if err = d .Set ("url " , githubLabel . GetURL () ); err != nil {
151+ return diag . FromErr ( err )
182152 }
183- if err = d .Set ("name" , name ); err != nil {
184- return err
153+
154+ return nil
155+ }
156+
157+ func resourceGithubIssueLabelUpdate (ctx context.Context , d * schema.ResourceData , m any ) diag.Diagnostics {
158+ meta , _ := m .(* Owner )
159+ client := meta .v3client
160+ orgName := meta .name
161+ repoName , ok := d .Get ("repository" ).(string )
162+ if ! ok {
163+ return diag .Errorf (`expected "repository" to be string` )
185164 }
186- if err = d .Set ("color" , githubLabel .GetColor ()); err != nil {
187- return err
165+ name , ok := d .Get ("name" ).(string )
166+ if ! ok {
167+ return diag .Errorf (`expected "name" to be string` )
188168 }
189- if err = d .Set ("description" , githubLabel .GetDescription ()); err != nil {
190- return err
169+ color , ok := d .Get ("color" ).(string )
170+ if ! ok {
171+ return diag .Errorf (`expected "color" to be string` )
191172 }
192- if err = d .Set ("url" , githubLabel .GetURL ()); err != nil {
193- return err
173+
174+ originalName := name
175+ if d .HasChange ("name" ) {
176+ oldName , _ := d .GetChange ("name" )
177+ oldNameString , ok := oldName .(string )
178+ if ! ok {
179+ return diag .Errorf (`expected old "name" to be string` )
180+ }
181+ originalName = oldNameString
182+ }
183+ label := & github.Label {
184+ Name : new (name ),
185+ Color : new (color ),
186+ }
187+ if v , ok := d .GetOk ("description" ); ok {
188+ description , ok := v .(string )
189+ if ! ok {
190+ return diag .Errorf (`expected "description" to be string` )
191+ }
192+ label .Description = & description
193+ }
194+ githubLabel , resp , err := client .Issues .EditLabel (ctx , orgName , repoName , originalName , label )
195+ if err != nil {
196+ return diag .FromErr (err )
197+ }
198+ id , err := buildID (repoName , name )
199+ if err != nil {
200+ return diag .FromErr (err )
201+ }
202+ d .SetId (id )
203+
204+ if err := d .Set ("url" , githubLabel .GetURL ()); err != nil {
205+ return diag .FromErr (err )
206+ }
207+
208+ if err := d .Set ("etag" , resp .Header .Get ("ETag" )); err != nil {
209+ return diag .FromErr (err )
194210 }
195211
196212 return nil
197213}
198214
199- func resourceGithubIssueLabelDelete (d * schema.ResourceData , meta any ) error {
200- client := meta .(* Owner ).v3client
201-
202- orgName := meta .(* Owner ).name
203- repoName := d .Get ("repository" ).(string )
204- name := d .Get ("name" ).(string )
205- ctx := context .WithValue (context .Background (), ctxId , d .Id ())
215+ func resourceGithubIssueLabelDelete (ctx context.Context , d * schema.ResourceData , m any ) diag.Diagnostics {
216+ meta , _ := m .(* Owner )
217+ client := meta .v3client
218+ orgName := meta .name
206219
220+ repoName , ok := d .Get ("repository" ).(string )
221+ if ! ok {
222+ return diag .Errorf (`expected "repository" to be string` )
223+ }
224+ name , ok := d .Get ("name" ).(string )
225+ if ! ok {
226+ return diag .Errorf (`expected "name" to be string` )
227+ }
207228 _ , err := client .Issues .DeleteLabel (ctx , orgName , repoName , name )
208- return handleArchivedRepoDelete (err , "issue label" , name , orgName , repoName )
229+ return diag .FromErr (handleArchivedRepoDelete (err , "issue label" , name , orgName , repoName ))
230+ }
231+
232+ func resourceGithubIssueLabelImport (_ context.Context , d * schema.ResourceData , _ any ) ([]* schema.ResourceData , error ) {
233+ repoName , name , err := parseID2 (d .Id ())
234+ if err != nil {
235+ return nil , err
236+ }
237+
238+ if err := d .Set ("repository" , repoName ); err != nil {
239+ return nil , err
240+ }
241+
242+ if err := d .Set ("name" , name ); err != nil {
243+ return nil , err
244+ }
245+
246+ return []* schema.ResourceData {d }, nil
209247}
0 commit comments