Refactor environment variables handling

This commit is contained in:
Anton Medvedev 2017-08-12 20:31:19 +03:00
parent e9a368ec5f
commit 8e01cf6924
9 changed files with 74 additions and 10 deletions

View File

@ -16,10 +16,12 @@
### Changed
- Changed `branch` parameter and option behavior
- Extended `task` func to support callables
- Renamed `env_vars` to `env`
### Fixed
- Improved the way `ParallelExecutor` handles option parameters
- Fixed no `stage` argument in parallel mode [#1299]
- Improved environment variables management
### Removed
- Removed `terminate_message` option

View File

@ -29,6 +29,14 @@
* `run('command')->toString()``run('command')`
* `run('if command; then echo "true"; fi;')->toBool()``test('command')`
4. `env_vars` renamed to `env`
* `set('env_vars', 'FOO=bar');``set('env', ['FOO' => 'bar']);`
If your are using Symfony recipe, then you need to change `env` setting:
* `set('env', 'prod');``set('symfony_env', 'prod');`
# Upgrade from 4.x to 5.x
1. Servers to Hosts

View File

@ -73,7 +73,7 @@ set('use_atomic_symlink', function () {
set('composer_action', 'install');
set('composer_options', '{{composer_action}} --verbose --prefer-dist --no-progress --no-interaction --no-dev --optimize-autoloader');
set('env_vars', ''); // Variable assignment before cmds (for example, SYMFONY_ENV={{set}})
set('env', []); // Run command environment (for example, SYMFONY_ENV=prod)
/**
* Return current release path.

View File

@ -12,5 +12,5 @@ task('deploy:vendors', function () {
if (!commandExist('unzip')) {
writeln('<comment>To speed up composer installation setup "unzip" command with PHP zip extension https://goo.gl/sxzFcD</comment>');
}
run('cd {{release_path}} && {{env_vars}} {{bin/composer}} {{composer_options}}');
run('cd {{release_path}} && {{bin/composer}} {{composer_options}}');
});

View File

@ -15,7 +15,7 @@ require_once __DIR__ . '/common.php';
*/
// Symfony build set
set('env', 'prod');
set('symfony_env', 'prod');
// Symfony shared dirs
set('shared_dirs', ['app/logs']);
@ -36,7 +36,11 @@ set('assets', ['web/css', 'web/images', 'web/js']);
set('dump_assets', false);
// Environment vars
set('env_vars', 'SYMFONY_ENV={{env}}');
set('env', function () {
return [
'SYMFONY_ENV' => get('symfony_env')
];
});
// Adding support for the Symfony3 directory structure
set('bin_dir', 'app');
@ -89,7 +93,7 @@ task('deploy:assets', function () {
* Install assets from public dir of bundles
*/
task('deploy:assets:install', function () {
run('{{env_vars}} {{bin/php}} {{bin/console}} assets:install {{console_options}} {{release_path}}/web');
run('{{bin/php}} {{bin/console}} assets:install {{console_options}} {{release_path}}/web');
})->desc('Install bundle assets');
@ -98,7 +102,7 @@ task('deploy:assets:install', function () {
*/
task('deploy:assetic:dump', function () {
if (get('dump_assets')) {
run('{{env_vars}} {{bin/php}} {{bin/console}} assetic:dump {{console_options}}');
run('{{bin/php}} {{bin/console}} assetic:dump {{console_options}}');
}
})->desc('Dump assets');
@ -106,14 +110,14 @@ task('deploy:assetic:dump', function () {
* Clear Cache
*/
task('deploy:cache:clear', function () {
run('{{env_vars}} {{bin/php}} {{bin/console}} cache:clear {{console_options}} --no-warmup');
run('{{bin/php}} {{bin/console}} cache:clear {{console_options}} --no-warmup');
})->desc('Clear cache');
/**
* Warm up cache
*/
task('deploy:cache:warmup', function () {
run('{{env_vars}} {{bin/php}} {{bin/console}} cache:warmup {{console_options}}');
run('{{bin/php}} {{bin/console}} cache:warmup {{console_options}}');
})->desc('Warm up cache');
@ -121,7 +125,7 @@ task('deploy:cache:warmup', function () {
* Migrate database
*/
task('database:migrate', function () {
run('{{env_vars}} {{bin/php}} {{bin/console}} doctrine:migrations:migrate {{console_options}} --allow-no-migration');
run('{{bin/php}} {{bin/console}} doctrine:migrations:migrate {{console_options}} --allow-no-migration');
})->desc('Migrate database');

View File

@ -73,3 +73,19 @@ function str_contains(string $haystack, string $needle)
{
return strpos($haystack, $needle) !== false;
}
/**
* Take array of key/value and create string of it.
*
* This function used for create environment string.
*/
function array_to_string(array $array): string
{
return implode(' ', array_map(
function ($key, $value) {
return sprintf("%s='%s'", $key, $value);
},
array_keys($array),
$array
));
}

View File

@ -22,6 +22,7 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use function Deployer\Support\array_to_string;
// There are two types of functions: Deployer dependent and Context dependent.
// Deployer dependent function uses in definition stage of recipe and may require Deployer::get() method.
@ -290,6 +291,12 @@ function run($command, $options = [])
$command = "cd $workingPath && ($command)";
}
$env = get('env', []) + ($options['env'] ?? []);
if (!empty($env)) {
$env = array_to_string($env);
$command = "export $env; $command";
}
if ($host instanceof Localhost) {
$output = $process->run($hostname, $command, $options);
} else {
@ -318,6 +325,12 @@ function runLocally($command, $options = [])
$command = "cd $workingPath && ($command)";
}
$env = get('env', []) + ($options['env'] ?? []);
if (!empty($env)) {
$env = array_to_string($env);
$command = "export $env; $command";
}
$output = $process->run($hostname, $command, $options);
return rtrim($output);

View File

@ -77,5 +77,19 @@ fail('deploy_fail', 'deploy:unlock');
// Dummy
task('deploy:vendors', function () {
run('echo {{env_vars}} {{bin/composer}} {{composer_options}}');
run('echo {{bin/composer}} {{composer_options}}');
});
// Environment test
task('test_env', function () {
add('env', ['KEY' => 'env value']);
writeln(run('echo $KEY $EXT', ['env' => [
'EXT' => 'ext'
]]));
writeln(runLocally('echo $KEY $LOCAL', ['env' => [
'LOCAL' => 'local'
]]));
});

View File

@ -86,4 +86,11 @@ class DeployTest extends DepCase
self::assertEquals(5, exec("ls -1 releases | wc -l"));
self::assertFileNotExists(self::$currentPath . '/release');
}
public function testEnvironment()
{
$output = $this->start('test_env');
self::assertContains('env value ext', $output);
self::assertContains('env value local', $output);
}
}