in backend/plugins/github_graphql/impl/impl.go [154:268]
func (p GithubGraphql) PrepareTaskData(taskCtx plugin.TaskContext, options map[string]interface{}) (interface{}, errors.Error) {
logger := taskCtx.GetLogger()
logger.Debug("%v", options)
var op githubTasks.GithubOptions
err := helper.Decode(options, &op, nil)
if err != nil {
return nil, err
}
connectionHelper := helper.NewConnectionHelper(
taskCtx,
nil,
p.Name(),
)
connection := &models.GithubConnection{}
err = connectionHelper.FirstById(connection, op.ConnectionId)
if err != nil {
return nil, errors.Default.Wrap(err, "unable to get github connection by the given connection ID: %v")
}
apiClient, err := githubTasks.CreateApiClient(taskCtx, connection)
if err != nil {
return nil, errors.Default.Wrap(err, "unable to get github API client instance")
}
err = githubImpl.EnrichOptions(taskCtx, &op, apiClient.ApiClient)
if err != nil {
return nil, err
}
tokens := strings.Split(connection.Token, ",")
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: tokens[0]},
)
oauthContext := taskCtx.GetContext()
proxy := connection.GetProxy()
if proxy != "" {
pu, err := url.Parse(proxy)
if err != nil {
return nil, errors.Convert(err)
}
if pu.Scheme == "http" || pu.Scheme == "socks5" {
proxyClient := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(pu)},
}
oauthContext = context.WithValue(
taskCtx.GetContext(),
oauth2.HTTPClient,
proxyClient,
)
logger.Debug("Proxy set in oauthContext to %s", proxy)
} else {
return nil, errors.BadInput.New("Unsupported scheme set in proxy")
}
}
httpClient := oauth2.NewClient(oauthContext, src)
endpoint, err := errors.Convert01(url.Parse(connection.Endpoint))
if err != nil {
return nil, errors.BadInput.Wrap(err, fmt.Sprintf("malformed connection endpoint supplied: %s", connection.Endpoint))
}
// github.com and github enterprise have different graphql endpoints
endpoint.Path = "/graphql" // see https://docs.github.com/en/graphql/guides/forming-calls-with-graphql
if endpoint.Hostname() != "api.github.com" {
// see https://docs.github.com/en/enterprise-server@3.11/graphql/guides/forming-calls-with-graphql
endpoint.Path = "/api/graphql"
}
client := graphql.NewClient(endpoint.String(), httpClient)
graphqlClient, err := helper.CreateAsyncGraphqlClient(taskCtx, client, taskCtx.GetLogger(),
func(ctx context.Context, client *graphql.Client, logger log.Logger) (rateRemaining int, resetAt *time.Time, err errors.Error) {
var query GraphQueryRateLimit
dataErrors, err := errors.Convert01(client.Query(taskCtx.GetContext(), &query, nil))
if err != nil {
return 0, nil, err
}
if len(dataErrors) > 0 {
return 0, nil, errors.Default.Wrap(dataErrors[0], `query rate limit fail`)
}
if query.RateLimit == nil {
logger.Info(`github graphql rate limit are disabled, fallback to 5000req/hour`)
return 5000, nil, nil
}
logger.Info(`github graphql init success with remaining %d/%d and will reset at %s`,
query.RateLimit.Remaining, query.RateLimit.Limit, query.RateLimit.ResetAt)
return int(query.RateLimit.Remaining), &query.RateLimit.ResetAt, nil
})
if err != nil {
return nil, err
}
graphqlClient.SetGetRateCost(func(q interface{}) int {
v := reflect.ValueOf(q)
return int(v.Elem().FieldByName(`RateLimit`).FieldByName(`Cost`).Int())
})
regexEnricher := helper.NewRegexEnricher()
if err = regexEnricher.TryAdd(devops.DEPLOYMENT, op.ScopeConfig.DeploymentPattern); err != nil {
return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
}
if err = regexEnricher.TryAdd(devops.PRODUCTION, op.ScopeConfig.ProductionPattern); err != nil {
return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
}
if err = regexEnricher.TryAdd(devops.ENV_NAME_PATTERN, op.ScopeConfig.EnvNamePattern); err != nil {
return nil, errors.BadInput.Wrap(err, "invalid value for `envNamePattern`")
}
taskData := &githubTasks.GithubTaskData{
Options: &op,
ApiClient: apiClient,
GraphqlClient: graphqlClient,
RegexEnricher: regexEnricher,
}
return taskData, nil
}