mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-13 20:14:45 +00:00
chore: prepare for PR
This commit is contained in:
1 parent
2310ad5f7f
commit
ec14b55f0a
2 files changed
+114
-240
No files matched your search
@@ -1,144 +1,59 @@
|
||||
<?php
|
||||
|
||||
test('multiline environment variables are properly escaped for docker build args', function () {
|
||||
$sshKey = '-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk
|
||||
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA
|
||||
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
|
||||
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
-----END OPENSSH PRIVATE KEY-----';
|
||||
|
||||
test('generateDockerBuildArgs returns only keys without values', function () {
|
||||
$variables = [
|
||||
['key' => 'SSH_PRIVATE_KEY', 'value' => "'{$sshKey}'", 'is_multiline' => true],
|
||||
['key' => 'SSH_PRIVATE_KEY', 'value' => "'some-ssh-key'", 'is_multiline' => true],
|
||||
['key' => 'REGULAR_VAR', 'value' => 'simple value', 'is_multiline' => false],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
|
||||
// SSH key should use double quotes and have proper escaping
|
||||
$sshArg = $buildArgs->first();
|
||||
expect($sshArg)->toStartWith('--build-arg SSH_PRIVATE_KEY="');
|
||||
expect($sshArg)->toEndWith('"');
|
||||
expect($sshArg)->toContain('BEGIN OPENSSH PRIVATE KEY');
|
||||
expect($sshArg)->not->toContain("'BEGIN"); // Should not have the wrapper single quotes
|
||||
|
||||
// Regular var should use escapeshellarg (single quotes)
|
||||
$regularArg = $buildArgs->last();
|
||||
expect($regularArg)->toBe("--build-arg REGULAR_VAR='simple value'");
|
||||
// Docker gets values from the environment, so only keys should be in build args
|
||||
expect($buildArgs->first())->toBe('--build-arg SSH_PRIVATE_KEY');
|
||||
expect($buildArgs->last())->toBe('--build-arg REGULAR_VAR');
|
||||
});
|
||||
|
||||
test('multiline variables with special bash characters are escaped correctly', function () {
|
||||
$valueWithSpecialChars = "line1\nline2 with \"quotes\"\nline3 with \$variables\nline4 with `backticks`";
|
||||
test('generateDockerBuildArgs works with collection of objects', function () {
|
||||
$variables = collect([
|
||||
(object) ['key' => 'VAR1', 'value' => 'value1', 'is_multiline' => false],
|
||||
(object) ['key' => 'VAR2', 'value' => "'multiline\nvalue'", 'is_multiline' => true],
|
||||
]);
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
expect($buildArgs)->toHaveCount(2);
|
||||
expect($buildArgs->values()->toArray())->toBe([
|
||||
'--build-arg VAR1',
|
||||
'--build-arg VAR2',
|
||||
]);
|
||||
});
|
||||
|
||||
test('generateDockerBuildArgs collection can be imploded into valid command string', function () {
|
||||
$variables = [
|
||||
['key' => 'SPECIAL_VALUE', 'value' => "'{$valueWithSpecialChars}'", 'is_multiline' => true],
|
||||
['key' => 'COOLIFY_URL', 'value' => 'http://example.com', 'is_multiline' => false],
|
||||
['key' => 'COOLIFY_BRANCH', 'value' => 'main', 'is_multiline' => false],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
|
||||
// The collection must be imploded to a string for command interpolation
|
||||
// This was the bug: Collection was interpolated as JSON instead of a space-separated string
|
||||
$argsString = $buildArgs->implode(' ');
|
||||
expect($argsString)->toBe('--build-arg COOLIFY_URL --build-arg COOLIFY_BRANCH');
|
||||
|
||||
// Verify it does NOT produce JSON when cast to string
|
||||
expect($argsString)->not->toContain('{');
|
||||
expect($argsString)->not->toContain('}');
|
||||
});
|
||||
|
||||
test('generateDockerBuildArgs handles variables without is_multiline', function () {
|
||||
$variables = [
|
||||
['key' => 'NO_FLAG_VAR', 'value' => 'some value'],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// Verify double quotes are escaped
|
||||
expect($arg)->toContain('\\"quotes\\"');
|
||||
// Verify dollar signs are escaped
|
||||
expect($arg)->toContain('\\$variables');
|
||||
// Verify backticks are escaped
|
||||
expect($arg)->toContain('\\`backticks\\`');
|
||||
});
|
||||
|
||||
test('single-line environment variables use escapeshellarg', function () {
|
||||
$variables = [
|
||||
['key' => 'SIMPLE_VAR', 'value' => 'simple value with spaces', 'is_multiline' => false],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// Should use single quotes from escapeshellarg
|
||||
expect($arg)->toBe("--build-arg SIMPLE_VAR='simple value with spaces'");
|
||||
});
|
||||
|
||||
test('multiline certificate with newlines is preserved', function () {
|
||||
$certificate = '-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRkSvMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTkwOTE3MDUzMzI5WhcNMjkwOTE0MDUzMzI5WjBF
|
||||
-----END CERTIFICATE-----';
|
||||
|
||||
$variables = [
|
||||
['key' => 'TLS_CERT', 'value' => "'{$certificate}'", 'is_multiline' => true],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// Newlines should be preserved in the output
|
||||
expect($arg)->toContain("\n");
|
||||
expect($arg)->toContain('BEGIN CERTIFICATE');
|
||||
expect($arg)->toContain('END CERTIFICATE');
|
||||
expect(substr_count($arg, "\n"))->toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('multiline JSON configuration is properly escaped', function () {
|
||||
$jsonConfig = '{
|
||||
"key": "value",
|
||||
"nested": {
|
||||
"array": [1, 2, 3]
|
||||
}
|
||||
}';
|
||||
|
||||
$variables = [
|
||||
['key' => 'JSON_CONFIG', 'value' => "'{$jsonConfig}'", 'is_multiline' => true],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// All double quotes in JSON should be escaped
|
||||
expect($arg)->toContain('\\"key\\"');
|
||||
expect($arg)->toContain('\\"value\\"');
|
||||
expect($arg)->toContain('\\"nested\\"');
|
||||
});
|
||||
|
||||
test('empty multiline variable is handled correctly', function () {
|
||||
$variables = [
|
||||
['key' => 'EMPTY_VAR', 'value' => "''", 'is_multiline' => true],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
expect($arg)->toBe('--build-arg EMPTY_VAR=""');
|
||||
});
|
||||
|
||||
test('multiline variable with only newlines', function () {
|
||||
$onlyNewlines = "\n\n\n";
|
||||
|
||||
$variables = [
|
||||
['key' => 'NEWLINES_ONLY', 'value' => "'{$onlyNewlines}'", 'is_multiline' => true],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
expect($arg)->toContain("\n");
|
||||
// Should have 3 newlines preserved
|
||||
expect(substr_count($arg, "\n"))->toBe(3);
|
||||
});
|
||||
|
||||
test('multiline variable with backslashes is escaped correctly', function () {
|
||||
$valueWithBackslashes = "path\\to\\file\nC:\\Windows\\System32";
|
||||
|
||||
$variables = [
|
||||
['key' => 'PATH_VAR', 'value' => "'{$valueWithBackslashes}'", 'is_multiline' => true],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// Backslashes should be doubled
|
||||
expect($arg)->toContain('path\\\\to\\\\file');
|
||||
expect($arg)->toContain('C:\\\\Windows\\\\System32');
|
||||
expect($arg)->toBe('--build-arg NO_FLAG_VAR');
|
||||
});
|
||||
|
||||
test('generateDockerEnvFlags produces correct format', function () {
|
||||
@@ -155,54 +70,14 @@ test('generateDockerEnvFlags produces correct format', function () {
|
||||
expect($envFlags)->toContain('line2');
|
||||
});
|
||||
|
||||
test('helper functions work with collection input', function () {
|
||||
test('generateDockerEnvFlags works with collection input', function () {
|
||||
$variables = collect([
|
||||
(object) ['key' => 'VAR1', 'value' => 'value1', 'is_multiline' => false],
|
||||
(object) ['key' => 'VAR2', 'value' => "'multiline\nvalue'", 'is_multiline' => true],
|
||||
]);
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
expect($buildArgs)->toHaveCount(2);
|
||||
|
||||
$envFlags = generateDockerEnvFlags($variables);
|
||||
expect($envFlags)->toBeString();
|
||||
expect($envFlags)->toContain('-e VAR1=');
|
||||
expect($envFlags)->toContain('-e VAR2="');
|
||||
});
|
||||
|
||||
test('variables without is_multiline default to false', function () {
|
||||
$variables = [
|
||||
['key' => 'NO_FLAG_VAR', 'value' => 'some value'],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// Should use escapeshellarg (single quotes) since is_multiline defaults to false
|
||||
expect($arg)->toBe("--build-arg NO_FLAG_VAR='some value'");
|
||||
});
|
||||
|
||||
test('real world SSH key example', function () {
|
||||
// Simulate what real_value returns (wrapped in single quotes)
|
||||
$sshKey = "'-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk
|
||||
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA
|
||||
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
|
||||
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
-----END OPENSSH PRIVATE KEY-----'";
|
||||
|
||||
$variables = [
|
||||
['key' => 'KEY', 'value' => $sshKey, 'is_multiline' => true],
|
||||
];
|
||||
|
||||
$buildArgs = generateDockerBuildArgs($variables);
|
||||
$arg = $buildArgs->first();
|
||||
|
||||
// Should produce clean output without wrapper quotes
|
||||
expect($arg)->toStartWith('--build-arg KEY="-----BEGIN OPENSSH PRIVATE KEY-----');
|
||||
expect($arg)->toEndWith('-----END OPENSSH PRIVATE KEY-----"');
|
||||
// Should NOT have the escaped quote sequence that was in the bug
|
||||
expect($arg)->not->toContain("''");
|
||||
expect($arg)->not->toContain("'\\''");
|
||||
});
|
||||
Reference in new issue
Block a user