Skip to content

Commit

Permalink
Adds issue section
Browse files Browse the repository at this point in the history
  • Loading branch information
butschster committed Apr 21, 2024
1 parent 8063060 commit a083311
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 12 deletions.
2 changes: 2 additions & 0 deletions app/app/src/Application/Bootloader/GithubBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ public function defineSingletons(): array
return [
ClientInterface::class => static fn(
CacheStorageProviderInterface $cache,
EnvironmentInterface $env,
) => new CacheableClient(
client: new Client(
client: new \GuzzleHttp\Client([
'base_uri' => 'https://api.github.com/',
'headers' => [
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'Bearer ' . $env->get('GITHUB_TOKEN'),
],
]),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@

namespace App\Endpoint\Http\Controller;

final class IssuesForContributorsAction
{
use App\Application\Http\Response\ResourceInterface;
use App\Endpoint\Http\Resource\IssueCollection;
use App\Endpoint\Http\Resource\IssueResource;
use App\Github\ClientInterface;
use Spiral\Router\Annotation\Route;

final readonly class IssuesForContributorsAction
{
#[Route(route: 'issues/for-contributors', name: 'issues-for-contributors', methods: ['GET'], group: 'api')]
public function __invoke(ClientInterface $client): ResourceInterface
{
return new IssueCollection($client->getIssuesForContributors(), IssueResource::class);
}
}
4 changes: 3 additions & 1 deletion app/app/src/Endpoint/Http/Resource/IssueCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace App\Endpoint\Http\Resource;

final class IssueCollection
use App\Application\Http\Response\ResourceCollection;

final class IssueCollection extends ResourceCollection
{

}
4 changes: 3 additions & 1 deletion app/app/src/Endpoint/Http/Resource/IssueResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace App\Endpoint\Http\Resource;

final class IssueResource
use App\Application\Http\Response\JsonResource;

final class IssueResource extends JsonResource
{

}
13 changes: 13 additions & 0 deletions app/app/src/Github/CacheableClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ public function getLastVersion(string $repository): string
return $version;
}

public function getIssuesForContributors(): array
{
$cacheKey = $this->getCacheKey('issues', __METHOD__);
if ($this->cache->has($cacheKey)) {
return $this->cache->get($cacheKey);
}

$issues = $this->client->getIssuesForContributors();
$this->cache->set($cacheKey, $issues, $this->ttl);

return $issues;
}

public function clearCache(): void
{
$this->cache->clear();
Expand Down
51 changes: 47 additions & 4 deletions app/app/src/Github/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace App\Github;

use App\Github\Entity\Issue;
use Carbon\Carbon;
use GuzzleHttp\Psr7\Request;

final readonly class Client implements ClientInterface
Expand All @@ -17,8 +19,8 @@ public function getStars(string $repository): int
{
$response = $this->client->sendRequest(
new Request(
'GET',
"repos/{$repository}",
method: 'GET',
uri: "repos/{$repository}",
),
);

Expand All @@ -31,13 +33,54 @@ public function getLastVersion(string $repository): string
{
$response = $this->client->sendRequest(
new Request(
'GET',
"repos/{$repository}/releases/latest",
method: 'GET',
uri: "repos/{$repository}/releases/latest",
),
);

$data = \json_decode($response->getBody()->getContents(), true);

return $data['tag_name'];
}

public function getIssuesForContributors(): array
{
$repositories = [
'buggregator/server',
'buggregator/trap',
'buggregator/frontend',
'buggregator/docs',
];

$issues = [];

foreach ($repositories as $repository) {
$issues = [...$issues, ...$this->fetchRepositoryIssues($repository)];
}

return $issues;
}

private function fetchRepositoryIssues(string $repository): array
{
$response = $this->client->sendRequest(
new Request(
method: 'GET',
uri: "repos/{$repository}/issues?labels=for%20contributors&assignee=none",
),
);

$data = \json_decode($response->getBody()->getContents(), true);

return \array_map(
static fn(array $issue): Issue => new Issue(
repository: $repository,
title: $issue['title'],
labels: \array_map(static fn(array $label) => $label['name'], $issue['labels']),
url: $issue['html_url'],
createdAt: Carbon::createFromFormat('Y-m-d\TH:i:s\Z', $issue['created_at']),
),
$data,
);
}
}
7 changes: 7 additions & 0 deletions app/app/src/Github/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@

namespace App\Github;

use App\Github\Entity\Issue;

interface ClientInterface
{
public function getStars(string $repository): int;

public function getLastVersion(string $repository): string;

/**
* @return Issue[]
*/
public function getIssuesForContributors(): array;
}
25 changes: 24 additions & 1 deletion app/app/src/Github/Entity/Issue.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,30 @@

namespace App\Github\Entity;

final class Issue
final readonly class Issue implements \JsonSerializable
{
/**
* @param non-empty-string $title
* @param non-empty-string[] $labels
* @param non-empty-string $url
*/
public function __construct(
public string $repository,
public string $title,
public array $labels,
public string $url,
public \DateTimeInterface $createdAt,
) {
}

public function jsonSerialize(): array
{
return [
'repository' => $this->repository,
'title' => $this->title,
'labels' => $this->labels,
'url' => $this->url,
'createdAt' => $this->createdAt->format(\DateTimeInterface::ATOM),
];
}
}
2 changes: 2 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ services:

VAR_DUMPER_FORMAT: server
VAR_DUMPER_SERVER: buggregator-demo:9912

GITHUB_TOKEN: ${GITHUB_TOKEN}
volumes:
- ./app:/app
depends_on:
Expand Down
6 changes: 3 additions & 3 deletions spa/components/v1/Contribution.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import { useIssuesStore } from "~/stores/issues";
import GridRow from "~/components/v1/GridRow.vue";
const issues = computed(() => {
const store = useIssuesStore();
store.fetch();
const store = useIssuesStore();
store.fetch();
const issues = computed(() => {
return store.issues;
});
Expand Down

0 comments on commit a083311

Please sign in to comment.