mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-02 14:36:17 +00:00
35
app/Actions/Site/UpdateSourceControl.php
Executable file
35
app/Actions/Site/UpdateSourceControl.php
Executable file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Site;
|
||||
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UpdateSourceControl
|
||||
{
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$site->source_control_id = $input['source_control'];
|
||||
$site->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
protected function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'source_control' => [
|
||||
'required',
|
||||
Rule::exists('source_controls', 'id'),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -11,6 +11,4 @@ final class SourceControl extends Enum
|
||||
const GITLAB = 'gitlab';
|
||||
|
||||
const BITBUCKET = 'bitbucket';
|
||||
|
||||
const CUSTOM = 'custom';
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
class SourceControlIsNotConnected extends Exception
|
||||
{
|
||||
public function __construct(protected SourceControl|string $sourceControl, string $message = null)
|
||||
public function __construct(protected SourceControl|string|null $sourceControl, string $message = null)
|
||||
{
|
||||
parent::__construct($message ?? 'Source control is not connected');
|
||||
}
|
||||
|
39
app/Http/Controllers/GitHookController.php
Normal file
39
app/Http/Controllers/GitHookController.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Models\GitHook;
|
||||
use Illuminate\Http\Request;
|
||||
use Throwable;
|
||||
|
||||
class GitHookController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
if (! $request->input('secret')) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
/** @var GitHook $gitHook */
|
||||
$gitHook = GitHook::query()
|
||||
->where('secret', $request->input('secret'))
|
||||
->firstOrFail();
|
||||
|
||||
foreach ($gitHook->actions as $action) {
|
||||
if ($action == 'deploy') {
|
||||
try {
|
||||
$gitHook->site->deploy();
|
||||
} catch (SourceControlIsNotConnected) {
|
||||
// TODO: send notification
|
||||
} catch (Throwable $e) {
|
||||
Log::error('git-hook-exception', (array) $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
]);
|
||||
}
|
||||
}
|
60
app/Http/Livewire/Application/AutoDeployment.php
Normal file
60
app/Http/Livewire/Application/AutoDeployment.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Application;
|
||||
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Models\Site;
|
||||
use App\Traits\HasToast;
|
||||
use App\Traits\RefreshComponentOnBroadcast;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Component;
|
||||
use Throwable;
|
||||
|
||||
class AutoDeployment extends Component
|
||||
{
|
||||
use RefreshComponentOnBroadcast;
|
||||
use HasToast;
|
||||
|
||||
public Site $site;
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function enable(): void
|
||||
{
|
||||
if (! $this->site->auto_deployment) {
|
||||
try {
|
||||
$this->site->enableAutoDeployment();
|
||||
|
||||
$this->site->refresh();
|
||||
|
||||
$this->toast()->success(__('Auto deployment has been enabled.'));
|
||||
} catch (SourceControlIsNotConnected) {
|
||||
$this->toast()->error(__('Source control is not connected. Check site\'s settings.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function disable(): void
|
||||
{
|
||||
if ($this->site->auto_deployment) {
|
||||
try {
|
||||
$this->site->disableAutoDeployment();
|
||||
|
||||
$this->site->refresh();
|
||||
|
||||
$this->toast()->success(__('Auto deployment has been disabled.'));
|
||||
} catch (SourceControlIsNotConnected) {
|
||||
$this->toast()->error(__('Source control is not connected. Check site\'s settings.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.application.auto-deployment');
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ public function save(): void
|
||||
session()->flash('status', 'script-updated');
|
||||
|
||||
$this->emitTo(Deploy::class, '$refresh');
|
||||
$this->emitTo(AutoDeployment::class, '$refresh');
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
|
31
app/Http/Livewire/Sites/UpdateSourceControlProvider.php
Normal file
31
app/Http/Livewire/Sites/UpdateSourceControlProvider.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Sites;
|
||||
|
||||
use App\Actions\Site\UpdateSourceControl;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Component;
|
||||
|
||||
class UpdateSourceControlProvider extends Component
|
||||
{
|
||||
public Site $site;
|
||||
|
||||
public ?int $source_control = null;
|
||||
|
||||
public function update(): void
|
||||
{
|
||||
app(UpdateSourceControl::class)->update($this->site, $this->all());
|
||||
|
||||
session()->flash('status', 'source-control-updated');
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
if (! $this->source_control) {
|
||||
$this->source_control = $this->site->source_control_id;
|
||||
}
|
||||
|
||||
return view('livewire.sites.update-source-control-provider');
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Exceptions\FailedToDeployGitHook;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
@ -22,6 +22,8 @@
|
||||
*/
|
||||
class GitHook extends AbstractModel
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'site_id',
|
||||
'source_control_id',
|
||||
@ -55,9 +57,6 @@ public function scopeHasEvent(Builder $query, string $event): Builder
|
||||
return $query->where('events', 'like', "%\"{$event}\"%");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FailedToDeployGitHook
|
||||
*/
|
||||
public function deployHook(): void
|
||||
{
|
||||
$this->update(
|
||||
|
@ -6,7 +6,6 @@
|
||||
use App\Enums\DeploymentStatus;
|
||||
use App\Enums\SiteStatus;
|
||||
use App\Enums\SslStatus;
|
||||
use App\Exceptions\FailedToDeployGitHook;
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Jobs\Site\ChangePHPVersion;
|
||||
use App\Jobs\Site\Deploy;
|
||||
@ -19,7 +18,7 @@
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
@ -341,22 +340,16 @@ public function getWebDirectoryPathAttribute(): string
|
||||
|
||||
/**
|
||||
* @throws SourceControlIsNotConnected
|
||||
* @throws ValidationException
|
||||
* @throws FailedToDeployGitHook
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function enableAutoDeployment(): void
|
||||
{
|
||||
if ($this->gitHook) {
|
||||
throw ValidationException::withMessages([
|
||||
'auto_deployment' => __('Auto deployment already enabled'),
|
||||
])->errorBag('auto_deployment');
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->sourceControl()) {
|
||||
throw ValidationException::withMessages([
|
||||
'auto_deployment' => __('Your application does not use any source controls'),
|
||||
])->errorBag('auto_deployment');
|
||||
throw new SourceControlIsNotConnected($this->source_control);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -364,7 +357,7 @@ public function enableAutoDeployment(): void
|
||||
$gitHook = new GitHook([
|
||||
'site_id' => $this->id,
|
||||
'source_control_id' => $this->sourceControl()->id,
|
||||
'secret' => generate_uid(),
|
||||
'secret' => Str::uuid()->toString(),
|
||||
'actions' => ['deploy'],
|
||||
'events' => ['push'],
|
||||
]);
|
||||
|
@ -46,7 +46,7 @@ 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),
|
||||
'url' => url('/api/git-hooks?secret='.$secret),
|
||||
'events' => [
|
||||
'repo:'.implode(',', $events),
|
||||
],
|
||||
|
@ -1,41 +0,0 @@
|
||||
<?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 $key): 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;
|
||||
}
|
||||
|
||||
public function deployKey(string $title, string $repo, string $key): void
|
||||
{
|
||||
// TODO: Implement deployKey() method.
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ public function deployHook(string $repo, array $events, string $secret): array
|
||||
'name' => 'web',
|
||||
'events' => $events,
|
||||
'config' => [
|
||||
'url' => url('/git-hooks?secret='.$secret),
|
||||
'url' => url('/api/git-hooks?secret='.$secret),
|
||||
'content_type' => 'json',
|
||||
],
|
||||
'active' => true,
|
||||
|
@ -53,7 +53,7 @@ public function deployHook(string $repo, array $events, string $secret): array
|
||||
$this->getApiUrl().'/projects/'.$repository.'/hooks',
|
||||
[
|
||||
'description' => 'deploy',
|
||||
'url' => url('/git-hooks?secret='.$secret),
|
||||
'url' => url('/api/git-hooks?secret='.$secret),
|
||||
'push_events' => in_array('push', $events),
|
||||
'issues_events' => false,
|
||||
'job_events' => false,
|
||||
|
Reference in New Issue
Block a user