PHPDeployer: установить переменную для локальной задачи на основе хоста? - PullRequest
0 голосов
/ 25 октября 2019

У меня есть средство развертывания, работающее как часть конвейера GitHub Action. Я хотел, чтобы конвейер запускал для меня сборку NPM и копировал ее как часть развертывания, а не развертывателя, использующего зависимости npm dev на сервере. Для сайтов core и stage я хочу использовать отладочную сборку, в то время как prod получает производственную сборку.

Полный файл deploy.php ниже:

<?php
namespace Deployer;

require 'recipe/laravel.php';
require 'recipe/rsync.php';
require 'recipe/discord.php';

// Project name
set('application', 'xxxxxxxxxx');

// Project repository
set('repository', 'git@github.com:xxxxxxxxxx');

// Shared files/dirs between deploys
add('shared_files', []);
add('shared_dirs', []);

// Writable dirs by web server
add('writable_dirs', []);
set('allow_anonymous_stats', false);

set('dev_db', false);
set('dev_js_mode', 'prod');
set('rsync_src', __DIR__ . '/public/');
set('rsync_dest', '{{release_path}}/public/');
set('discord_channel', 'xxxxxxxxxx');
set('discord_token', 'xxxxxxxxxx');

// Hosts
host('core')
    ->hostname('xxxxxxxxxx.com')
    ->user('xxxxxxxxxx')
    ->set('deploy_path', '/home/xxxxxxxxxx.com')
    ->set('branch', 'master')
    ->set('dev_db', true)
    ->set('dev_js_mode', 'dev');

host('stage')
    ->hostname('xxxxxxxxxx')
    ->user('xxxxxxxxxx')
    ->set('deploy_path', '/home/xxxxxxxxxx.com')
    ->set('branch', 'stage')
    ->set('dev_js_mode', 'dev');

host('prod')
    ->hostname('xxxxxxxxxx.com')
    ->user('xxxxxxxxxx')
    ->set('deploy_path', '/home/xxxxxxxxxx.com')
    ->set('branch', 'prod');

// Custom Tasks
task('reload', function () {
    run('sudo systemctl restart php7.2-fpm');
    run('sudo systemctl restart nginx');
});

task('database', function() {
    $freshDb = get('dev_db');

    if ($freshDb === true) {
        run('composer run refresh-db --working-dir={{release_path}}/');
    } else {
        invoke('artisan:migrate');
    }
});

task('local:javascript:package', function() {
    run('npm ci');
    run('npm run {{dev_js_mode}}');
})->local();

task('local:javascript:deploy', [
    'rsync',
]);

task('local:javascript', [
    'local:javascript:package',
    'local:javascript:deploy',
]);

// modifications
before('deploy:symlink', 'local:javascript');
before('deploy:symlink', 'database');

after('deploy', 'reload');
after('rollback', 'reload');
after('deploy:failed', 'deploy:unlock');

before('deploy', 'discord:notify');
after('success', 'discord:notify:success');
after('deploy:failed', 'discord:notify:failure');

У меня есть dev_js_mode переменная по умолчанию установлена ​​на «prod», просто чтобы быть уверенным, что отладочная сборка не вылезет туда, где я ее не собираюсь.

Если я запусту dep -vvv deploy core, я смогу увидеть шаг local:javascript:packagedev_js_mode имеет значение "prod", которое я получаю, потому что команда не выполняется на хосте, но я не могу найти способ заставить это работать.

1 Ответ

0 голосов
/ 26 октября 2019

После большого количества проб n ошибок, я нашел два способа решения моей проблемы:

  1. Установите переменную php через удаленное закрытие перед использованием ее в локальной задаче. Хаки, но это работает:
<?php
namespace Deployer;

set('testing', 'prod');

$var = 'original';

host('core')
    ->hostname('example.com')
    ->set('testing', 'dev');

host('prod')
    ->hostname('example.com')
    ->set('testing', 'prod');

task('remote:run', function() use (&$var) {
    $var = get('testing');
    run('echo remote {{testing}}, var is '. $var);
});

task('local:var', function() use (&$var) {
    run('echo local {{testing}}, var is '. $var);
})->local();

task('mytest', [
    'remote:run',
    'local:var',
]);
Вероятно, более поддерживаемый способ - более гибкий или запутанный, в зависимости от того, как вы на него смотрите - создает две версии локальной задачи и ограничивает их посредством чего-то вроде этапа. Создает 2-3 задачи вместо одной:
<?php
namespace Deployer;

host('core')
    ->hostname('example.com')
    ->stage('core');

host('prod')
    ->hostname('example.com')
    ->stage('prod');

task('remote:run', function(){
    run('echo remote');
});

task('local:core', function() {
    run('echo local, core only');
})->local()->onStage('core');

task('local:prod', function() {
    run('echo local, prod only');
})->local()->onStage('prod');

task('local', [
    'local:core',
    'local:prod',
]);

task('mytest', [
    'remote:run',
    'local', // instead of 'local', you can just call both 'local:core' and 'local:prod'
]);
...