This commit is contained in:
Saeed Vaziry
2023-07-02 12:47:50 +02:00
commit 5c72f12490
825 changed files with 41659 additions and 0 deletions

View File

@ -0,0 +1,40 @@
<?php
namespace App\SourceControlProviders;
use App\Contracts\SourceControlProvider;
use App\Exceptions\RepositoryNotFound;
use App\Exceptions\RepositoryPermissionDenied;
use App\Exceptions\SourceControlIsNotConnected;
use App\Models\SourceControl;
use Illuminate\Http\Client\Response;
abstract class AbstractSourceControlProvider implements SourceControlProvider
{
protected SourceControl $sourceControl;
public function __construct(SourceControl $sourceControl)
{
$this->sourceControl = $sourceControl;
}
/**
* @throws SourceControlIsNotConnected
* @throws RepositoryNotFound
* @throws RepositoryPermissionDenied
*/
protected function handleResponseErrors(Response $res, string $repo): void
{
if ($res->status() == 401) {
throw new SourceControlIsNotConnected($this->sourceControl);
}
if ($res->status() == 404) {
throw new RepositoryNotFound($repo);
}
if ($res->status() == 403) {
throw new RepositoryPermissionDenied($repo);
}
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace App\SourceControlProviders;
use App\Exceptions\FailedToDeployGitHook;
use App\Exceptions\FailedToDestroyGitHook;
use Exception;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
class Bitbucket extends AbstractSourceControlProvider
{
protected string $apiUrl = 'https://api.bitbucket.org/2.0';
public function connect(): bool
{
$res = Http::withToken($this->sourceControl->access_token)
->get($this->apiUrl.'/repositories');
return $res->successful();
}
/**
* @throws Exception
*/
public function getRepo(string $repo = null): mixed
{
$res = Http::withToken($this->sourceControl->access_token)
->get($this->apiUrl."/repositories/$repo");
$this->handleResponseErrors($res, $repo);
return $res->json();
}
public function fullRepoUrl(string $repo): string
{
return "https://x-token-auth:{$this->sourceControl->access_token}@bitbucket.org/$repo.git";
}
/**
* @throws FailedToDeployGitHook
*/
public function deployHook(string $repo, array $events, string $secret): array
{
$response = Http::withToken($this->sourceControl->access_token)->post($this->apiUrl."/repositories/$repo/hooks", [
'description' => 'deploy',
'url' => url('/git-hooks?secret='.$secret),
'events' => [
'repo:'.implode(',', $events),
],
'active' => true,
]);
if ($response->status() != 201) {
throw new FailedToDeployGitHook($response->json()['error']['message']);
}
return [
'hook_id' => json_decode($response->body())->uuid,
'hook_response' => json_decode($response->body()),
];
}
/**
* @throws FailedToDestroyGitHook
*/
public function destroyHook(string $repo, string $hookId): void
{
$hookId = urlencode($hookId);
$response = Http::withToken($this->sourceControl->access_token)->delete($this->apiUrl."/repositories/$repo/hooks/$hookId");
if ($response->status() != 204) {
throw new FailedToDestroyGitHook('Error');
}
}
/**
* @throws Exception
*/
public function getLastCommit(string $repo, string $branch): ?array
{
$res = Http::withToken($this->sourceControl->access_token)
->get($this->apiUrl."/repositories/$repo/commits?include=".$branch);
$this->handleResponseErrors($res, $repo);
$commits = $res->json();
if (isset($commits['values']) && count($commits['values']) > 0) {
return [
'commit_id' => $commits['values'][0]['hash'],
'commit_data' => [
'name' => $this->getCommitter($commits['values'][0]['author']['raw'])['name'] ?? null,
'email' => $this->getCommitter($commits['values'][0]['author']['raw'])['email'] ?? null,
'message' => str_replace("\n", '', $commits['values'][0]['message']),
'url' => $commits['values'][0]['links']['html']['href'] ?? null,
],
];
}
return null;
}
protected function getCommitter(string $raw): array
{
$committer = explode(' <', $raw);
return [
'name' => $committer[0],
'email' => Str::replace('>', '', $committer[1]),
];
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\SourceControlProviders;
class Custom extends AbstractSourceControlProvider
{
public function connect(): bool
{
return true;
}
public function getRepo(string $repo = null): string
{
return '';
}
public function fullRepoUrl(string $repo): string
{
return $repo;
}
public function deployHook(string $repo, array $events, string $secret): array
{
return [];
}
public function destroyHook(string $repo, string $hookId): void
{
// TODO: Implement destroyHook() method.
}
public function getLastCommit(string $repo, string $branch): ?array
{
return null;
}
}

View File

@ -0,0 +1,120 @@
<?php
namespace App\SourceControlProviders;
use App\Exceptions\FailedToDeployGitHook;
use App\Exceptions\FailedToDestroyGitHook;
use Exception;
use Illuminate\Support\Facades\Http;
class Github extends AbstractSourceControlProvider
{
protected string $apiUrl = 'https://api.github.com';
public function connect(): bool
{
$res = Http::withHeaders([
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'Bearer '.$this->sourceControl->access_token,
])->get($this->apiUrl.'/user/repos');
return $res->successful();
}
/**
* @throws Exception
*/
public function getRepo(string $repo = null): mixed
{
if ($repo) {
$url = $this->apiUrl.'/repos/'.$repo;
} else {
$url = $this->apiUrl.'/user/repos';
}
$res = Http::withHeaders([
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'Bearer '.$this->sourceControl->access_token,
])->get($url);
$this->handleResponseErrors($res, $repo);
return $res->json();
}
public function fullRepoUrl(string $repo): string
{
return "https://{$this->sourceControl->access_token}@github.com/$repo.git";
}
/**
* @throws FailedToDeployGitHook
*/
public function deployHook(string $repo, array $events, string $secret): array
{
$response = Http::withHeaders([
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'Bearer '.$this->sourceControl->access_token,
])->post($this->apiUrl."/repos/$repo/hooks", [
'name' => 'web',
'events' => $events,
'config' => [
'url' => url('/git-hooks?secret='.$secret),
'content_type' => 'json',
],
'active' => true,
]);
if ($response->status() != 201) {
throw new FailedToDeployGitHook(json_decode($response->body())->message);
}
return [
'hook_id' => json_decode($response->body())->id,
'hook_response' => json_decode($response->body()),
];
}
/**
* @throws FailedToDestroyGitHook
*/
public function destroyHook(string $repo, string $hookId): void
{
$response = Http::withHeaders([
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'Bearer '.$this->sourceControl->access_token,
])->delete($this->apiUrl."/repos/$repo/hooks/$hookId");
if ($response->status() != 204) {
throw new FailedToDestroyGitHook(json_decode($response->body())->message);
}
}
/**
* @throws Exception
*/
public function getLastCommit(string $repo, string $branch): ?array
{
$url = $this->apiUrl.'/repos/'.$repo.'/commits/'.$branch;
$res = Http::withHeaders([
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'Bearer '.$this->sourceControl->access_token,
])->get($url);
$this->handleResponseErrors($res, $repo);
$commit = $res->json();
if (isset($commit['sha']) && isset($commit['commit'])) {
return [
'commit_id' => $commit['sha'],
'commit_data' => [
'name' => $commit['commit']['committer']['name'] ?? null,
'email' => $commit['commit']['committer']['email'] ?? null,
'message' => $commit['commit']['message'] ?? null,
'url' => $commit['html_url'] ?? null,
],
];
}
return null;
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace App\SourceControlProviders;
use App\Exceptions\FailedToDeployGitHook;
use App\Exceptions\FailedToDestroyGitHook;
use Exception;
use Illuminate\Support\Facades\Http;
class Gitlab extends AbstractSourceControlProvider
{
protected string $apiUrl = 'https://gitlab.com/api/v4';
public function connect(): bool
{
$res = Http::withToken($this->sourceControl->access_token)
->get($this->apiUrl.'/projects');
return $res->successful();
}
/**
* @throws Exception
*/
public function getRepo(string $repo = null): mixed
{
$repository = $repo ? urlencode($repo) : null;
$res = Http::withToken($this->sourceControl->access_token)
->get($this->apiUrl.'/projects/'.$repository.'/repository/commits');
$this->handleResponseErrors($res, $repo);
return $res->json();
}
public function fullRepoUrl(string $repo): string
{
return 'https://oauth2:'.$this->sourceControl->access_token.'@gitlab.com/'.$repo.'.git';
}
/**
* @throws FailedToDeployGitHook
*/
public function deployHook(string $repo, array $events, string $secret): array
{
$repository = urlencode($repo);
$response = Http::withToken($this->sourceControl->access_token)->post(
$this->apiUrl.'/projects/'.$repository.'/hooks',
[
'description' => 'deploy',
'url' => url('/git-hooks?secret='.$secret),
'push_events' => in_array('push', $events),
'issues_events' => false,
'job_events' => false,
'merge_requests_events' => false,
'note_events' => false,
'pipeline_events' => false,
'tag_push_events' => false,
'wiki_page_events' => false,
'deployment_events' => false,
'confidential_note_events' => false,
'confidential_issues_events' => false,
]
);
if ($response->status() != 201) {
throw new FailedToDeployGitHook(json_decode($response->body())->message);
}
return [
'hook_id' => json_decode($response->body())->id,
'hook_response' => json_decode($response->body()),
];
}
/**
* @throws FailedToDestroyGitHook
*/
public function destroyHook(string $repo, string $hookId): void
{
$repository = urlencode($repo);
$response = Http::withToken($this->sourceControl->access_token)->delete(
$this->apiUrl.'/projects/'.$repository.'/hooks/'.$hookId
);
if ($response->status() != 204) {
throw new FailedToDestroyGitHook(json_decode($response->body())->message);
}
}
/**
* @throws Exception
*/
public function getLastCommit(string $repo, string $branch): ?array
{
$repository = urlencode($repo);
$res = Http::withToken($this->sourceControl->access_token)
->get($this->apiUrl.'/projects/'.$repository.'/repository/commits?ref_name='.$branch);
$this->handleResponseErrors($res, $repo);
$commits = $res->json();
if (count($commits) > 0) {
return [
'commit_id' => $commits[0]['id'],
'commit_data' => [
'name' => $commits[0]['committer_name'] ?? null,
'email' => $commits[0]['committer_email'] ?? null,
'message' => $commits[0]['title'] ?? null,
'url' => $commits[0]['web_url'] ?? null,
],
];
}
return null;
}
}