Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Github contribution error #650

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/modules/custom/ct_github/ct_github.services.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
services:
ct_github.query:
class: Drupal\ct_github\GithubQuery
arguments: ['@config.factory', '@cache.data']
arguments: ['@config.factory', '@cache.data', '@logger.factory']
ct_github.loggerChannel:
parent: logger.channel_base
arguments: ['ct_github']
47 changes: 41 additions & 6 deletions web/modules/custom/ct_github/src/GithubQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Drupal\Core\Config\ConfigFactory;
use Github\AuthMethod;
use Github\Client;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;

/**
* Github Query Class.
Expand All @@ -31,7 +32,7 @@ class GithubQuery {
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;

protected $logger;
/**
* Set authentication token to access GitHub API.
*
Expand All @@ -40,13 +41,14 @@ class GithubQuery {
* @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend
* The injected cache backend service.
*/
public function __construct(ConfigFactory $config_factory, CacheBackendInterface $cacheBackend) {
public function __construct(ConfigFactory $config_factory, CacheBackendInterface $cacheBackend, LoggerChannelFactoryInterface $loggerFactory) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra whitespace. This should have been caught by the CI. This is another issue but let's not introduce this here.

$config = $config_factory->get('ct_github.settings');
$token = $config->get('github_auth_token');
$client = new Client();
$client->authenticate($token, NULL, AuthMethod::ACCESS_TOKEN);
$client = (strlen($token) === 40) ? (new Client())->authenticate($token, NULL, AuthMethod::ACCESS_TOKEN) : NULL;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all tokens are 40 characters in length. Fine-grained tokens are longer.


$this->client = $client;
$this->cache = $cacheBackend;
$this->logger = $loggerFactory->get('ct_github'); // Assigning the logger channel directly here
}

/**
Expand Down Expand Up @@ -113,6 +115,9 @@ public function getQuery(string $username): string {
*/
public function isUserValid(string $username): bool {
$cid = 'ct_github:user:' . $username;
if ($this->client === NULL) {
return FALSE;
}
$cache = $this->cache->get($cid);
if ($cache) {
return $cache->data == 'valid';
Expand All @@ -130,8 +135,38 @@ public function isUserValid(string $username): bool {
* API request to get user contributions.
*/
public function getUserContributions(string $username) {
if ($this->client === NULL) {
return NULL;
}
$query = $this->getQuery($username);
return $this->client->api('graphql')->execute($query);
}
$maxRetries = 5;
$retryCount = 0;
$waitTime = 1; // Initial wait time in seconds for backoff

while ($retryCount < $maxRetries) {
try {
return $this->client->api('graphql')->execute($query);
} catch (Github\Exception\RuntimeException $e) {
// Check if the error is due to bad credentials
if ($e->getMessage() === 'Bad credentials') {
$this->logger->error('GitHub API error: Bad credentials. Please check the credentials.');
return NULL;
}
Comment on lines +151 to +154
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it likely that we will get bad credentials here? Shouldn't this have been caught in authenticate method itself?


// Handle other errors with backoff
$retryCount++;
$this->logger->warning("GitHub API request failed. Retry $retryCount/$maxRetries. Error: " . $e->getMessage());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not log this at warning when we are going to try again. We can log this at info or notice level maybe.


// Stop retries if max retries reached
if ($retryCount >= $maxRetries) {
$this->logger->error("GitHub API request failed after $maxRetries attempts.");
return NULL;
}

// Wait before retrying with exponential backoff
sleep($waitTime);
$waitTime *= 2; // Double the wait time for exponential backoff
}
}
}
}
7 changes: 6 additions & 1 deletion web/modules/custom/ct_github/src/GithubRetriever.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ protected function getUserContributions($username) {
*/
public function getIssues() {
$userContributions = $this->getUserContributions($this->username);

if($userContributions){
$issues = array_map(function ($issue) {
return new Issue($issue['title'], $issue['url']);
}, $userContributions['data']['user']['issues']['nodes']);
return $issues;
return $issues;}
Comment on lines +69 to +73
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace error. Again this should have been caught in the CI.

}

/**
Expand All @@ -78,6 +80,9 @@ public function getCodeContributions() {
$userContributions = $this->getUserContributions($this->username);
$codeContribution = [];
// Get all commits associated with the user and set the title accodingly.
if(!$userContributions){
return NULL;
}
foreach ($userContributions['data']['user']['pullRequests']['nodes'] as $data) {
foreach ($data['commits']['nodes'] as $node) {
if ($node['commit']['authoredByCommitter']) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public function processItem($data) {
/** @var \Drupal\ct_manager\ContributionSourceInterface $plugin_instance */
$plugin_instance = $this->pluginManager->createInstance($plugin_id);
if (!($plugin_instance->isUserValid($user))) {
if ($plugin_id === "github") {
return;
}
Comment on lines +93 to +95
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a code smell. The ct_manager should not have to know about ct_github.

$this->logger->error('@plugin username for @username is invalid.', ['@plugin' => $plugin_id, '@username' => $user->getAccountName()]);
return;
}
Expand All @@ -99,6 +102,9 @@ public function processItem($data) {

$this->logger->notice('Saving @plugin issues for @user', ['@plugin' => $plugin_id, '@user' => $user->getAccountName()]);
/** @var \Drupal\ct_manager\Data\Issue $issue */
if ($issues) {
return NULL;
}
foreach ($issues as $issue) {
if ($this->contribStorage->getNodeForIssue($issue->getUrl())) {
$this->logger->notice('Skipping issue @issue, and all after it.', ['@issue' => $issue->getUrl()]);
Expand Down