feat: add PR comments

This commit is contained in:
Andras Bacsai 2024-01-26 18:46:50 +01:00
parent 9628072b0c
commit 5c334bbac6
5 changed files with 30 additions and 18 deletions

View File

@ -10,4 +10,5 @@ enum ProcessStatus: string
case ERROR = 'error'; case ERROR = 'error';
case KILLED = 'killed'; case KILLED = 'killed';
case CANCELLED = 'cancelled'; case CANCELLED = 'cancelled';
case CLOSED = 'closed';
} }

View File

@ -3,7 +3,7 @@
namespace App\Jobs; namespace App\Jobs;
use App\Enums\ApplicationDeploymentStatus; use App\Enums\ApplicationDeploymentStatus;
use App\Enums\ProxyTypes; use App\Enums\ProcessStatus;
use App\Events\ApplicationStatusChanged; use App\Events\ApplicationStatusChanged;
use App\Models\Application; use App\Models\Application;
use App\Models\ApplicationDeploymentQueue; use App\Models\ApplicationDeploymentQueue;
@ -158,6 +158,7 @@ public function __construct(int $application_deployment_queue_id)
$this->preview->fqdn = $preview_fqdn; $this->preview->fqdn = $preview_fqdn;
$this->preview->save(); $this->preview->save();
} }
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::IN_PROGRESS);
} }
} }
@ -254,8 +255,14 @@ public function handle(): void
$this->push_to_docker_registry(); $this->push_to_docker_registry();
} }
$this->next(ApplicationDeploymentStatus::FINISHED->value); $this->next(ApplicationDeploymentStatus::FINISHED->value);
if ($this->pull_request_id !== 0) {
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::FINISHED);
}
$this->application->isConfigurationChanged(true); $this->application->isConfigurationChanged(true);
} catch (Exception $e) { } catch (Exception $e) {
if ($this->pull_request_id !== 0) {
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::ERROR);
}
$this->fail($e); $this->fail($e);
throw $e; throw $e;
} finally { } finally {

View File

@ -17,38 +17,34 @@ class ApplicationPullRequestUpdateJob implements ShouldQueue, ShouldBeEncrypted
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public string $build_logs_url; public string $build_logs_url;
public Application $application;
public ApplicationPreview $preview;
public string $body; public string $body;
public function __construct( public function __construct(
public string $application_id, public Application $application,
public int $pull_request_id, public ApplicationPreview $preview,
public string $deployment_uuid, public ProcessStatus $status,
public string $status public ?string $deployment_uuid = null
) { ) {
} }
public function handle() public function handle()
{ {
try { try {
$this->application = Application::findOrFail($this->application_id); if ($this->status === ProcessStatus::CLOSED) {
$this->preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id); $this->delete_comment();
return;
$this->build_logs_url = base_url() . "/project/{$this->application->environment->project->uuid}/{$this->application->environment->name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; } else if ($this->status === ProcessStatus::IN_PROGRESS) {
if ($this->status === ProcessStatus::IN_PROGRESS->value) {
$this->body = "The preview deployment is in progress. 🟡\n\n"; $this->body = "The preview deployment is in progress. 🟡\n\n";
} } else if ($this->status === ProcessStatus::FINISHED) {
if ($this->status === ProcessStatus::FINISHED->value) {
$this->body = "The preview deployment is ready. 🟢\n\n"; $this->body = "The preview deployment is ready. 🟢\n\n";
if ($this->preview->fqdn) { if ($this->preview->fqdn) {
$this->body .= "[Open Preview]({$this->preview->fqdn}) | "; $this->body .= "[Open Preview]({$this->preview->fqdn}) | ";
} }
} } else if ($this->status === ProcessStatus::ERROR) {
if ($this->status === ProcessStatus::ERROR->value) {
$this->body = "The preview deployment failed. 🔴\n\n"; $this->body = "The preview deployment failed. 🔴\n\n";
} }
$this->build_logs_url = base_url() . "/project/{$this->application->environment->project->uuid}/{$this->application->environment->name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}";
$this->body .= "[Open Build Logs](" . $this->build_logs_url . ")\n\n\n"; $this->body .= "[Open Build Logs](" . $this->build_logs_url . ")\n\n\n";
$this->body .= "Last updated at: " . now()->toDateTimeString() . " CET"; $this->body .= "Last updated at: " . now()->toDateTimeString() . " CET";
@ -77,10 +73,14 @@ private function update_comment()
private function create_comment() private function create_comment()
{ {
['data' => $data] = githubApi(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/{$this->pull_request_id}/comments", method: 'post', data: [ ['data' => $data] = githubApi(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/{$this->preview->pull_request_id}/comments", method: 'post', data: [
'body' => $this->body, 'body' => $this->body,
]); ]);
$this->preview->pull_request_issue_comment_id = $data['id']; $this->preview->pull_request_issue_comment_id = $data['id'];
$this->preview->save(); $this->preview->save();
} }
private function delete_comment()
{
githubApi(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/comments/{$this->preview->pull_request_issue_comment_id}", method: 'delete');
}
} }

View File

@ -69,6 +69,7 @@ function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $m
} }
$json = $response->json(); $json = $response->json();
if ($response->failed() && $throwError) { if ($response->failed() && $throwError) {
ray($json);
throw new \Exception("Failed to get data from {$source->name} with error:<br><br>" . $json['message'] . "<br><br>Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC'); throw new \Exception("Failed to get data from {$source->name} with error:<br><br>" . $json['message'] . "<br><br>Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC');
} }
return [ return [

View File

@ -1,5 +1,7 @@
<?php <?php
use App\Enums\ProcessStatus;
use App\Jobs\ApplicationPullRequestUpdateJob;
use App\Jobs\SubscriptionInvoiceFailedJob; use App\Jobs\SubscriptionInvoiceFailedJob;
use App\Jobs\SubscriptionTrialEndedJob; use App\Jobs\SubscriptionTrialEndedJob;
use App\Jobs\SubscriptionTrialEndsSoonJob; use App\Jobs\SubscriptionTrialEndsSoonJob;
@ -470,6 +472,7 @@
if ($action === 'closed' || $action === 'close') { if ($action === 'closed' || $action === 'close') {
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first(); $found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
if ($found) { if ($found) {
ApplicationPullRequestUpdateJob::dispatchSync(application: $application, preview: $found, status: ProcessStatus::CLOSED);
$found->delete(); $found->delete();
$container_name = generateApplicationContainerName($application, $pull_request_id); $container_name = generateApplicationContainerName($application, $pull_request_id);
// ray('Stopping container: ' . $container_name); // ray('Stopping container: ' . $container_name);