Skip to content

Commit ded4e69

Browse files
committed
fixup! feat: Add new gh client implementation
1 parent c83856a commit ded4e69

8 files changed

Lines changed: 69 additions & 73 deletions

docs/index.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,19 @@ provider "github" {
121121

122122
- `app_auth` (Block List, Max: 1) Authenticate using a GitHub App. (see [below for nested schema](#nestedblock--app_auth))
123123
- `base_url` (String) The base URL for the GitHub API; this defaults to the GitHub API URL. If you are using GitHub Enterprise Server (GHES) or GitHub Enterprise Cloud with Data Residency (GHEC-DR), this is required. This can also be set by the `GITHUB_BASE_URL` environment variable.
124-
- `insecure` (Boolean) Allow insecure server connections when using SSL.
124+
- `cache_path` (String) The path to the cache directory for persisting GitHub API requests between runs; if not set there will be no caching between runs. This can also be set by the `GITHUB_CACHE_PATH` environment variable.
125+
- `insecure` (Boolean, Deprecated) Allow insecure server connections when using SSL.
126+
- `legacy_client` (Boolean) Use the legacy GitHub client implementation; if set to `false`, the new client implementation is used. This can also be set by the `GITHUB_LEGACY_CLIENT` environment variable.
125127
- `max_per_page` (Number) The maximum number of results per page for paginated API requests; this defaults to `100`. This can also be set by the `GITHUB_MAX_PER_PAGE` environment variable.
126128
- `max_retries` (Number) The maximum number of retries for failed requests; this defaults to `3`.
127129
- `organization` (String, Deprecated) GitHub organization to manage. This can also be set by the `GITHUB_ORGANIZATION` environment variable.
128130
- `owner` (String) GitHub organization or user account to manage; this is required when authenticating using a GitHub App. If the owner is not provided and a token is provided, the provider will attempt to auto-detect the owner associated with the token. This can also be set by the `GITHUB_OWNER` environment variable.
129-
- `parallel_requests` (Boolean) Allow the provider to make parallel API calls; this is experimental and may cause concurrency and rate limiting issues.
130-
- `read_delay_ms` (Number) The delay in milliseconds between read operations; this defaults to `0`. This can be used to mitigate rate limiting issues when performing a large number of read operations.
131+
- `parallel_requests` (Boolean) Allow the provider to make parallel API calls; this is experimental and may cause concurrency and rate limiting issues. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is designed to safely handle parallel requests.
132+
- `read_delay_ms` (Number) The delay in milliseconds between read operations; this defaults to `0`. This can be used to mitigate rate limiting issues when performing a large number of read operations. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is GitHub rate limit aware.
131133
- `retry_delay_ms` (Number) The delay in milliseconds between retry attempts; this defaults to `1000`. This setting only applies when `max_retries` is greater than `0`.
132-
- `retryable_errors` (List of Number) List of HTTP status codes that should be retried; if not set this uses the provider defaults. This setting only applies when `max_retries` is greater than `0`.
134+
- `retryable_errors` (List of Number) List of HTTP status codes that should be retried; if not set this uses the provider defaults. This setting only applies when `max_retries` is greater than `0`. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation handles the retry logic.
133135
- `token` (String) GitHub OAuth or Personal Access Token (PAT) to use for authentication. This can also be set by the `GITHUB_TOKEN` environment variable.
134-
- `write_delay_ms` (Number) The delay in milliseconds between write operations; this defaults to `1000`. This is used to mitigate the GitHub API's abuse rate limits when writing. Note that **ALL** requests to the GraphQL API are implemented as `POST` requests under the hood, so this setting affects those calls as well.
136+
- `write_delay_ms` (Number) The delay in milliseconds between write operations; this defaults to `1000`. This is used to mitigate the GitHub API's abuse rate limits when writing. Note that **ALL** requests to the GraphQL API are implemented as `POST` requests under the hood, so this setting affects those calls as well. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is GitHub rate limit aware.
135137

136138
<a id="nestedblock--app_auth"></a>
137139
### Nested Schema for `app_auth`

github/config.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ import (
1616
)
1717

1818
type Config struct {
19-
LegacyClient bool
19+
AppID *string
20+
AppInstallationID *string
21+
AppPEM []byte
2022
BaseURL *url.URL
21-
RESTAPIPath string
23+
CachePath *string
2224
GraphQLAPIPath string
25+
Insecure bool
26+
LegacyClient bool
27+
MaxRetries int
2328
Owner string
24-
AppID *string
25-
AppPEM []byte
26-
AppInstallationID *string
27-
Token string
29+
ParallelRequests bool
2830
ReadDelay time.Duration
29-
WriteDelay time.Duration
30-
RetryDelay time.Duration
31+
RESTAPIPath string
3132
RetryableErrors map[int]bool
32-
MaxRetries int
33-
ParallelRequests bool
34-
Insecure bool
35-
CachePath *string
33+
RetryDelay time.Duration
34+
Token string
35+
WriteDelay time.Duration
3636
}
3737

3838
type Owner struct {

github/data_source_github_branch_protection_rules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func dataSourceGithubBranchProtectionRulesRead(ctx context.Context, d *schema.Re
5858

5959
var rules []any
6060
for {
61-
err := client.Query(meta.(*Owner).StopContext, &query, variables)
61+
err := client.Query(ctx, &query, variables)
6262
if err != nil {
6363
return diag.FromErr(err)
6464
}

github/data_source_github_ip_ranges.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ func dataSourceGithubIpRanges() *schema.Resource {
198198
func dataSourceGithubIpRangesRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
199199
owner := meta.(*Owner)
200200

201-
api, _, err := owner.v3client.Meta.Get(owner.StopContext)
201+
api, _, err := owner.v3client.Meta.Get(ctx)
202202
if err != nil {
203203
return diag.FromErr(err)
204204
}

github/data_source_github_organization_teams.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,12 @@ func dataSourceGithubOrganizationTeamsRead(ctx context.Context, d *schema.Resour
117117

118118
var teams []any
119119
for {
120-
err = client.Query(meta.(*Owner).StopContext, &query, variables)
120+
err = client.Query(ctx, &query, variables)
121121
if err != nil {
122122
return diag.FromErr(err)
123123
}
124124

125-
additionalTeams, err := flattenGitHubTeams(clientv3, meta.(*Owner).StopContext, orgName, query)
125+
additionalTeams, err := flattenGitHubTeams(clientv3, ctx, orgName, query)
126126
if err != nil {
127127
return diag.FromErr(err)
128128
}

github/data_source_github_ssh_keys.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func dataSourceGithubSshKeys() *schema.Resource {
2424
func dataSourceGithubSshKeysRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
2525
owner := meta.(*Owner)
2626

27-
api, _, err := owner.v3client.Meta.Get(owner.StopContext)
27+
api, _, err := owner.v3client.Meta.Get(ctx)
2828
if err != nil {
2929
return diag.FromErr(err)
3030
}

github/data_source_github_user_external_identity.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func dataSourceGithubUserExternalIdentityRead(ctx context.Context, d *schema.Res
5959
"username": githubv4.String(username),
6060
}
6161

62-
err := client.Query(meta.(*Owner).StopContext, &query, variables)
62+
err := client.Query(ctx, &query, variables)
6363
if err != nil {
6464
return diag.FromErr(err)
6565
}

github/provider.go

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/hashicorp/terraform-plugin-log/tflog"
1414
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1515
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
16+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1617

1718
"github.com/integrations/terraform-provider-github/v6/internal/ghclient"
1819
)
@@ -82,22 +83,25 @@ func NewProvider() func() *schema.Provider {
8283
},
8384
},
8485
"read_delay_ms": {
85-
Type: schema.TypeInt,
86-
Optional: true,
87-
Default: 0,
88-
Description: "The delay in milliseconds between read operations; this defaults to `0`. This can be used to mitigate rate limiting issues when performing a large number of read operations. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is GitHub rate limit aware.",
86+
Type: schema.TypeInt,
87+
Optional: true,
88+
Default: 0,
89+
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)),
90+
Description: "The delay in milliseconds between read operations; this defaults to `0`. This can be used to mitigate rate limiting issues when performing a large number of read operations. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is GitHub rate limit aware.",
8991
},
9092
"write_delay_ms": {
91-
Type: schema.TypeInt,
92-
Optional: true,
93-
Default: 1000,
94-
Description: "The delay in milliseconds between write operations; this defaults to `1000`. This is used to mitigate the GitHub API's abuse rate limits when writing. Note that **ALL** requests to the GraphQL API are implemented as `POST` requests under the hood, so this setting affects those calls as well. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is GitHub rate limit aware.",
93+
Type: schema.TypeInt,
94+
Optional: true,
95+
Default: 1000,
96+
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)),
97+
Description: "The delay in milliseconds between write operations; this defaults to `1000`. This is used to mitigate the GitHub API's abuse rate limits when writing. Note that **ALL** requests to the GraphQL API are implemented as `POST` requests under the hood, so this setting affects those calls as well. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation is GitHub rate limit aware.",
9598
},
9699
"retry_delay_ms": {
97-
Type: schema.TypeInt,
98-
Optional: true,
99-
Default: 1000,
100-
Description: "The delay in milliseconds between retry attempts; this defaults to `1000`. This setting only applies when `max_retries` is greater than `0`.",
100+
Type: schema.TypeInt,
101+
Optional: true,
102+
Default: 1000,
103+
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)),
104+
Description: "The delay in milliseconds between retry attempts; this defaults to `1000`. This setting only applies when `max_retries` is greater than `0`.",
101105
},
102106
"retryable_errors": {
103107
Type: schema.TypeList,
@@ -106,16 +110,18 @@ func NewProvider() func() *schema.Provider {
106110
Description: "List of HTTP status codes that should be retried; if not set this uses the provider defaults. This setting only applies when `max_retries` is greater than `0`. This is ignored for the REST API when `legacy_client` is `false` since the new client implementation handles the retry logic.",
107111
},
108112
"max_retries": {
109-
Type: schema.TypeInt,
110-
Optional: true,
111-
Default: 3,
112-
Description: "The maximum number of retries for failed requests; this defaults to `3`.",
113+
Type: schema.TypeInt,
114+
Optional: true,
115+
Default: 3,
116+
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)),
117+
Description: "The maximum number of retries for failed requests; this defaults to `3`.",
113118
},
114119
"max_per_page": {
115-
Type: schema.TypeInt,
116-
Optional: true,
117-
DefaultFunc: schema.EnvDefaultFunc("GITHUB_MAX_PER_PAGE", 100),
118-
Description: "The maximum number of results per page for paginated API requests; this defaults to `100`. This can also be set by the `GITHUB_MAX_PER_PAGE` environment variable.",
120+
Type: schema.TypeInt,
121+
Optional: true,
122+
DefaultFunc: schema.EnvDefaultFunc("GITHUB_MAX_PER_PAGE", 100),
123+
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(1)),
124+
Description: "The maximum number of results per page for paginated API requests; this defaults to `100`. This can also be set by the `GITHUB_MAX_PER_PAGE` environment variable.",
119125
},
120126
"parallel_requests": {
121127
Type: schema.TypeBool,
@@ -322,10 +328,15 @@ func NewProvider() func() *schema.Provider {
322328
func configureProvider() func(context.Context, *schema.ResourceData) (any, diag.Diagnostics) {
323329
return func(ctx context.Context, d *schema.ResourceData) (any, diag.Diagnostics) {
324330
config := &Config{
325-
LegacyClient: d.Get("legacy_client").(bool),
326331
GraphQLAPIPath: "graphql",
327332
}
328333

334+
if v, ok := d.GetOk("legacy_client"); ok {
335+
if b, ok := v.(bool); ok {
336+
config.LegacyClient = b
337+
}
338+
}
339+
329340
if v, ok := d.GetOk("base_url"); ok {
330341
if s, ok := v.(string); ok && s != "" {
331342
baseURL, isGHES, err := getBaseURL(s)
@@ -382,7 +393,7 @@ func configureProvider() func(context.Context, *schema.ResourceData) (any, diag.
382393

383394
if v, ok := d.GetOk("token"); ok {
384395
if s, ok := v.(string); ok && s != "" {
385-
tflog.Info(ctx, "Using token from provider configuration.", map[string]any{"token": "****"})
396+
tflog.Info(ctx, "Using token from provider configuration.")
386397
config.Token = s
387398
}
388399
}
@@ -409,32 +420,20 @@ func configureProvider() func(context.Context, *schema.ResourceData) (any, diag.
409420

410421
if v, ok := d.GetOk("read_delay_ms"); ok {
411422
if i, ok := v.(int); ok {
412-
if i < 0 {
413-
return nil, diag.Errorf("read_delay_ms must be greater than or equal to 0")
414-
}
415-
416423
tflog.Info(ctx, "Using read delay from provider configuration.", map[string]any{"read_delay_ms": i})
417424
config.ReadDelay = time.Duration(i) * time.Millisecond
418425
}
419426
}
420427

421428
if v, ok := d.GetOk("write_delay_ms"); ok {
422429
if i, ok := v.(int); ok {
423-
if i <= 0 {
424-
return nil, diag.Errorf("write_delay_ms must be greater than 0")
425-
}
426-
427430
tflog.Info(ctx, "Using write delay from provider configuration.", map[string]any{"write_delay_ms": i})
428431
config.WriteDelay = time.Duration(i) * time.Millisecond
429432
}
430433
}
431434

432435
if v, ok := d.GetOk("retry_delay_ms"); ok {
433436
if i, ok := v.(int); ok {
434-
if i < 0 {
435-
return nil, diag.Errorf("retry_delay_ms must be greater than or equal to 0")
436-
}
437-
438437
tflog.Info(ctx, "Using retry delay from provider configuration.", map[string]any{"retry_delay_ms": i})
439438
config.RetryDelay = time.Duration(i) * time.Millisecond
440439
}
@@ -462,35 +461,31 @@ func configureProvider() func(context.Context, *schema.ResourceData) (any, diag.
462461

463462
if v, ok := d.GetOk("max_retries"); ok {
464463
if i, ok := v.(int); ok {
465-
if i < 0 {
466-
return nil, diag.Errorf("max_retries must be greater than or equal to 0")
467-
}
468-
469464
tflog.Info(ctx, "Using max retries from provider configuration.", map[string]any{"max_retries": i})
470465
config.MaxRetries = i
471466
}
472467
}
473468

474469
if v, ok := d.GetOk("max_per_page"); ok {
475470
if i, ok := v.(int); ok {
476-
if i <= 0 {
477-
return nil, diag.Errorf("max_per_page must be greater than 0")
478-
}
479-
480471
tflog.Info(ctx, "Using max per page from provider configuration.", map[string]any{"max_per_page": i})
481472
// TODO: Move max per page to the provider metadata and remove the global variable.
482473
maxPerPage = i
483474
}
484475
}
485476

486-
if d.Get("parallel_requests").(bool) {
487-
tflog.Warn(ctx, "Parallel requests are enabled; this may cause concurrency and rate limiting issues.")
488-
config.ParallelRequests = true
477+
if v, ok := d.GetOk("parallel_requests"); ok {
478+
if b, ok := v.(bool); ok && b {
479+
tflog.Warn(ctx, "Parallel requests are enabled; this may cause concurrency and rate limiting issues.")
480+
config.ParallelRequests = true
481+
}
489482
}
490483

491-
if d.Get("insecure").(bool) {
492-
tflog.Warn(ctx, "Insecure mode enabled; SSL certificate verification is disabled. This is not recommended for production environments.")
493-
config.Insecure = true
484+
if v, ok := d.GetOk("insecure"); ok {
485+
if b, ok := v.(bool); ok && b {
486+
tflog.Warn(ctx, "Insecure mode enabled; SSL certificate verification is disabled. This is not recommended for production environments.")
487+
config.Insecure = true
488+
}
494489
}
495490

496491
if v, ok := d.GetOk("cache_path"); ok {
@@ -512,8 +507,7 @@ func configureProvider() func(context.Context, *schema.ResourceData) (any, diag.
512507
// configureProviderMeta initializes the provider metadata, including setting up the GitHub API clients based on the provided configuration. It returns the initialized metadata or an error if the configuration is invalid or if there are issues initializing the clients.
513508
func configureProviderMeta(ctx context.Context, c *Config) (any, error) {
514509
owner := &Owner{
515-
name: c.Owner,
516-
StopContext: context.Background(),
510+
name: c.Owner,
517511
}
518512

519513
if c.LegacyClient {

0 commit comments

Comments
 (0)