mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(env): quote old multi-line JSON values in the .env file
Variables saved before exact escaping wrote JSON objects and arrays without quotes. A multi-line JSON value broke the .env file, so Docker Compose stopped the deployment. These values now use exact escaping, which gives the container the same value as before beta.463. Closes #8279 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a7b7aa350a
commit
0b45d8dd6c
@@ -172,20 +172,23 @@ trait HasSecretManager
|
||||
}
|
||||
|
||||
/**
|
||||
* The old escaping puts literal and multiline values in single quotes without escaping. Docker
|
||||
* Compose ends the value at the next quote, so a value with a quote breaks the whole .env file.
|
||||
* The old escaping writes JSON objects and arrays without quotes, so a JSON value with a line
|
||||
* break breaks the whole .env file (#8279). It puts other literal and multiline values in single
|
||||
* quotes without escaping, and Docker Compose ends the value at the next quote.
|
||||
*/
|
||||
private function legacyEnvFileLineIsUnreadable(EnvironmentVariable $environmentVariable): bool
|
||||
{
|
||||
if (! $environmentVariable->is_literal && ! $environmentVariable->is_multiline) {
|
||||
$value = $this->resolvedEnvironmentVariableValue($environmentVariable);
|
||||
|
||||
if (! is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$value = $this->resolvedEnvironmentVariableValue($environmentVariable);
|
||||
if (json_validate($value) && (str_starts_with($value, '{') || str_starts_with($value, '['))) {
|
||||
return str_contains($value, "\n");
|
||||
}
|
||||
|
||||
return is_string($value)
|
||||
&& str_contains($value, "'")
|
||||
&& ! (json_validate($value) && (str_starts_with($value, '{') || str_starts_with($value, '[')));
|
||||
return ($environmentVariable->is_literal || $environmentVariable->is_multiline) && str_contains($value, "'");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1936,6 +1936,22 @@ it('writes a readable runtime env line for legacy literal values with a single q
|
||||
expect($runtimeEnvs)->toContain('LEGACY_QUOTE="it\'s"');
|
||||
});
|
||||
|
||||
it('writes a readable runtime env line for legacy multiline JSON values', function () {
|
||||
[$application, $server] = makeDeploymentControlVarFixture();
|
||||
$json = "{\n \"type\": \"service_account\"\n}";
|
||||
|
||||
$variable = createApplicationEnvironmentVariable($application, ['key' => 'GOOGLE_CREDENTIALS_JSON', 'value' => $json, 'is_multiline' => true, 'is_runtime' => true, 'is_buildtime' => false]);
|
||||
$variable->uses_legacy_escaping = true;
|
||||
$variable->save();
|
||||
|
||||
[$job, $reflection] = makeControlVarFilteringJob($application->fresh(), $server);
|
||||
|
||||
/** @var Collection $runtimeEnvs */
|
||||
$runtimeEnvs = invokeDeploymentJobMethod($job, $reflection, 'generate_runtime_environment_variables');
|
||||
|
||||
expect($runtimeEnvs)->toContain('GOOGLE_CREDENTIALS_JSON='.escapeComposeEnvFileValue($json));
|
||||
});
|
||||
|
||||
it('keeps the old runtime env format for preview variables saved before exact escaping', function () {
|
||||
[$application, $server] = makeDeploymentControlVarFixture();
|
||||
|
||||
|
||||
@@ -129,6 +129,19 @@ test('legacy literal and multiline variables with a single quote get a line that
|
||||
->and($this->service->legacyEscapingChangesValue($literal))->toBeFalse();
|
||||
});
|
||||
|
||||
test('legacy multiline json variables get a line that docker compose can read', function (array $flags) {
|
||||
$json = "{\n \"type\": \"service_account\"\n}";
|
||||
$multiline = legacyVariable($this->service, ['key' => 'GOOGLE_CREDENTIALS_JSON', 'value' => $json, ...$flags]);
|
||||
$singleLine = legacyVariable($this->service, ['key' => 'SINGLE_LINE_JSON', 'value' => '{"a":"b"}', ...$flags]);
|
||||
|
||||
expect($this->service->composeEnvironmentFileLine($multiline))->toBe("GOOGLE_CREDENTIALS_JSON=\"{\n \\\"type\\\": \\\"service_account\\\"\n}\"")
|
||||
->and($this->service->composeEnvironmentFileLine($singleLine))->toBe('SINGLE_LINE_JSON={"a":"b"}')
|
||||
->and($this->service->legacyEscapingChangesValue($multiline))->toBeFalse();
|
||||
})->with([
|
||||
'multiline' => [['is_multiline' => true]],
|
||||
'plain' => [[]],
|
||||
]);
|
||||
|
||||
test('legacy database variables keep the old compose environment format', function () {
|
||||
$database = StandalonePostgresql::forceCreate([
|
||||
'uuid' => 'postgres-legacy-test',
|
||||
|
||||
Reference in New Issue
Block a user