Skip to content

Commit

Permalink
pull request webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
andrasbacsai committed May 31, 2023
1 parent 232d2cc commit c953482
Show file tree
Hide file tree
Showing 16 changed files with 272 additions and 64 deletions.
36 changes: 18 additions & 18 deletions app/Http/Livewire/Project/Application/General.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ class General extends Component
public string|null $global_wildcard_domain = null;

public bool $is_static;
public bool $is_git_submodules_allowed;
public bool $is_git_lfs_allowed;
public bool $is_debug;
public bool $is_previews;
public bool $is_auto_deploy;
public bool $is_force_https;
public bool $is_git_submodules_enabled;
public bool $is_git_lfs_enabled;
public bool $is_debug_enabled;
public bool $is_preview_deployments_enabled;
public bool $is_auto_deploy_enabled;
public bool $is_force_https_enabled;

protected $rules = [
'application.name' => 'required|min:6',
Expand All @@ -51,12 +51,12 @@ public function instantSave()
{
// @TODO: find another way - if possible
$this->application->settings->is_static = $this->is_static;
$this->application->settings->is_git_submodules_allowed = $this->is_git_submodules_allowed;
$this->application->settings->is_git_lfs_allowed = $this->is_git_lfs_allowed;
$this->application->settings->is_debug = $this->is_debug;
$this->application->settings->is_previews = $this->is_previews;
$this->application->settings->is_auto_deploy = $this->is_auto_deploy;
$this->application->settings->is_force_https = $this->is_force_https;
$this->application->settings->is_git_submodules_enabled = $this->is_git_submodules_enabled;
$this->application->settings->is_git_lfs_enabled = $this->is_git_lfs_enabled;
$this->application->settings->is_debug_enabled = $this->is_debug_enabled;
$this->application->settings->is_preview_deployments_enabled = $this->is_preview_deployments_enabled;
$this->application->settings->is_auto_deploy_enabled = $this->is_auto_deploy_enabled;
$this->application->settings->is_force_https_enabled = $this->is_force_https_enabled;
$this->application->settings->save();
$this->application->refresh();
$this->emit('saved', 'Application settings updated!');
Expand All @@ -72,12 +72,12 @@ protected function checkWildCardDomain()
public function mount()
{
$this->is_static = $this->application->settings->is_static;
$this->is_git_submodules_allowed = $this->application->settings->is_git_submodules_allowed;
$this->is_git_lfs_allowed = $this->application->settings->is_git_lfs_allowed;
$this->is_debug = $this->application->settings->is_debug;
$this->is_previews = $this->application->settings->is_previews;
$this->is_auto_deploy = $this->application->settings->is_auto_deploy;
$this->is_force_https = $this->application->settings->is_force_https;
$this->is_git_submodules_enabled = $this->application->settings->is_git_submodules_enabled;
$this->is_git_lfs_enabled = $this->application->settings->is_git_lfs_enabled;
$this->is_debug_enabled = $this->application->settings->is_debug_enabled;
$this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled;
$this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled;
$this->is_force_https_enabled = $this->application->settings->is_force_https_enabled;
$this->checkWildCardDomain();
}
public function generateGlobalRandomDomain()
Expand Down
5 changes: 1 addition & 4 deletions app/Http/Livewire/Project/Application/Previews.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ public function stop(int $pull_request_id)
ray('Stopping container: ' . $container_name);

instant_remote_process(["docker rm -f $container_name"], $this->application->destination->server, throwError: false);
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
if ($found) {
$found->delete();
}
ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->delete();
$this->application->refresh();
} catch (\Throwable $th) {
return general_error_handler($th, $this);
Expand Down
8 changes: 4 additions & 4 deletions app/Jobs/ApplicationDeploymentJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ private function set_labels_for_applications()
// Set labels for http (redirect to https)
$labels[] = "traefik.http.routers.{$http_label}.rule=Host(`{$host}`) && PathPrefix(`{$path}`)";
$labels[] = "traefik.http.routers.{$http_label}.entryPoints=http";
if ($this->application->settings->is_force_https) {
if ($this->application->settings->is_force_https_enabled) {
$labels[] = "traefik.http.routers.{$http_label}.middlewares=redirect-to-https";
}
} else {
Expand Down Expand Up @@ -539,7 +539,7 @@ private function execute_now(
'command' => $commandText,
]);
$this->activity->save();
if ($isDebuggable && !$this->application->settings->is_debug) {
if ($isDebuggable && !$this->application->settings->is_debug_enabled) {
$hideFromOutput = true;
}
$remote_process = resolve(RunRemoteProcess::class, [
Expand All @@ -565,10 +565,10 @@ private function set_git_import_settings($git_clone_command)
if ($this->application->git_commit_sha !== 'HEAD') {
$git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git -c advice.detachedHead=false checkout {$this->application->git_commit_sha} >/dev/null 2>&1";
}
if ($this->application->settings->is_git_submodules_allowed) {
if ($this->application->settings->is_git_submodules_enabled) {
$git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git submodule update --init --recursive";
}
if ($this->application->settings->is_git_lfs_allowed) {
if ($this->application->settings->is_git_lfs_enabled) {
$git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git lfs pull";
}
return $git_clone_command;
Expand Down
9 changes: 8 additions & 1 deletion app/Models/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,14 @@ public function get_deployment(string $deployment_uuid)
}
public function isDeployable(): bool
{
if ($this->settings->is_auto_deploy) {
if ($this->settings->is_auto_deploy_enabled) {
return true;
}
return false;
}
public function isPRDeployable(): bool
{
if ($this->settings->is_preview_deployments_enabled) {
return true;
}
return false;
Expand Down
1 change: 1 addition & 0 deletions app/Models/ApplicationDeploymentQueue.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ class ApplicationDeploymentQueue extends Model
'force_rebuild',
'commit',
'status',
'is_webhook',
];
}
18 changes: 16 additions & 2 deletions app/Models/ApplicationSetting.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@

class ApplicationSetting extends Model
{
protected $cast = [
'is_static' => 'boolean',
'is_auto_deploy_enabled' => 'boolean',
'is_force_https_enabled' => 'boolean',
'is_debug_enabled' => 'boolean',
'is_preview_deployments_enabled' => 'boolean',
'is_git_submodules_enabled' => 'boolean',
'is_git_lfs_enabled' => 'boolean',
];
protected $fillable = [
'application_id',
'is_git_submodules_allowed',
'is_git_lfs_allowed',
'is_static',
'is_auto_deploy_enabled',
'is_force_https_enabled',
'is_debug_enabled',
'is_preview_deployments_enabled',
'is_git_submodules_enabled',
'is_git_lfs_enabled',
];
public function isStatic(): Attribute
{
Expand Down
3 changes: 2 additions & 1 deletion bootstrap/helpers/applications.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
use App\Jobs\ApplicationDeploymentJob;
use App\Models\ApplicationDeploymentQueue;

function queue_application_deployment(int $application_id, string $deployment_uuid, int|null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false)
function queue_application_deployment(int $application_id, string $deployment_uuid, int|null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false)
{
ray('Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild);
$deployment = ApplicationDeploymentQueue::create([
'application_id' => $application_id,
'deployment_uuid' => $deployment_uuid,
'pull_request_id' => $pull_request_id,
'force_rebuild' => $force_rebuild,
'is_webhook' => $is_webhook,
'commit' => $commit,
]);
$queued_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'queued')->get()->sortByDesc('created_at');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ public function up(): void
Schema::create('application_settings', function (Blueprint $table) {
$table->id();
$table->boolean('is_static')->default(false);
$table->boolean('is_git_submodules_allowed')->default(true);
$table->boolean('is_git_lfs_allowed')->default(true);
$table->boolean('is_auto_deploy')->default(true);
$table->boolean('is_force_https')->default(true);
$table->boolean('is_git_submodules_enabled')->default(true);
$table->boolean('is_git_lfs_enabled')->default(true);
$table->boolean('is_auto_deploy_enabled')->default(true);
$table->boolean('is_force_https_enabled')->default(true);
$table->boolean('is_debug_enabled')->default(false);
$table->boolean('is_preview_deployments_enabled')->default(false);
// $table->boolean('is_dual_cert')->default(false);
$table->boolean('is_debug')->default(false);
$table->boolean('is_previews')->default(false);
// $table->boolean('is_custom_ssl')->default(false);
// $table->boolean('is_http2')->default(false);
$table->foreignId('application_id');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function up(): void
$table->boolean('force_rebuild')->default(false);
$table->string('commit')->default('HEAD');
$table->string('status')->default('queued');
$table->boolean('is_webhook')->default(false);
$table->timestamps();
});
}
Expand Down
2 changes: 1 addition & 1 deletion database/seeders/ApplicationSettingsSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ApplicationSettingsSeeder extends Seeder
public function run(): void
{
$application_1 = Application::find(1)->load(['settings']);
$application_1->settings->is_debug = false;
$application_1->settings->is_debug_enabled = false;
$application_1->settings->save();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,20 @@
class="hover:no-underline">
<div class="flex flex-col justify-start">
@if (data_get($deployment, 'pull_request_id'))
<div>Pull Request #{{ data_get($deployment, 'pull_request_id') }}</div>
<div>
Pull Request #{{ data_get($deployment, 'pull_request_id') }}
@if (data_get($deployment, 'is_webhook'))
(Webhook)
@endif
</div>
@elseif (data_get($deployment, 'is_webhook'))
<div>Webhook (commit
@if (data_get($deployment, 'commit'))
{{ data_get($deployment, 'commit') }})
@else
HEAD)
@endif
</div>
@else
<div>Commit:
@if (data_get($deployment, 'commit'))
Expand Down
14 changes: 8 additions & 6 deletions resources/views/livewire/project/application/general.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,19 @@
</div>
<h3>Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="More logs will be visible during a deployment." instantSave id="is_debug"
<x-forms.checkbox helper="More logs will be visible during a deployment." instantSave id="is_debug_enabled"
label="Debug" />
<x-forms.checkbox
helper="Your application will be available only on https if your domain starts with https://..."
instantSave id="is_force_https" label="Force Https" />
instantSave id="is_force_https_enabled" label="Force Https" />
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
id="is_auto_deploy" label="Auto Deploy" />
{{-- <x-forms.checkbox helper="Preview deployments" instantSave id="is_previews" label="Previews?" /> --}}
<x-forms.checkbox instantSave id="is_git_submodules_allowed" label="Git Submodules"
id="is_auto_deploy_enabled" label="Auto Deploy" />
<x-forms.checkbox
helper="Automatically deploy Preview Deployments for all opened PR's. Closed PRs deletes Preview Deployments."
instantSave id="is_preview_deployments_enabled" label="Auto Previews Deployments" />
<x-forms.checkbox instantSave id="is_git_submodules_enabled" label="Git Submodules"
helper="Allow Git Submodules during build process." />
<x-forms.checkbox instantSave id="is_git_lfs_allowed" label="Git LFS"
<x-forms.checkbox instantSave id="is_git_lfs_enabled" label="Git LFS"
helper="Allow Git LFS during build process." />
{{-- <x-forms.checkbox disabled instantSave id="is_dual_cert" label="Dual Certs?" />
<x-forms.checkbox disabled instantSave id="is_custom_ssl" label="Is Custom SSL?" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<div>

<livewire:project.application.preview.form :application="$application" />
<h3>Pull Requests on Git</h3>
<div>
<x-forms.button wire:click="load_prs">Load Pull Requests
<x-forms.button wire:click="load_prs">Load Opened Pull Requests
</x-forms.button>
@isset($rate_limit_remaining)
<div class="pt-1 text-sm">Requests remaning till rate limited by Git: {{ $rate_limit_remaining }}</div>
Expand Down
83 changes: 72 additions & 11 deletions routes/webhooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use App\Jobs\ApplicationDeploymentJob;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Models\PrivateKey;
use App\Models\GithubApp;
use App\Models\GithubEventsApplications;
Expand Down Expand Up @@ -85,23 +86,83 @@
if (Str::isMatch('/refs\/heads\/*/', $branch)) {
$branch = Str::after($branch, 'refs/heads/');
}
ray('Webhook GitHub Push Event: ' . $id . ' with branch: ' . $branch);
}
if ($x_github_event === 'pull_request') {
$id = data_get($payload, 'pull_request.base.repo.id');
$branch = data_get($payload, 'pull_request.base.ref');
$action = data_get($payload, 'action');
$id = data_get($payload, 'repository.id');
$pull_request_id = data_get($payload, 'number');
$pull_request_html_url = data_get($payload, 'pull_request.html_url');
$branch = data_get($payload, 'pull_request.head.ref');
$base_branch = data_get($payload, 'pull_request.base.ref');
ray('Webhook GitHub Pull Request Event: ' . $id . ' with branch: ' . $branch . ' and base branch: ' . $base_branch . ' and pull request id: ' . $pull_request_id);
}
if (!$id || !$branch) {
return response('not cool');
return response('Nothing to do. No id or branch found.');
}
$applications = Application::where('repository_project_id', $id);
if ($x_github_event === 'push') {
$applications = $applications->where('git_branch', $branch)->get();
}
if ($x_github_event === 'pull_request') {
$applications = $applications->where('git_branch', $base_branch)->get();
}

if ($applications->isEmpty()) {
return response('Nothing to do. No applications found.');
}
$applications = Application::where('repository_project_id', $id)->where('git_branch', $branch)->get();
foreach ($applications as $application) {
if ($application->isDeployable()) {
$deployment_uuid = new Cuid2(7);
dispatch(new ApplicationDeploymentJob(
deployment_uuid: $deployment_uuid,
application_uuid: $application->uuid,
force_rebuild: false,
));
if ($x_github_event === 'push') {
if ($application->isDeployable()) {
ray('Deploying ' . $application->name . ' with branch ' . $branch);
$deployment_uuid = new Cuid2(7);
queue_application_deployment(
application_id: $application->id,
deployment_uuid: $deployment_uuid,
force_rebuild: false,
is_webhook: true
);
} else {
ray('Deployments disabled for ' . $application->name);
}
}
if ($x_github_event === 'pull_request') {
if ($action === 'opened') {
if ($application->isPRDeployable()) {
$deployment_uuid = new Cuid2(7);
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
if (!$found) {
ApplicationPreview::create([
'application_id' => $application->id,
'pull_request_id' => $pull_request_id,
'pull_request_html_url' => $pull_request_html_url
]);
}
queue_application_deployment(
application_id: $application->id,
pull_request_id: $pull_request_id,
deployment_uuid: $deployment_uuid,
force_rebuild: false,
is_webhook: true
);
ray('Deploying preview for ' . $application->name . ' with branch ' . $branch . ' and base branch ' . $base_branch . ' and pull request id ' . $pull_request_id);
return response('Preview Deployment queued.');
} else {
ray('Preview deployments disabled for ' . $application->name);
return response('Nothing to do. Preview Deployments disabled.');
}
}
if ($action === 'closed') {
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
if ($found) {
$found->delete();
$container_name = generate_container_name($application->uuid, $pull_request_id);
ray('Stopping container: ' . $container_name);
remote_process(["docker rm -f $container_name"], $application->destination->server);
return response('Preview Deployment closed.');
}
return response('Nothing to do. No Preview Deplyoment found');
}
}
}
} catch (\Exception $e) {
Expand Down
Loading

0 comments on commit c953482

Please sign in to comment.