diff --git a/app/Jobs/ProcessGithubPullRequestWebhook.php b/app/Jobs/ProcessGithubPullRequestWebhook.php index 54e386676..5a390e8ed 100644 --- a/app/Jobs/ProcessGithubPullRequestWebhook.php +++ b/app/Jobs/ProcessGithubPullRequestWebhook.php @@ -14,6 +14,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Throwable; use Visus\Cuid2\Cuid2; class ProcessGithubPullRequestWebhook implements ShouldBeEncrypted, ShouldQueue @@ -70,16 +71,25 @@ private function handleClosedAction(Application $application): void ->first(); if ($found) { - ApplicationPullRequestUpdateJob::dispatchSync( - application: $application, - preview: $found, - status: ProcessStatus::CLOSED - ); - - CleanupPreviewDeployment::run($application, $this->pullRequestId, $found); + try { + $this->dispatchPullRequestClosedUpdate($application, $found); + } catch (Throwable $e) { + report($e); + } finally { + CleanupPreviewDeployment::run($application, $this->pullRequestId, $found); + } } } + protected function dispatchPullRequestClosedUpdate(Application $application, ApplicationPreview $preview): void + { + ApplicationPullRequestUpdateJob::dispatchSync( + application: $application, + preview: $preview, + status: ProcessStatus::CLOSED + ); + } + private function handleOpenAction(Application $application, ?GithubApp $githubApp): void { if (! $application->isPRDeployable()) { diff --git a/tests/Feature/ProcessGithubPullRequestWebhookTest.php b/tests/Feature/ProcessGithubPullRequestWebhookTest.php new file mode 100644 index 000000000..6e0e9241e --- /dev/null +++ b/tests/Feature/ProcessGithubPullRequestWebhookTest.php @@ -0,0 +1,72 @@ + InstanceSettings::firstOrCreate(['id' => 0])); + + $this->team = Team::factory()->create(); + $this->server = Server::factory()->create(['team_id' => $this->team->id]); + $this->destination = StandaloneDocker::where('server_id', $this->server->id)->first(); + $this->project = Project::factory()->create(['team_id' => $this->team->id]); + $this->environment = Environment::factory()->create(['project_id' => $this->project->id]); + + $this->application = Application::factory()->create([ + 'environment_id' => $this->environment->id, + 'destination_id' => $this->destination->id, + 'destination_type' => $this->destination->getMorphClass(), + ]); +}); + +it('cleans up a closed pull request preview when pull request comment cleanup fails', function () { + $preview = ApplicationPreview::create([ + 'application_id' => $this->application->id, + 'pull_request_id' => 42, + 'pull_request_html_url' => 'https://github.com/example/repo/pull/42', + ]); + + CleanupPreviewDeployment::shouldRun() + ->once() + ->withArgs(fn (Application $application, int $pullRequestId, ApplicationPreview $applicationPreview): bool => $application->is($this->application) + && $pullRequestId === 42 + && $applicationPreview->is($preview)) + ->andReturn([ + 'cancelled_deployments' => 0, + 'killed_containers' => 0, + 'status' => 'success', + ]); + + $job = new class( + applicationId: $this->application->id, + githubAppId: null, + action: 'closed', + pullRequestId: 42, + pullRequestHtmlUrl: 'https://github.com/example/repo/pull/42', + pullRequestTitle: null, + beforeSha: null, + afterSha: null, + commitSha: 'HEAD', + authorAssociation: 'OWNER', + fullName: 'example/repo', + ) extends ProcessGithubPullRequestWebhook + { + protected function dispatchPullRequestClosedUpdate(Application $application, ApplicationPreview $preview): void + { + throw new RuntimeException('GitHub comment cleanup failed.'); + } + }; + + $job->handle(); +});