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

Adds Buggregator as a tool #334

Merged
merged 8 commits into from
Mar 11, 2024
Merged
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
45 changes: 45 additions & 0 deletions app/Services/Buggregator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace App\Services;

use App\Shell\GitHubDockerTags;

class Buggregator extends BaseService
{
protected static $category = Category::TOOLS;

protected $dockerTagsClass = GitHubDockerTags::class;
protected $organization = 'ghcr.io';
protected $imageName = 'buggregator/server';
protected $tag = 'latest';
protected $defaultPort = 8000;
protected $prompts = [
[
'shortname' => 'smtp_port',
'prompt' => 'What is the SMTP port?',
'default' => '1025',
],
[
'shortname' => 'var_dumper_port',
'prompt' => 'What is the VarDumper server port?',
'default' => '9912',
],
[
'shortname' => 'monolog_port',
'prompt' => 'What is the Monolog port?',
'default' => '9913',
],
[
'shortname' => 'network_alias',
'prompt' => 'What network alias to you want to assign to this container? This alias can be used by other services on the same network.',
'default' => 'buggregator',
],
];

protected $dockerRunTemplate = '-p "${:port}":8000 \
-p "${:smtp_port}":1025 \
-p "${:var_dumper_port}":9912 \
-p "${:monolog_port}":9913 \
--network-alias "${:network_alias}" \
"${:organization}"/"${:image_name}":"${:tag}"';
}
55 changes: 55 additions & 0 deletions app/Shell/GitHubDockerTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace App\Shell;

use Illuminate\Support\Collection;
use Psr\Http\Message\StreamInterface;
use RuntimeException;

class GitHubDockerTags extends DockerTags
{
public function getTags(): Collection
{
return collect(json_decode($this->getTagsResponse(), true)['tags']);
}

public function getLatestTag(): string
{
return $this->getTags()->first();
}

protected function getTagsResponse(): StreamInterface
{
$token = $this->getToken();

return $this->guzzle
->get($this->buildTagsUrl(), [
'headers' => [
'Authorization' => "Bearer {$token}",
],
])
->getBody();
}

protected function getToken(): string
{
$image = $this->service->imageName();

$response = $this->guzzle->get('https://ghcr.io/token?' . http_build_query([
'scope' => "repository:{$image}:pull",
]), [
'http_errors' => false,
]);

if ($response->getStatusCode() !== 200) {
throw new RuntimeException("Something went wrong getting the Token from GitHub's registry.");
}

return json_decode($response->getBody(), true)['token'];
}

protected function tagsUrlTemplate(): string
{
return 'https://%s/v2/%s/tags/list';
}
}
58 changes: 58 additions & 0 deletions tests/Feature/GitHubTagsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Tests\Feature;

use App\Services\Buggregator;
use App\Shell\GitHubDockerTags;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use Mockery as M;
use RuntimeException;
use Tests\TestCase;

class GitHubTagsTest extends TestCase
{
/** @test */
function it_fetches_latest_tag()
{
$handlerStack = HandlerStack::create($this->mockImagesResponseHandler());
$client = new Client(['handler' => $handlerStack]);

/** @var GitHubDockerTags $dockerTags */
$dockerTags = M::mock(GitHubDockerTags::class, [$client, app(Buggregator::class)])->makePartial();

$this->assertEquals('latest', $dockerTags->getLatestTag());
}

/** @test */
function it_throws_exception_when_token_request_fails()
{
$handlerStack = HandlerStack::create($this->mockImagesResponseHandler(false));
$client = new Client(['handler' => $handlerStack]);

/** @var GitHubDockerTags $dockerTags */
$dockerTags = M::mock(GitHubDockerTags::class, [$client, app(Buggregator::class)])->makePartial();

$this->expectException(RuntimeException::class);

$dockerTags->getLatestTag();
}

private function mockImagesResponseHandler($tokenWorks = true)
{
return new MockHandler([
new Response($tokenWorks ? 200 : 400, [], json_encode([
'token' => 'fake-token',
])),
new Response(200, [], json_encode([
'tags' => [
'latest',
'1.0.0',
'1.0.0.rc-1',
],
])),
]);
}
}
Loading