PHPDeployer:根据主机为本地任务设置变量?

PHPDeployer: set variable for local task based on host?

我将部署器 运行ning 作为 GitHub 操作管道的一部分。我想让管道 运行 为我构建 NPM,并将其复制为部署的一部分,而不是让部署者在服务器上使用 npm dev 依赖项。对于 corestage 站点,我想使用调试版本,而 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:package 步骤已将 dev_js_mode 设置为 "prod",因为命令不是运行正在主机上运行,​​但我想不出办法让它工作。

在多次尝试错误之后,我想出了两种方法来解决我的问题。

  1. 在本地任务中使用它之前,通过远程闭包设置一个 php 变量。 Hacky,但它有效:
<?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',
]);
  1. 可能更受支持的方式——更灵活或更复杂,取决于你如何看待它——是创建本地任务的两个版本并通过诸如阶段之类的东西来约束它们。它创建 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'
]);