Skip to content

Commit 62e59d5

Browse files
committed
feat(github_graphql): introduce graphql client with shared auth and integrate into task flow
- added CreateGraphqlClient to encapsulate graphql client construction - reused CreateAuthenticatedHttpClient from github/tasks to inject token refresh via RoundTripper - replaced manual graphql client setup in PrepareTaskData with new factory function - preserved existing rate limit handling via getRateRemaining callback - preserved query cost calculation using SetGetRateCost Technical details: - graphql client now uses http transport with TokenProvider and RefreshRoundTripper - removes dependency on oauth2 client and avoids token expiration issues - decouples graphql client from REST ApiClient by avoiding reuse of apiClient.GetClient() - maintains compatibility with github.com and enterprise graphql endpoints Note: - shared auth logic remains in github/tasks and is imported with alias to avoid package name collision - introduces cross-plugin dependency (github_graphql → github/tasks) as a pragmatic tradeoff to avoid duplication
1 parent 6510b00 commit 62e59d5

2 files changed

Lines changed: 72 additions & 14 deletions

File tree

backend/plugins/github_graphql/impl/impl.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package impl
2020
import (
2121
"context"
2222
"fmt"
23-
"net/url"
2423
"reflect"
2524
"time"
2625

@@ -177,19 +176,9 @@ func (p GithubGraphql) PrepareTaskData(taskCtx plugin.TaskContext, options map[s
177176
return nil, err
178177
}
179178

180-
endpoint, err := errors.Convert01(url.Parse(connection.Endpoint))
181-
if err != nil {
182-
return nil, errors.BadInput.Wrap(err, fmt.Sprintf("malformed connection endpoint supplied: %s", connection.Endpoint))
183-
}
184-
// github.com and github enterprise have different graphql endpoints
185-
endpoint.Path = "/graphql" // see https://docs.github.com/en/graphql/guides/forming-calls-with-graphql
186-
if endpoint.Hostname() != "api.github.com" {
187-
// see https://docs.github.com/en/enterprise-server@3.11/graphql/guides/forming-calls-with-graphql
188-
endpoint.Path = "/api/graphql"
189-
}
190-
191-
client := graphql.NewClient(endpoint.String(), apiClient.GetClient())
192-
graphqlClient, err := helper.CreateAsyncGraphqlClient(taskCtx, client, taskCtx.GetLogger(),
179+
graphqlClient, err := tasks.CreateGraphqlClient(
180+
taskCtx,
181+
connection,
193182
func(ctx context.Context, client *graphql.Client, logger log.Logger) (rateRemaining int, resetAt *time.Time, err errors.Error) {
194183
var query GraphQueryRateLimit
195184
dataErrors, err := errors.Convert01(client.Query(taskCtx.GetContext(), &query, nil))
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package tasks
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"github.com/apache/incubator-devlake/core/log"
24+
"net/url"
25+
"time"
26+
27+
"github.com/apache/incubator-devlake/core/errors"
28+
"github.com/apache/incubator-devlake/core/plugin"
29+
helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
30+
"github.com/apache/incubator-devlake/plugins/github/models"
31+
githubTasks "github.com/apache/incubator-devlake/plugins/github/tasks"
32+
"github.com/merico-ai/graphql"
33+
)
34+
35+
func CreateGraphqlClient(
36+
taskCtx plugin.TaskContext,
37+
connection *models.GithubConnection,
38+
getRateRemaining func(context.Context, *graphql.Client, log.Logger) (rateRemaining int, resetAt *time.Time, err errors.Error),
39+
) (*helper.GraphqlAsyncClient, errors.Error) {
40+
41+
// inject the shared auth layer
42+
httpClient, err := githubTasks.CreateAuthenticatedHttpClient(taskCtx, connection, nil)
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
// Build endpoint
48+
endpoint, err := errors.Convert01(url.Parse(connection.Endpoint))
49+
if err != nil {
50+
return nil, errors.BadInput.Wrap(err, fmt.Sprintf("malformed connection endpoint supplied: %s", connection.Endpoint))
51+
}
52+
// github.com and github enterprise have different graphql endpoints
53+
if endpoint.Hostname() == "api.github.com" {
54+
// see https://docs.github.com/en/graphql/guides/forming-calls-with-graphql
55+
endpoint.Path = "/graphql"
56+
} else {
57+
// see https://docs.github.com/en/enterprise-server@3.11/graphql/guides/forming-calls-with-graphql
58+
endpoint.Path = "/api/graphql"
59+
}
60+
61+
gqlClient := graphql.NewClient(endpoint.String(), httpClient)
62+
63+
return helper.CreateAsyncGraphqlClient(
64+
taskCtx,
65+
gqlClient,
66+
taskCtx.GetLogger(),
67+
getRateRemaining,
68+
)
69+
}

0 commit comments

Comments
 (0)