feat(railpack): expose COOLIFY_* vars at build time and generalize buildpack control flag
Mirrors Nixpacks behavior: inject COOLIFY_* and SOURCE_COMMIT into railpack build variables so apps (e.g. SPAs baking public URLs) can read them via /run/secrets/<KEY>. Rename is_nixpacks → is_buildpack_control to cover both NIXPACKS_ and RAILPACK_ prefixed keys. Update the env variable view and appends list accordingly. Promote generate_coolify_env_variables to protected for testability.
This commit is contained in:
parent
21eac6654f
commit
b6ca6b1b20
5 changed files with 122 additions and 14 deletions
|
|
@ -2527,6 +2527,14 @@ private function railpack_build_variables(): Collection
|
|||
$variables->put('RAILPACK_INSTALL_CMD', $this->application->install_command);
|
||||
}
|
||||
|
||||
// Mirror Nixpacks behavior: expose COOLIFY_* and SOURCE_COMMIT to the build so apps
|
||||
// (e.g. SPAs baking the public URL) can read them via /run/secrets/<KEY>.
|
||||
foreach ($this->generate_coolify_env_variables(forBuildTime: true) as $key => $value) {
|
||||
if (! is_null($value) && $value !== '') {
|
||||
$variables->put($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $variables;
|
||||
}
|
||||
|
||||
|
|
@ -2829,7 +2837,7 @@ private function build_railpack_static_image(): void
|
|||
);
|
||||
}
|
||||
|
||||
private function generate_coolify_env_variables(bool $forBuildTime = false): Collection
|
||||
protected function generate_coolify_env_variables(bool $forBuildTime = false): Collection
|
||||
{
|
||||
$coolify_envs = collect([]);
|
||||
$local_branch = $this->branch;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class EnvironmentVariable extends BaseModel
|
|||
'resourceable_id' => 'integer',
|
||||
];
|
||||
|
||||
protected $appends = ['real_value', 'is_shared', 'is_really_required', 'is_nixpacks', 'is_coolify'];
|
||||
protected $appends = ['real_value', 'is_shared', 'is_really_required', 'is_buildpack_control', 'is_coolify'];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
|
|
@ -215,16 +215,10 @@ protected function isReallyRequired(): Attribute
|
|||
);
|
||||
}
|
||||
|
||||
protected function isNixpacks(): Attribute
|
||||
protected function isBuildpackControl(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
if (str($this->key)->startsWith('NIXPACKS_')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
get: fn () => self::isBuildpackControlKey($this->key),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
<x-forms.checkbox instantSave id="is_multiline" label="Is Multiline?" />
|
||||
@endif
|
||||
@else
|
||||
@if (!$env->is_nixpacks)
|
||||
@if (!$env->is_buildpack_control)
|
||||
<x-forms.checkbox instantSave id="is_buildtime"
|
||||
helper="Make this variable available during Docker build process. Useful for build secrets and dependencies."
|
||||
label="Available at Buildtime" />
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
helper="Make this variable available in the running container at runtime."
|
||||
label="Available at Runtime" />
|
||||
@if (!$isMagicVariable)
|
||||
@if (!$env->is_nixpacks)
|
||||
@if (!$env->is_buildpack_control)
|
||||
<x-forms.checkbox instantSave id="is_multiline" label="Is Multiline?" />
|
||||
@if ($is_multiline === false)
|
||||
<x-forms.checkbox instantSave id="is_literal"
|
||||
|
|
@ -236,7 +236,7 @@
|
|||
<x-forms.checkbox instantSave id="is_multiline" label="Is Multiline?" />
|
||||
@endif
|
||||
@else
|
||||
@if (!$env->is_nixpacks)
|
||||
@if (!$env->is_buildpack_control)
|
||||
<x-forms.checkbox instantSave id="is_buildtime"
|
||||
helper="Make this variable available during Docker build process. Useful for build secrets and dependencies."
|
||||
label="Available at Buildtime" />
|
||||
|
|
@ -245,7 +245,7 @@
|
|||
helper="Make this variable available in the running container at runtime."
|
||||
label="Available at Runtime" />
|
||||
@if (!$isMagicVariable)
|
||||
@if (!$env->is_nixpacks)
|
||||
@if (!$env->is_buildpack_control)
|
||||
<x-forms.checkbox instantSave id="is_multiline" label="Is Multiline?" />
|
||||
@if ($is_multiline === false)
|
||||
<x-forms.checkbox instantSave id="is_literal"
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
$job = Mockery::mock(ApplicationDeploymentJob::class)->makePartial();
|
||||
$job->shouldAllowMockingProtectedMethods();
|
||||
$job->shouldReceive('generate_coolify_env_variables')->andReturn(collect([]));
|
||||
|
||||
$reflection = new ReflectionClass(ApplicationDeploymentJob::class);
|
||||
$applicationProperty = $reflection->getProperty('application');
|
||||
|
|
@ -102,6 +103,7 @@
|
|||
|
||||
$job = Mockery::mock(ApplicationDeploymentJob::class)->makePartial();
|
||||
$job->shouldAllowMockingProtectedMethods();
|
||||
$job->shouldReceive('generate_coolify_env_variables')->andReturn(collect([]));
|
||||
|
||||
$reflection = new ReflectionClass(ApplicationDeploymentJob::class);
|
||||
$applicationProperty = $reflection->getProperty('application');
|
||||
|
|
@ -124,3 +126,70 @@
|
|||
'RAILPACK_PREVIEW_ONLY' => 'preview-value',
|
||||
]);
|
||||
});
|
||||
|
||||
it('merges coolify env variables into railpack build variables', function () {
|
||||
$application = Mockery::mock(Application::class);
|
||||
$application->shouldReceive('getAttribute')->with('install_command')->andReturn(null);
|
||||
|
||||
$userVar = Mockery::mock(EnvironmentVariable::class)->makePartial();
|
||||
$userVar->forceFill([
|
||||
'key' => 'MY_BUILD_VAR',
|
||||
'is_literal' => false,
|
||||
'is_multiline' => false,
|
||||
]);
|
||||
$userVar->shouldReceive('getResolvedValueWithServer')->once()->with(Mockery::type(Server::class))->andReturn('hello');
|
||||
|
||||
$envQuery = Mockery::mock();
|
||||
$envQuery->shouldReceive('where')->with('is_buildtime', true)->once()->andReturnSelf();
|
||||
$envQuery->shouldReceive('get')->once()->andReturn(collect([$userVar]));
|
||||
$application->shouldReceive('environment_variables')->once()->andReturn($envQuery);
|
||||
|
||||
$job = Mockery::mock(ApplicationDeploymentJob::class)->makePartial();
|
||||
$job->shouldAllowMockingProtectedMethods();
|
||||
$job->shouldReceive('generate_coolify_env_variables')
|
||||
->with(true)
|
||||
->andReturn(collect([
|
||||
'COOLIFY_URL' => 'https://app.example.com',
|
||||
'COOLIFY_FQDN' => 'app.example.com',
|
||||
'COOLIFY_BRANCH' => 'main',
|
||||
'COOLIFY_RESOURCE_UUID' => 'app-uuid',
|
||||
'SOURCE_COMMIT' => 'abc123',
|
||||
'EMPTY_VAR' => '',
|
||||
'NULL_VAR' => null,
|
||||
]));
|
||||
|
||||
$reflection = new ReflectionClass(ApplicationDeploymentJob::class);
|
||||
$applicationProperty = $reflection->getProperty('application');
|
||||
$applicationProperty->setAccessible(true);
|
||||
$applicationProperty->setValue($job, $application);
|
||||
|
||||
$pullRequestProperty = $reflection->getProperty('pull_request_id');
|
||||
$pullRequestProperty->setAccessible(true);
|
||||
$pullRequestProperty->setValue($job, 0);
|
||||
|
||||
$mainServerProperty = $reflection->getProperty('mainServer');
|
||||
$mainServerProperty->setAccessible(true);
|
||||
$mainServerProperty->setValue($job, Mockery::mock(Server::class));
|
||||
|
||||
$method = $reflection->getMethod('generate_railpack_env_variables');
|
||||
$method->setAccessible(true);
|
||||
$variables = $method->invoke($job);
|
||||
|
||||
expect($variables->all())->toBe([
|
||||
'MY_BUILD_VAR' => 'hello',
|
||||
'COOLIFY_URL' => 'https://app.example.com',
|
||||
'COOLIFY_FQDN' => 'app.example.com',
|
||||
'COOLIFY_BRANCH' => 'main',
|
||||
'COOLIFY_RESOURCE_UUID' => 'app-uuid',
|
||||
'SOURCE_COMMIT' => 'abc123',
|
||||
]);
|
||||
|
||||
$envArgsProperty = $reflection->getProperty('env_railpack_args');
|
||||
$envArgsProperty->setAccessible(true);
|
||||
$envArgs = $envArgsProperty->getValue($job);
|
||||
|
||||
expect($envArgs)->toContain("--env 'COOLIFY_URL=https://app.example.com'");
|
||||
expect($envArgs)->toContain("--env 'SOURCE_COMMIT=abc123'");
|
||||
expect($envArgs)->not->toContain('EMPTY_VAR');
|
||||
expect($envArgs)->not->toContain('NULL_VAR');
|
||||
});
|
||||
|
|
|
|||
37
tests/Unit/EnvironmentVariableBuildpackControlTest.php
Normal file
37
tests/Unit/EnvironmentVariableBuildpackControlTest.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use App\Models\EnvironmentVariable;
|
||||
|
||||
it('flags NIXPACKS_ keys as buildpack control variables', function () {
|
||||
$env = new EnvironmentVariable;
|
||||
$env->key = 'NIXPACKS_NODE_VERSION';
|
||||
|
||||
expect($env->is_buildpack_control)->toBeTrue();
|
||||
});
|
||||
|
||||
it('flags RAILPACK_ keys as buildpack control variables', function () {
|
||||
$env = new EnvironmentVariable;
|
||||
$env->key = 'RAILPACK_NODE_VERSION';
|
||||
|
||||
expect($env->is_buildpack_control)->toBeTrue();
|
||||
});
|
||||
|
||||
it('does not flag user-defined keys as buildpack control variables', function () {
|
||||
$env = new EnvironmentVariable;
|
||||
$env->key = 'MY_BUILD_VAR';
|
||||
|
||||
expect($env->is_buildpack_control)->toBeFalse();
|
||||
});
|
||||
|
||||
it('does not flag empty key as buildpack control variable', function () {
|
||||
$env = new EnvironmentVariable;
|
||||
|
||||
expect($env->is_buildpack_control)->toBeFalse();
|
||||
});
|
||||
|
||||
it('lists is_buildpack_control in appends and drops legacy is_nixpacks', function () {
|
||||
$env = new EnvironmentVariable;
|
||||
|
||||
expect($env->getAppends())->toContain('is_buildpack_control');
|
||||
expect($env->getAppends())->not->toContain('is_nixpacks');
|
||||
});
|
||||
Loading…
Reference in a new issue