diff --git a/src/Console/RunTaskCommand.php b/src/Console/RunTaskCommand.php index 147f60cc..26c52155 100644 --- a/src/Console/RunTaskCommand.php +++ b/src/Console/RunTaskCommand.php @@ -8,12 +8,14 @@ namespace Deployer\Console; use Deployer\Deployer; -use Deployer\Server\DryRun; use Deployer\Environment; +use Deployer\Server\ServerInterface; +use Deployer\Stage\Stage; use Deployer\Task\AbstractTask; use Deployer\Task\Runner; use Deployer\Task\TaskInterface; use Symfony\Component\Console\Command\Command as BaseCommand; +use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -45,6 +47,13 @@ class RunTaskCommand extends BaseCommand 'Run without execution command on servers.' ); + $this->addArgument( + 'stage', + InputArgument::OPTIONAL, + 'Run tasks for a specific environment', + Deployer::$defaultStage + ); + $this->addOption( 'server', null, @@ -60,12 +69,29 @@ class RunTaskCommand extends BaseCommand // Nothing to do now. } + $servers = Deployer::$servers; + + if (Deployer::$multistage) { + if (null === $input->getArgument('stage')) { + throw new \InvalidArgumentException('You have turned on multistage support, but not defined a stage (or default stage).'); + } + if (!isset(Deployer::$stages[$input->getArgument('stage')])) { + throw new \InvalidArgumentException('This stage is not defined.'); + } + /** @var Stage $stage */ + $stage = Deployer::$stages[$input->getArgument('stage')]; + $servers = $stage->getServers(); + foreach ( $stage->getOptions() as $key => $value ) { + set($key, $value); + } + } + try { foreach ($this->task->get() as $runner) { $isPrinted = $this->writeDesc($output, $runner->getDesc()); - $this->runSeries($runner, $input, $output); + $this->runSeries($runner, $servers, $input, $output); if ($isPrinted) { $this->writeOk($output); @@ -73,17 +99,21 @@ class RunTaskCommand extends BaseCommand } } catch (\Exception $e) { - $this->rollbackOnDeploy($input, $output); + $this->rollbackOnDeploy($servers, $input, $output); throw $e; } } - private function runSeries(Runner $runner, InputInterface $input, OutputInterface $output) + private function runSeries(Runner $runner, array $servers, InputInterface $input, OutputInterface $output) { $taskName = $runner->getName(); $taskName = empty($taskName) ? 'UnNamed' : $taskName; - foreach (Deployer::$servers as $name => $server) { + /** + * @var string $name + * @var ServerInterface $server + */ + foreach ($servers as $name => $server) { // Skip to specified server. $onServer = $input->getOption('server'); if (null !== $onServer && $onServer !== $name) { @@ -150,7 +180,7 @@ class RunTaskCommand extends BaseCommand * @param InputInterface $input * @param OutputInterface $output */ - private function rollbackOnDeploy(InputInterface $input, OutputInterface $output) + private function rollbackOnDeploy(array $servers, InputInterface $input, OutputInterface $output) { if (!isset(Deployer::$tasks['deploy:rollback'])) { return; @@ -159,7 +189,7 @@ class RunTaskCommand extends BaseCommand $task = Deployer::$tasks['deploy:rollback']; foreach ($task->get() as $runner) { - $this->runSeries($runner, $input, $output); + $this->runSeries($runner, $servers, $input, $output); } } } \ No newline at end of file diff --git a/src/Deployer.php b/src/Deployer.php index 6f905ff6..8e642a00 100644 --- a/src/Deployer.php +++ b/src/Deployer.php @@ -56,6 +56,25 @@ class Deployer */ public static $servers = []; + + /** + * Turn on/off multistage support + * @var bool + */ + public static $multistage = false; + + /** + * Default deploy stage + * @var string + */ + public static $defaultStage = 'develop'; + + /** + * List of all stages. + * @var array[] + */ + public static $stages = []; + /** * Array of global parameters. * @var array diff --git a/src/Stage/Stage.php b/src/Stage/Stage.php new file mode 100644 index 00000000..d2ba442b --- /dev/null +++ b/src/Stage/Stage.php @@ -0,0 +1,66 @@ +name = $name; + $this->servers = $servers; + $this->options = $options; + } + + public function getName() + { + return $this->name; + } + + public function getServers() + { + return $this->servers; + } + + public function options(array $options) + { + $this->options = $options; + } + + public function set($key, $value) + { + return $this->options[$key] = $value; + } + + public function get($key, $default) + { + return array_key_exists($key, $this->options) ? $this->options[$key] : $default; + } + + public function getOptions() + { + return $this->options; + } +} \ No newline at end of file diff --git a/src/Stage/StageFactory.php b/src/Stage/StageFactory.php new file mode 100644 index 00000000..b6e93f65 --- /dev/null +++ b/src/Stage/StageFactory.php @@ -0,0 +1,46 @@ +