mirror of
https://github.com/tiennm99/coolify.git
synced 2026-08-19 06:23:35 +00:00
fix(environment): keep Compose self-references editable
This commit is contained in:
@@ -714,6 +714,12 @@ class All extends Component
|
||||
// Extract all hard-coded variables
|
||||
$hardcodedVars = extractHardcodedEnvironmentVariables($dockerComposeRaw);
|
||||
|
||||
// Compose self-references are inputs supplied through Coolify's .env file,
|
||||
// not hard-coded values. Keep them editable in the environment variables UI.
|
||||
$hardcodedVars = $hardcodedVars->reject(
|
||||
fn (array $variable): bool => $this->isSelfReferencingComposeVariable($variable)
|
||||
);
|
||||
|
||||
// Filter out magic variables (SERVICE_FQDN_*, SERVICE_URL_*, SERVICE_NAME_*)
|
||||
$hardcodedVars = $hardcodedVars->filter(function ($var) {
|
||||
$key = $var['key'];
|
||||
@@ -755,7 +761,14 @@ class All extends Component
|
||||
return [];
|
||||
}
|
||||
|
||||
return extractHardcodedEnvironmentVariables($dockerComposeRaw)
|
||||
$assignments = extractHardcodedEnvironmentVariables($dockerComposeRaw);
|
||||
$editableKeys = $assignments
|
||||
->filter(fn (array $variable): bool => $this->isSelfReferencingComposeVariable($variable))
|
||||
->pluck('key')
|
||||
->unique();
|
||||
|
||||
return $assignments
|
||||
->reject(fn (array $variable): bool => $editableKeys->contains($variable['key']))
|
||||
->pluck('key')
|
||||
->reject(fn (string $key): bool => str($key)->startsWith(['SERVICE_FQDN_', 'SERVICE_URL_', 'SERVICE_NAME_']))
|
||||
->unique()
|
||||
@@ -763,6 +776,28 @@ class All extends Component
|
||||
->all();
|
||||
}
|
||||
|
||||
private function isSelfReferencingComposeVariable(array $variable): bool
|
||||
{
|
||||
$value = $variable['value'] ?? null;
|
||||
if (! is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($value === '$'.$variable['key']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$reference = extractBalancedBraceContent($value);
|
||||
if ($reference === null || $reference['start'] !== 1 || $reference['end'] !== strlen($value) - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$splitReference = splitOnOperatorOutsideNested($reference['content']);
|
||||
$referencedKey = $splitReference['variable'] ?? $reference['content'];
|
||||
|
||||
return $referencedKey === $variable['key'];
|
||||
}
|
||||
|
||||
public function getDevView()
|
||||
{
|
||||
$this->variables = $this->formatEnvironmentVariables($this->getEnvironmentVariables(false, false));
|
||||
|
||||
@@ -182,6 +182,42 @@ YAML,
|
||||
->toBe(['API_TOKEN']);
|
||||
});
|
||||
|
||||
it('keeps Compose self-referencing environment variables editable without changing Compose', function () {
|
||||
$dockerCompose = <<<'YAML'
|
||||
services:
|
||||
app:
|
||||
image: nginx
|
||||
environment:
|
||||
API_TOKEN: ${API_TOKEN}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||
FIXED_VALUE: production
|
||||
YAML;
|
||||
|
||||
$service = Service::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'docker_compose_raw' => $dockerCompose,
|
||||
]);
|
||||
|
||||
foreach (['API_TOKEN', 'LOG_LEVEL'] as $key) {
|
||||
EnvironmentVariable::create([
|
||||
'key' => $key,
|
||||
'resourceable_type' => Service::class,
|
||||
'resourceable_id' => $service->id,
|
||||
]);
|
||||
}
|
||||
|
||||
$rows = Livewire::test(All::class, ['resource' => $service])
|
||||
->call('loadEnvironmentVariables')
|
||||
->instance()
|
||||
->environmentVariablePageRows;
|
||||
|
||||
expect($rows->where('kind', 'managed')->pluck('environmentVariable.key')->all())
|
||||
->toBe(['API_TOKEN', 'LOG_LEVEL'])
|
||||
->and($rows->where('kind', 'hardcoded')->pluck('environmentVariable.key')->all())
|
||||
->toBe(['FIXED_VALUE'])
|
||||
->and($service->fresh()->docker_compose_raw)->toBe($dockerCompose);
|
||||
});
|
||||
|
||||
it('shows a Compose-defined value as read-only when a managed variable has the same key', function () {
|
||||
$service = Service::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
|
||||
Reference in New Issue
Block a user