From ace643d3d8375308ac98f9b6d1e546559d1bbd1d Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:38:58 +0200 Subject: [PATCH] fix(railpack): query buildtime env vars directly instead of via computed attribute Replace `railpack_environment_variables_collection()` helper (which returned pre-filtered Eloquent attribute collections) with inline queries on `environment_variables()` / `environment_variables_preview()` filtered by `is_buildtime`. This ensures Railpack build variables are sourced from the same query path as the rest of the deployment pipeline and avoids relying on a now-removed accessor that silently included all railpack vars regardless of build context. --- app/Jobs/ApplicationDeploymentJob.php | 25 +++++++++++-------- ...icationDeploymentRailpackEnvParityTest.php | 14 ++++++----- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 420fe8fd4..6f9aabfd5 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -2483,15 +2483,6 @@ private function generate_railpack_env_variables(): Collection return $variables; } - private function railpack_environment_variables_collection(): Collection - { - if ($this->pull_request_id === 0) { - return $this->application->railpack_environment_variables; - } - - return $this->application->railpack_environment_variables_preview; - } - private function normalize_resolved_build_variable_value(EnvironmentVariable $environmentVariable): ?string { $resolvedValue = $environmentVariable->getResolvedValueWithServer($this->mainServer); @@ -2506,9 +2497,23 @@ private function normalize_resolved_build_variable_value(EnvironmentVariable $en return $resolvedValue; } + /** + * All buildtime variables that must reach the Railpack build. + * + * Railpack's BuildKit frontend treats every `--env` passed to `railpack prepare` + * as a build secret entry in the generated plan, then pairs it with `--secret id=,env=` + * on `docker buildx build`. Because Railpack's schema disallows top-level `variables` + * (unlike Nixpacks, which bakes variables into the plan), this `--env` → `--secret` + * channel is the only way user-defined buildtime variables become available to + * commands declared with `useSecrets: true`. + */ private function railpack_build_variables(): Collection { - $variables = $this->railpack_environment_variables_collection() + $envCollection = $this->pull_request_id === 0 + ? $this->application->environment_variables()->where('is_buildtime', true)->get() + : $this->application->environment_variables_preview()->where('is_buildtime', true)->get(); + + $variables = $envCollection ->mapWithKeys(function (EnvironmentVariable $environmentVariable) { $value = $this->normalize_resolved_build_variable_value($environmentVariable); if (is_null($value) || $value === '') { diff --git a/tests/Unit/ApplicationDeploymentRailpackEnvParityTest.php b/tests/Unit/ApplicationDeploymentRailpackEnvParityTest.php index 8ed7b2c41..487268fb6 100644 --- a/tests/Unit/ApplicationDeploymentRailpackEnvParityTest.php +++ b/tests/Unit/ApplicationDeploymentRailpackEnvParityTest.php @@ -41,9 +41,10 @@ ]); $nullValue->shouldReceive('getResolvedValueWithServer')->once()->with(Mockery::type(Server::class))->andReturn(null); - $application->shouldReceive('getAttribute') - ->with('railpack_environment_variables') - ->andReturn(collect([$nodeVersion, $literalValue, $jsonValue, $nullValue])); + $envQuery = Mockery::mock(); + $envQuery->shouldReceive('where')->with('is_buildtime', true)->once()->andReturnSelf(); + $envQuery->shouldReceive('get')->once()->andReturn(collect([$nodeVersion, $literalValue, $jsonValue, $nullValue])); + $application->shouldReceive('environment_variables')->once()->andReturn($envQuery); $job = Mockery::mock(ApplicationDeploymentJob::class)->makePartial(); $job->shouldAllowMockingProtectedMethods(); @@ -94,9 +95,10 @@ ]); $previewValue->shouldReceive('getResolvedValueWithServer')->once()->with(Mockery::type(Server::class))->andReturn('preview-value'); - $application->shouldReceive('getAttribute') - ->with('railpack_environment_variables_preview') - ->andReturn(collect([$previewValue])); + $previewQuery = Mockery::mock(); + $previewQuery->shouldReceive('where')->with('is_buildtime', true)->once()->andReturnSelf(); + $previewQuery->shouldReceive('get')->once()->andReturn(collect([$previewValue])); + $application->shouldReceive('environment_variables_preview')->once()->andReturn($previewQuery); $job = Mockery::mock(ApplicationDeploymentJob::class)->makePartial(); $job->shouldAllowMockingProtectedMethods();