Skip to content

Commit 39d017d

Browse files
committed
fix(github_graphql): reuse ApiClient transport for GraphQL to enable token refresh
Replace oauth2.StaticTokenSource-based HTTP client with the underlying http.Client from ApiAsyncClient. Previously, the GraphQL client constructed its own HTTP client using StaticTokenSource, which froze the access token at task start time. This caused GitHub App installation tokens (which expire after ~1 hour) to become invalid during long-running pipelines, leading to persistent 401 errors. Now, the GraphQL client reuses apiClient.GetClient(), which is already configured with RefreshRoundTripper and TokenProvider. This enables automatic token refresh on 401 responses, aligning GraphQL behavior with the REST client. Design decisions: - Reuse transport layer instead of duplicating authentication logic to ensure consistency across REST and GraphQL clients. - Avoid StaticTokenSource, as it prevents token refresh and breaks long-running pipelines. - Leverage existing RefreshRoundTripper for transparent token rotation without modifying GraphQL query logic. - Keep protocol-specific logic (GraphQL vs REST) separate while sharing the underlying HTTP transport. This ensures GraphQL pipelines using GitHub App authentication can run beyond token expiry without failure. Fixes #8788 (bug 2)
1 parent f1d24c1 commit 39d017d

1 file changed

Lines changed: 2 additions & 32 deletions

File tree

  • backend/plugins/github_graphql/impl

backend/plugins/github_graphql/impl/impl.go

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ package impl
2020
import (
2121
"context"
2222
"fmt"
23-
"net/http"
2423
"net/url"
2524
"reflect"
26-
"strings"
2725
"time"
2826

2927
"github.com/apache/incubator-devlake/core/models/domainlayer/devops"
@@ -39,7 +37,6 @@ import (
3937
"github.com/apache/incubator-devlake/plugins/github_graphql/model/migrationscripts"
4038
"github.com/apache/incubator-devlake/plugins/github_graphql/tasks"
4139
"github.com/merico-ai/graphql"
42-
"golang.org/x/oauth2"
4340
)
4441

4542
// make sure interface is implemented
@@ -180,45 +177,18 @@ func (p GithubGraphql) PrepareTaskData(taskCtx plugin.TaskContext, options map[s
180177
return nil, err
181178
}
182179

183-
tokens := strings.Split(connection.Token, ",")
184-
src := oauth2.StaticTokenSource(
185-
&oauth2.Token{AccessToken: tokens[0]},
186-
)
187-
oauthContext := taskCtx.GetContext()
188-
proxy := connection.GetProxy()
189-
if proxy != "" {
190-
pu, err := url.Parse(proxy)
191-
if err != nil {
192-
return nil, errors.Convert(err)
193-
}
194-
if pu.Scheme == "http" || pu.Scheme == "socks5" {
195-
proxyClient := &http.Client{
196-
Transport: &http.Transport{Proxy: http.ProxyURL(pu)},
197-
}
198-
oauthContext = context.WithValue(
199-
taskCtx.GetContext(),
200-
oauth2.HTTPClient,
201-
proxyClient,
202-
)
203-
logger.Debug("Proxy set in oauthContext to %s", proxy)
204-
} else {
205-
return nil, errors.BadInput.New("Unsupported scheme set in proxy")
206-
}
207-
}
208-
209-
httpClient := oauth2.NewClient(oauthContext, src)
210180
endpoint, err := errors.Convert01(url.Parse(connection.Endpoint))
211181
if err != nil {
212182
return nil, errors.BadInput.Wrap(err, fmt.Sprintf("malformed connection endpoint supplied: %s", connection.Endpoint))
213183
}
214-
215184
// github.com and github enterprise have different graphql endpoints
216185
endpoint.Path = "/graphql" // see https://docs.github.com/en/graphql/guides/forming-calls-with-graphql
217186
if endpoint.Hostname() != "api.github.com" {
218187
// see https://docs.github.com/en/enterprise-server@3.11/graphql/guides/forming-calls-with-graphql
219188
endpoint.Path = "/api/graphql"
220189
}
221-
client := graphql.NewClient(endpoint.String(), httpClient)
190+
191+
client := graphql.NewClient(endpoint.String(), apiClient.GetClient())
222192
graphqlClient, err := helper.CreateAsyncGraphqlClient(taskCtx, client, taskCtx.GetLogger(),
223193
func(ctx context.Context, client *graphql.Client, logger log.Logger) (rateRemaining int, resetAt *time.Time, err errors.Error) {
224194
var query GraphQueryRateLimit

0 commit comments

Comments
 (0)