From a54e70b4e08bec81266ca759a2db17c31cd46dc1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 13 May 2026 11:49:15 +0200 Subject: [PATCH] fix(deployments): skip registry image tag for previews Only push the configured Docker registry image tag for production deployments, and cover preview and missing-tag cases with unit tests. --- app/Jobs/ApplicationDeploymentJob.php | 11 +++- .../DockerImagePreviewTagResolutionTest.php | 57 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 2e43456b8..5e554eb03 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -1106,7 +1106,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue 'hidden' => true, ], ); - if ($this->application->docker_registry_image_tag) { + if ($this->shouldPushDockerRegistryImageTag()) { // Tag image with docker_registry_image_tag $this->application_deployment_queue->addLogEntry("Tagging and pushing image with {$this->application->docker_registry_image_tag} tag."); $this->execute_remote_command( @@ -1130,6 +1130,15 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue } } + private function shouldPushDockerRegistryImageTag(): bool + { + if (blank($this->application->docker_registry_image_tag)) { + return false; + } + + return $this->pull_request_id === 0; + } + private function generate_image_names() { if ($this->application->dockerfile) { diff --git a/tests/Unit/DockerImagePreviewTagResolutionTest.php b/tests/Unit/DockerImagePreviewTagResolutionTest.php index e6d0b6a4e..17f7d7b9b 100644 --- a/tests/Unit/DockerImagePreviewTagResolutionTest.php +++ b/tests/Unit/DockerImagePreviewTagResolutionTest.php @@ -74,3 +74,60 @@ it('falls back to latest when neither preview nor application tags are set', fun expect($method->invoke($job))->toBe('latest'); }); + +function makeDockerRegistryTagPushJob(int $pullRequestId, ?string $dockerRegistryImageTag): object +{ + $reflection = new ReflectionClass(ApplicationDeploymentJob::class); + $job = $reflection->newInstanceWithoutConstructor(); + + $pullRequestProperty = $reflection->getProperty('pull_request_id'); + $pullRequestProperty->setAccessible(true); + $pullRequestProperty->setValue($job, $pullRequestId); + + $applicationProperty = $reflection->getProperty('application'); + $applicationProperty->setAccessible(true); + $applicationProperty->setValue($job, new Application([ + 'docker_registry_image_tag' => $dockerRegistryImageTag, + ])); + + return $job; +} + +it('pushes the configured docker registry image tag for production deployments', function () { + $reflection = new ReflectionClass(ApplicationDeploymentJob::class); + $job = makeDockerRegistryTagPushJob( + pullRequestId: 0, + dockerRegistryImageTag: 'latest', + ); + + $method = $reflection->getMethod('shouldPushDockerRegistryImageTag'); + $method->setAccessible(true); + + expect($method->invoke($job))->toBeTrue(); +}); + +it('skips the configured docker registry image tag for preview deployments', function () { + $reflection = new ReflectionClass(ApplicationDeploymentJob::class); + $job = makeDockerRegistryTagPushJob( + pullRequestId: 42, + dockerRegistryImageTag: 'latest', + ); + + $method = $reflection->getMethod('shouldPushDockerRegistryImageTag'); + $method->setAccessible(true); + + expect($method->invoke($job))->toBeFalse(); +}); + +it('skips pushing a configured docker registry image tag when no tag is set', function () { + $reflection = new ReflectionClass(ApplicationDeploymentJob::class); + $job = makeDockerRegistryTagPushJob( + pullRequestId: 0, + dockerRegistryImageTag: null, + ); + + $method = $reflection->getMethod('shouldPushDockerRegistryImageTag'); + $method->setAccessible(true); + + expect($method->invoke($job))->toBeFalse(); +});