func()

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
}