fix(deploy): keep the healthy new container when a rolling update fails late

Laravel runs failed() on a fresh copy of the job, so the in-memory
newVersionIsHealthy flag was always false there and a failure after the
old container stopped removed the only running container. Keep the flag
in the cache, keyed by the deployment UUID.

Closes #12253

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-23 23:03:33 +02:00
co-authored by Claude Opus 5.5
parent 2a7faa1210
commit 1bebdffaff
4 changed files with 131 additions and 22 deletions
@@ -6,6 +6,9 @@ use App\Models\Application;
use App\Models\ApplicationDeploymentQueue;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Queue\TimeoutExceededException;
use Tests\TestCase;
uses(TestCase::class);
/**
* Test to verify that deployment errors are properly logged with comprehensive details.
@@ -91,6 +94,7 @@ it('logs comprehensive error details when failed() is called', function () {
$containerNameProperty = $reflection->getProperty('container_name');
$containerNameProperty->setAccessible(true);
$containerNameProperty->setValue($job, 'test-container');
$reflection->getProperty('deployment_uuid')->setValue($job, 'error-logging-test');
// Mock the failDeployment method to prevent errors
$job->shouldReceive('failDeployment')->andReturn();
@@ -197,6 +201,7 @@ it('handles exceptions with no message gracefully', function () {
$containerNameProperty = $reflection->getProperty('container_name');
$containerNameProperty->setAccessible(true);
$containerNameProperty->setValue($job, 'test-container');
$reflection->getProperty('deployment_uuid')->setValue($job, 'error-logging-test');
$job->shouldReceive('failDeployment')->andReturn();
$job->shouldReceive('execute_remote_command')->andReturn();
@@ -288,6 +293,7 @@ it('logs error code 0 correctly', function () {
$containerNameProperty = $reflection->getProperty('container_name');
$containerNameProperty->setAccessible(true);
$containerNameProperty->setValue($job, 'test-container');
$reflection->getProperty('deployment_uuid')->setValue($job, 'error-logging-test');
$job->shouldReceive('failDeployment')->andReturn();
$job->shouldReceive('execute_remote_command')->andReturn();
@@ -393,6 +399,7 @@ it('logs the configured timeout when the deployment times out', function () {
$containerNameProperty = $reflection->getProperty('container_name');
$containerNameProperty->setValue($job, 'test-container');
$reflection->getProperty('deployment_uuid')->setValue($job, 'error-logging-test');
$job->shouldReceive('failDeployment')->andReturn();
$job->shouldReceive('execute_remote_command')->andReturn();