fix(compose): preserve environment variable semantics (#11794)

This commit is contained in:
Andras Bacsai
2026-10-11 21:02:11 +02:00
committed by GitHub
parent 1e42284db0
commit cdd8f82840
17 changed files with 1258 additions and 37 deletions
@@ -93,6 +93,70 @@ YAML;
->and($result[1]['value'])->toBe('false');
});
test('distinguishes passthrough variables from explicit empty values', function () {
$yaml = <<<'YAML'
services:
list-app:
environment:
- PASSTHROUGH
- EMPTY=
map-app:
environment:
MAPPED_PASSTHROUGH:
MAPPED_EMPTY: ""
YAML;
$result = extractHardcodedEnvironmentVariables($yaml)->keyBy('key');
expect($result['PASSTHROUGH']['is_passthrough'])->toBeTrue()
->and($result['EMPTY']['is_passthrough'])->toBeFalse()
->and($result['MAPPED_PASSTHROUGH']['is_passthrough'])->toBeTrue()
->and($result['MAPPED_EMPTY']['is_passthrough'])->toBeFalse();
});
test('detects Compose inputs that must remain unset when blank', function () {
$yaml = <<<'YAML'
services:
app:
environment:
BARE:
DASH: ${DASH-default}
QUESTION: ${QUESTION?required}
COLON_DASH: ${COLON_DASH:-default}
ESCAPED: $${ESCAPED-nope}
YAML;
expect(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'BARE', null))->toBeTrue()
->and(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'DASH', null))->toBeTrue()
->and(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'QUESTION', null))->toBeTrue()
->and(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'COLON_DASH', null))->toBeTrue()
->and(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'ESCAPED', null))->toBeFalse()
->and(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'DASH', ''))->toBeFalse()
->and(dockerComposeEnvironmentVariableShouldBeUnset($yaml, 'COLON_DASH', 'debug'))->toBeFalse();
});
test('extracts fallback and required metadata from derived Compose values', function () {
$compose = <<<'YAML'
services:
app:
environment:
URL: https://${HOST:-${INNER_HOST:-localhost}/api}
PATH: ${TOKEN?TOKEN is required}/v1
YAML;
expect(dockerComposeEnvironmentVariableInfo($compose, 'HOST'))->toMatchArray([
'services' => ['app'],
'default' => '${INNER_HOST:-localhost}/api',
'operator' => ':-',
'required' => false,
])->and(dockerComposeEnvironmentVariableInfo($compose, 'TOKEN'))->toMatchArray([
'services' => ['app'],
'default' => null,
'operator' => '?',
'required' => true,
]);
});
test('returns empty collection for malformed YAML', function () {
$yaml = 'invalid: yaml: content::: [[[';