From cac22f65f4b7ed691f74987c560b991f1a49c10e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 8 Oct 2026 07:18:39 +0200 Subject: [PATCH] fix(deployment): build static buildpack preview images from generated Dockerfile Pull request deployments sent every non-railpack build pack to build_image(), which no longer handles the static build pack since it was moved to build_static_image(). Static preview deployments then failed with "open Dockerfile: no such file or directory". Closes #8238 --- app/Jobs/ApplicationDeploymentJob.php | 15 ++++-- .../PreviewDeploymentStaticBuildpackTest.php | 48 +++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 tests/Unit/PreviewDeploymentStaticBuildpackTest.php diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 4c8b6ca3e9..b93a94a95c 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -2705,11 +2705,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue if ($this->application->build_pack === 'dockerfile') { $this->add_build_env_variables_to_dockerfile(); } - if ($this->application->build_pack === 'railpack') { - $this->build_railpack_image(); - } else { - $this->build_image(); - } + $this->build_pull_request_image(); // This overwrites the build-time .env with ALL variables (build-time + runtime) $this->save_runtime_environment_variables(); @@ -2717,6 +2713,15 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue $this->rolling_update(); } + private function build_pull_request_image(): void + { + match ($this->application->build_pack) { + 'railpack' => $this->build_railpack_image(), + 'static' => $this->build_static_image(), + default => $this->build_image(), + }; + } + private function create_workdir() { if ($this->use_build_server) { diff --git a/tests/Unit/PreviewDeploymentStaticBuildpackTest.php b/tests/Unit/PreviewDeploymentStaticBuildpackTest.php new file mode 100644 index 0000000000..b1026ed20e --- /dev/null +++ b/tests/Unit/PreviewDeploymentStaticBuildpackTest.php @@ -0,0 +1,48 @@ +build_pack = 'static'; + $application->static_image = 'nginx:alpine'; + $application->custom_nginx_configuration = 'server { listen 80; }'; + + $queue = Mockery::mock(ApplicationDeploymentQueue::class); + $queue->shouldReceive('addLogEntry'); + + $commands = []; + $job = Mockery::mock(ApplicationDeploymentJob::class)->makePartial(); + $job->shouldReceive('execute_remote_command')->andReturnUsing(function (...$batch) use (&$commands) { + foreach ($batch as $command) { + $commands[] = $command[0]; + } + }); + + foreach ([ + 'application' => $application, + 'application_deployment_queue' => $queue, + 'deployment_uuid' => 'deployment-uuid', + 'pull_request_id' => 7, + 'workdir' => '/artifacts/deployment-uuid', + 'production_image_name' => 'preview-app:pr-7-abc', + ] as $property => $value) { + (new ReflectionProperty(ApplicationDeploymentJob::class, $property))->setValue($job, $value); + } + + (new ReflectionMethod(ApplicationDeploymentJob::class, 'build_pull_request_image'))->invoke($job); + + $writesGeneratedDockerfile = collect($commands) + ->contains(fn (string $command) => str_contains($command, 'tee /artifacts/deployment-uuid/Dockerfile')); + + expect($writesGeneratedDockerfile)->toBeTrue(); +});