1
0
mirror of https://github.com/hauke68/Magallanes.git synced 2025-09-13 04:30:17 +02:00

[Nostromo] Improve Exception workflow

This commit is contained in:
Andrés Montañez 2017-01-07 01:53:57 -03:00
parent 6d5861ec82
commit 238777cb41
29 changed files with 216 additions and 247 deletions

View File

@ -10,14 +10,12 @@
namespace Mage\Command\BuiltIn; namespace Mage\Command\BuiltIn;
use Mage\Runtime\Exception\DeploymentException;
use Mage\Runtime\Exception\InvalidEnvironmentException;
use Mage\Runtime\Exception\RuntimeException; use Mage\Runtime\Exception\RuntimeException;
use Mage\Runtime\Runtime; use Mage\Runtime\Runtime;
use Mage\Task\ErrorException;
use Mage\Task\ExecuteOnRollbackInterface; use Mage\Task\ExecuteOnRollbackInterface;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;
use Mage\Task\SkipException; use Mage\Task\Exception\ErrorException;
use Mage\Task\Exception\SkipException;
use Mage\Task\TaskFactory; use Mage\Task\TaskFactory;
use Mage\Utils; use Mage\Utils;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -70,37 +68,38 @@ class DeployCommand extends AbstractCommand
try { try {
$this->runtime->setEnvironment($input->getArgument('environment')); $this->runtime->setEnvironment($input->getArgument('environment'));
} catch (InvalidEnvironmentException $exception) {
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
return $exception->getCode();
}
$output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment())); $output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment()));
$this->log(sprintf('Environment: %s', $this->runtime->getEnvironment())); $this->log(sprintf('Environment: %s', $this->runtime->getEnvironment()));
if ($this->runtime->getEnvironmentConfig('releases', false)) { if ($this->runtime->getEnvironmentConfig('releases', false)) {
$this->runtime->generateReleaseId(); $this->runtime->generateReleaseId();
$output->writeln(sprintf(' Release ID: <fg=green>%s</>', $this->runtime->getReleaseId())); $output->writeln(sprintf(' Release ID: <fg=green>%s</>', $this->runtime->getReleaseId()));
$this->log(sprintf('Release ID: %s', $this->runtime->getReleaseId())); $this->log(sprintf('Release ID: %s', $this->runtime->getReleaseId()));
} }
if ($this->runtime->getConfigOptions('log_file', false)) { if ($this->runtime->getConfigOptions('log_file', false)) {
$output->writeln(sprintf(' Logfile: <fg=green>%s</>', $this->runtime->getConfigOptions('log_file'))); $output->writeln(sprintf(' Logfile: <fg=green>%s</>', $this->runtime->getConfigOptions('log_file')));
} }
$output->writeln('');
try {
// Check if Branch is forced
if ($input->getOption('branch') !== false) { if ($input->getOption('branch') !== false) {
$this->runtime->setEnvironmentConfig('branch', $input->getOption('branch')); $this->runtime->setEnvironmentConfig('branch', $input->getOption('branch'));
} }
if ($this->runtime->getEnvironmentConfig('branch', false)) {
$output->writeln(sprintf(' Branch: <fg=green>%s</>', $this->runtime->getEnvironmentConfig('branch')));
}
$output->writeln('');
$this->taskFactory = new TaskFactory($this->runtime); $this->taskFactory = new TaskFactory($this->runtime);
$this->runDeployment($output); $this->runDeployment($output);
} catch (DeploymentException $exception) {
} catch (RuntimeException $exception) {
$output->writeln('');
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage())); $output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
return $exception->getCode(); $output->writeln('');
$this->statusCode = 7;
} }
$output->writeln('Finished <fg=blue>Magallanes</>'); $output->writeln('Finished <fg=blue>Magallanes</>');
@ -112,11 +111,11 @@ class DeployCommand extends AbstractCommand
* Run the Deployment Process * Run the Deployment Process
* *
* @param OutputInterface $output * @param OutputInterface $output
* @throws DeploymentException * @throws RuntimeException
*/ */
protected function runDeployment(OutputInterface $output) protected function runDeployment(OutputInterface $output)
{ {
// Run Pre Deploy Tasks // Run "Pre Deploy" Tasks
$this->runtime->setStage(Runtime::PRE_DEPLOY); $this->runtime->setStage(Runtime::PRE_DEPLOY);
$preDeployTasks = $this->runtime->getTasks(); $preDeployTasks = $this->runtime->getTasks();
@ -133,10 +132,10 @@ class DeployCommand extends AbstractCommand
} }
if (!$this->runTasks($output, $preDeployTasks)) { if (!$this->runTasks($output, $preDeployTasks)) {
throw new DeploymentException(sprintf(' Tasks failed on %s stage, halting deployment', $this->getStageName()), 50); throw new RuntimeException(sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), 50);
} }
// Run On Deploy Tasks // Run "On Deploy" Tasks
$hosts = $this->runtime->getEnvironmentConfig('hosts'); $hosts = $this->runtime->getEnvironmentConfig('hosts');
if (count($hosts) == 0) { if (count($hosts) == 0) {
$output->writeln(' No hosts defined, skipping On Deploy tasks'); $output->writeln(' No hosts defined, skipping On Deploy tasks');
@ -165,13 +164,14 @@ class DeployCommand extends AbstractCommand
foreach ($hosts as $host) { foreach ($hosts as $host) {
$this->runtime->setWorkingHost($host); $this->runtime->setWorkingHost($host);
if (!$this->runTasks($output, $onDeployTasks)) { if (!$this->runTasks($output, $onDeployTasks)) {
throw new DeploymentException(sprintf(' Tasks failed on <fg=black;options=bold>%s</> stage, halting deployment', $this->getStageName()), 50); $this->runtime->setWorkingHost(null);
throw new RuntimeException(sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), 50);
} }
$this->runtime->setWorkingHost(null); $this->runtime->setWorkingHost(null);
} }
} }
// Run On Release Tasks // Run "On Release" Tasks
$hosts = $this->runtime->getEnvironmentConfig('hosts'); $hosts = $this->runtime->getEnvironmentConfig('hosts');
if (count($hosts) == 0) { if (count($hosts) == 0) {
$output->writeln(' No hosts defined, skipping On Release tasks'); $output->writeln(' No hosts defined, skipping On Release tasks');
@ -189,13 +189,14 @@ class DeployCommand extends AbstractCommand
foreach ($hosts as $host) { foreach ($hosts as $host) {
$this->runtime->setWorkingHost($host); $this->runtime->setWorkingHost($host);
if (!$this->runTasks($output, $onReleaseTasks)) { if (!$this->runTasks($output, $onReleaseTasks)) {
throw new DeploymentException(sprintf(' Tasks failed on <fg=black;options=bold>%s</> stage, halting deployment', $this->getStageName()), 50); $this->runtime->setWorkingHost(null);
throw new RuntimeException(sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), 50);
} }
$this->runtime->setWorkingHost(null); $this->runtime->setWorkingHost(null);
} }
} }
// Run Post Release Tasks // Run "Post Release" Tasks
$hosts = $this->runtime->getEnvironmentConfig('hosts'); $hosts = $this->runtime->getEnvironmentConfig('hosts');
if (count($hosts) == 0) { if (count($hosts) == 0) {
$output->writeln(' No hosts defined, skipping Post Release tasks'); $output->writeln(' No hosts defined, skipping Post Release tasks');
@ -213,13 +214,14 @@ class DeployCommand extends AbstractCommand
foreach ($hosts as $host) { foreach ($hosts as $host) {
$this->runtime->setWorkingHost($host); $this->runtime->setWorkingHost($host);
if (!$this->runTasks($output, $postReleaseTasks)) { if (!$this->runTasks($output, $postReleaseTasks)) {
throw new DeploymentException(sprintf(' Tasks failed on <fg=black;options=bold>%s</> stage, halting deployment', $this->getStageName()), 50); $this->runtime->setWorkingHost(null);
throw new RuntimeException(sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), 50);
} }
$this->runtime->setWorkingHost(null); $this->runtime->setWorkingHost(null);
} }
} }
// Run Post Deploy Tasks // Run "Post Deploy" Tasks
$this->runtime->setStage(Runtime::POST_DEPLOY); $this->runtime->setStage(Runtime::POST_DEPLOY);
$postDeployTasks = $this->runtime->getTasks(); $postDeployTasks = $this->runtime->getTasks();
if ($this->runtime->getEnvironmentConfig('releases', false) && !$this->runtime->inRollback()) { if ($this->runtime->getEnvironmentConfig('releases', false) && !$this->runtime->inRollback()) {
@ -235,7 +237,7 @@ class DeployCommand extends AbstractCommand
} }
if (!$this->runTasks($output, $postDeployTasks)) { if (!$this->runTasks($output, $postDeployTasks)) {
throw new DeploymentException(sprintf(' Tasks failed on <fg=black;options=bold>%s</> stage, halting deployment', $this->getStageName()), 50); throw new RuntimeException(sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), 50);
} }
} }
@ -282,19 +284,25 @@ class DeployCommand extends AbstractCommand
$this->log(sprintf('Task %s (%s) finished with OK', $task->getDescription(), $task->getName())); $this->log(sprintf('Task %s (%s) finished with OK', $task->getDescription(), $task->getName()));
} else { } else {
$output->writeln('<fg=red>FAIL</>'); $output->writeln('<fg=red>FAIL</>');
$this->statusCode = 500; $this->statusCode = 180;
$this->log(sprintf('Task %s (%s) finished with FAIL', $task->getDescription(), $task->getName())); $this->log(sprintf('Task %s (%s) finished with FAIL', $task->getDescription(), $task->getName()));
} }
} catch (SkipException $exception) { } catch (SkipException $exception) {
$succeededTasks++; $succeededTasks++;
$output->writeln('<fg=yellow>SKIPPED</>'); $output->writeln('<fg=yellow>SKIPPED</>');
$this->log(sprintf('Task %s (%s) finished with SKIPPED, thrown SkipException', $task->getDescription(), $task->getName())); $this->log(sprintf('Task %s (%s) finished with SKIPPED, thrown SkipException', $task->getDescription(), $task->getName()));
} catch (ErrorException $exception) { } catch (ErrorException $exception) {
$output->writeln(sprintf('<fg=red>ERROR</> [%s]', $exception->getTrimmedMessage())); $output->writeln(sprintf('<fg=red>ERROR</> [%s]', $exception->getTrimmedMessage()));
$this->log(sprintf('Task %s (%s) finished with FAIL, with Error "%s"', $task->getDescription(), $task->getName(), $exception->getMessage())); $this->log(sprintf('Task %s (%s) finished with FAIL, with Error "%s"', $task->getDescription(), $task->getName(), $exception->getMessage()));
$this->statusCode = $exception->getCode(); $this->statusCode = 190;
} }
} }
if ($this->statusCode !== 0) {
break;
}
} }
if ($succeededTasks != $totalTasks) { if ($succeededTasks != $totalTasks) {
@ -303,7 +311,7 @@ class DeployCommand extends AbstractCommand
$alertColor = 'green'; $alertColor = 'green';
} }
$output->writeln(sprintf(' Finished <fg=black;options=bold>%s</> tasks: <fg=%s>%d/%d</> done.', $this->getStageName(), $alertColor, $succeededTasks, $totalTasks)); $output->writeln(sprintf(' Finished <fg=%s>%d/%d</> tasks for <fg=black;options=bold>%s</>.', $alertColor, $succeededTasks, $totalTasks, $this->getStageName()));
$output->writeln(''); $output->writeln('');
return ($succeededTasks == $totalTasks); return ($succeededTasks == $totalTasks);

View File

@ -11,8 +11,6 @@
namespace Mage\Command\BuiltIn\Releases; namespace Mage\Command\BuiltIn\Releases;
use Mage\Utils; use Mage\Utils;
use Mage\Runtime\Exception\InvalidEnvironmentException;
use Mage\Runtime\Exception\DeploymentException;
use Mage\Runtime\Exception\RuntimeException; use Mage\Runtime\Exception\RuntimeException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -27,6 +25,11 @@ use Mage\Command\AbstractCommand;
*/ */
class ListCommand extends AbstractCommand class ListCommand extends AbstractCommand
{ {
/**
* @var int
*/
protected $statusCode = 0;
/** /**
* Configure the Command * Configure the Command
*/ */
@ -45,8 +48,6 @@ class ListCommand extends AbstractCommand
* @param InputInterface $input * @param InputInterface $input
* @param OutputInterface $output * @param OutputInterface $output
* @return int|mixed * @return int|mixed
* @throws DeploymentException
* @throws RuntimeException
*/ */
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
@ -55,91 +56,92 @@ class ListCommand extends AbstractCommand
try { try {
$this->runtime->setEnvironment($input->getArgument('environment')); $this->runtime->setEnvironment($input->getArgument('environment'));
} catch (InvalidEnvironmentException $exception) {
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
return $exception->getCode();
}
if (!$this->runtime->getEnvironmentConfig('releases', false)) { if (!$this->runtime->getEnvironmentConfig('releases', false)) {
throw new DeploymentException('Releases are not enabled', 70); throw new RuntimeException('Releases are not enabled', 70);
} }
$output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment())); $output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment()));
$this->log(sprintf('Environment: %s', $this->runtime->getEnvironment())); $this->log(sprintf('Environment: %s', $this->runtime->getEnvironment()));
if ($this->runtime->getConfigOptions('log_file', false)) { if ($this->runtime->getConfigOptions('log_file', false)) {
$output->writeln(sprintf(' Logfile: <fg=green>%s</>', $this->runtime->getConfigOptions('log_file'))); $output->writeln(sprintf(' Logfile: <fg=green>%s</>', $this->runtime->getConfigOptions('log_file')));
} }
$output->writeln('');
$hosts = $this->runtime->getEnvironmentConfig('hosts');
if (count($hosts) == 0) {
$output->writeln('No hosts defined');
$output->writeln(''); $output->writeln('');
} else {
$hostPath = rtrim($this->runtime->getEnvironmentConfig('host_path'), '/');
foreach ($hosts as $host) { $hosts = $this->runtime->getEnvironmentConfig('hosts');
$this->runtime->setWorkingHost($host); if (count($hosts) == 0) {
$output->writeln('No hosts defined');
$output->writeln('');
} else {
$hostPath = rtrim($this->runtime->getEnvironmentConfig('host_path'), '/');
// Get List of Releases foreach ($hosts as $host) {
$cmdListReleases = sprintf('ls -1 %s/releases', $hostPath); $this->runtime->setWorkingHost($host);
/** @var Process $process */ // Get List of Releases
$process = $this->runtime->runRemoteCommand($cmdListReleases, false); $cmdListReleases = sprintf('ls -1 %s/releases', $hostPath);
if (!$process->isSuccessful()) {
throw new RuntimeException(sprintf('Unable to retrieve releases from host "%s"', $host), 80);
}
if (trim($process->getOutput()) != '') {
$releases = explode(PHP_EOL, trim($process->getOutput()));
rsort($releases);
} else {
$releases = [];
}
if (count($releases) == 0) {
$output->writeln(sprintf(' No releases available on host <fg=black;options=bold>%s</>:', $host));
} else {
// Get Current Release
$cmdCurrentRelease = sprintf('readlink -f %s/current', $hostPath);
/** @var Process $process */ /** @var Process $process */
$process = $this->runtime->runRemoteCommand($cmdCurrentRelease, false); $process = $this->runtime->runRemoteCommand($cmdListReleases, false);
if (!$process->isSuccessful()) { if (!$process->isSuccessful()) {
throw new RuntimeException(sprintf('Unable to retrieve current release from host "%s"', $host), 85); throw new RuntimeException(sprintf('Unable to retrieve releases from host "%s"', $host), 80);
} }
$currentReleaseId = explode('/', trim($process->getOutput())); if (trim($process->getOutput()) != '') {
$currentReleaseId = $currentReleaseId[count($currentReleaseId) - 1]; $releases = explode(PHP_EOL, trim($process->getOutput()));
rsort($releases);
} else {
$releases = [];
}
$output->writeln(sprintf(' Releases on host <fg=black;options=bold>%s</>:', $host)); if (count($releases) == 0) {
$output->writeln(sprintf(' No releases available on host <fg=black;options=bold>%s</>:', $host));
} else {
// Get Current Release
$cmdCurrentRelease = sprintf('readlink -f %s/current', $hostPath);
foreach ($releases as $releaseId) { /** @var Process $process */
$releaseDate = Utils::getReleaseDate($releaseId); $process = $this->runtime->runRemoteCommand($cmdCurrentRelease, false);
if (!$process->isSuccessful()) {
throw new RuntimeException(sprintf('Unable to retrieve current release from host "%s"', $host), 85);
}
$output->write(sprintf(' Release ID: <fg=magenta>%s</> - Date: <fg=black;options=bold>%s</> [%s]', $currentReleaseId = explode('/', trim($process->getOutput()));
$releaseId, $currentReleaseId = $currentReleaseId[count($currentReleaseId) - 1];
$releaseDate->format('Y-m-d H:i:s'),
Utils::getTimeDiff($releaseDate)
));
if ($releaseId == $currentReleaseId) { $output->writeln(sprintf(' Releases on host <fg=black;options=bold>%s</>:', $host));
$output->writeln(' <fg=red;options=bold>[current]</>');
} else { foreach ($releases as $releaseId) {
$output->writeln(''); $releaseDate = Utils::getReleaseDate($releaseId);
$output->write(sprintf(' Release ID: <fg=magenta>%s</> - Date: <fg=black;options=bold>%s</> [%s]',
$releaseId,
$releaseDate->format('Y-m-d H:i:s'),
Utils::getTimeDiff($releaseDate)
));
if ($releaseId == $currentReleaseId) {
$output->writeln(' <fg=red;options=bold>[current]</>');
} else {
$output->writeln('');
}
} }
} }
}
$this->runtime->setWorkingHost(null); $this->runtime->setWorkingHost(null);
$output->writeln(''); $output->writeln('');
}
} }
} catch (RuntimeException $exception) {
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
$this->statusCode = $exception->getCode();
} }
$output->writeln('Finished <fg=blue>Magallanes</>'); $output->writeln('Finished <fg=blue>Magallanes</>');
return 0; return $this->statusCode;
} }
} }

View File

@ -11,8 +11,7 @@
namespace Mage\Command\BuiltIn\Releases; namespace Mage\Command\BuiltIn\Releases;
use Mage\Task\TaskFactory; use Mage\Task\TaskFactory;
use Mage\Runtime\Exception\InvalidEnvironmentException; use Mage\Runtime\Exception\RuntimeException;
use Mage\Runtime\Exception\DeploymentException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
@ -26,6 +25,11 @@ use Mage\Command\BuiltIn\DeployCommand;
*/ */
class RollbackCommand extends DeployCommand class RollbackCommand extends DeployCommand
{ {
/**
* @var int
*/
protected $statusCode = 0;
/** /**
* Configure the Command * Configure the Command
*/ */
@ -45,7 +49,6 @@ class RollbackCommand extends DeployCommand
* @param InputInterface $input * @param InputInterface $input
* @param OutputInterface $output * @param OutputInterface $output
* @return int|mixed * @return int|mixed
* @throws DeploymentException
*/ */
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
@ -54,24 +57,22 @@ class RollbackCommand extends DeployCommand
try { try {
$this->runtime->setEnvironment($input->getArgument('environment')); $this->runtime->setEnvironment($input->getArgument('environment'));
} catch (InvalidEnvironmentException $exception) {
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
return $exception->getCode();
}
if (!$this->runtime->getEnvironmentConfig('releases', false)) { if (!$this->runtime->getEnvironmentConfig('releases', false)) {
throw new DeploymentException('Releases are not enabled', 70); throw new RuntimeException('Releases are not enabled', 70);
} }
$releaseToRollback = $input->getArgument('release');
if (($releaseId = $this->checkReleaseAvailability($releaseToRollback)) === false) {
throw new RuntimeException(sprintf('Release "%s" is not available on all hosts', $releaseToRollback), 72);
}
// Check if the Release exists in all hosts
$releaseToRollback = $input->getArgument('release');
if ($releaseId = $this->checkReleaseAvailability($releaseToRollback)) {
$this->runtime->setReleaseId($releaseId)->setRollback(true); $this->runtime->setReleaseId($releaseId)->setRollback(true);
$output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment())); $output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment()));
$this->log(sprintf('Environment: %s', $this->runtime->getEnvironment())); $this->log(sprintf('Environment: %s', $this->runtime->getEnvironment()));
$output->writeln(sprintf(' Rollback to Release ID: <fg=green>%s</>', $this->runtime->getReleaseId())); $output->writeln(sprintf(' Rollback to Release Id: <fg=green>%s</>', $this->runtime->getReleaseId()));
$this->log(sprintf('Release ID: %s', $this->runtime->getReleaseId())); $this->log(sprintf('Release ID: %s', $this->runtime->getReleaseId()));
if ($this->runtime->getConfigOptions('log_file', false)) { if ($this->runtime->getConfigOptions('log_file', false)) {
@ -80,22 +81,17 @@ class RollbackCommand extends DeployCommand
$output->writeln(''); $output->writeln('');
// Get the Task Factory
$this->taskFactory = new TaskFactory($this->runtime); $this->taskFactory = new TaskFactory($this->runtime);
$this->runDeployment($output);
try { } catch (RuntimeException $exception) {
$this->runDeployment($output); $output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
} catch (DeploymentException $exception) { $this->statusCode = $exception->getCode();
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
return $exception->getCode();
}
} else {
throw new DeploymentException(sprintf('Release "%s" is not available on all hosts', $releaseToRollback), 72);
} }
$output->writeln('Finished <fg=blue>Magallanes</>'); $output->writeln('Finished <fg=blue>Magallanes</>');
return 0; return $this->statusCode;
} }
/** /**

View File

@ -1,20 +0,0 @@
<?php
/*
* This file is part of the Magallanes package.
*
* (c) Andrés Montañez <andres@andresmontanez.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Mage\Runtime\Exception;
/**
* An Error occurred while Deploying
*
* @author Andrés Montañez <andresmontanez@gmail.com>
*/
class DeploymentException extends RuntimeException
{
}

View File

@ -1,20 +0,0 @@
<?php
/*
* This file is part of the Magallanes package.
*
* (c) Andrés Montañez <andres@andresmontanez.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Mage\Runtime\Exception;
/**
* The provided Environment is invalid
*
* @author Andrés Montañez <andresmontanez@gmail.com>
*/
class InvalidEnvironmentException extends RuntimeException
{
}

View File

@ -13,7 +13,7 @@ namespace Mage\Runtime;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel; use Psr\Log\LogLevel;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Runtime\Exception\InvalidEnvironmentException; use Mage\Runtime\Exception\RuntimeException;
/** /**
* Runtime is a container of all run in time configuration, stages of progress, hosts being deployed, etc. * Runtime is a container of all run in time configuration, stages of progress, hosts being deployed, etc.
@ -210,7 +210,6 @@ class Runtime
* @param mixed $key Section name * @param mixed $key Section name
* @param mixed $default Default value * @param mixed $default Default value
* @return mixed * @return mixed
* @throws InvalidEnvironmentException
*/ */
public function getEnvironmentConfig($key = null, $default = null) public function getEnvironmentConfig($key = null, $default = null)
{ {
@ -257,7 +256,7 @@ class Runtime
* *
* @param string $environment Environment name * @param string $environment Environment name
* @return Runtime * @return Runtime
* @throws InvalidEnvironmentException * @throws RuntimeException
*/ */
public function setEnvironment($environment) public function setEnvironment($environment)
{ {
@ -266,7 +265,7 @@ class Runtime
return $this; return $this;
} }
throw new InvalidEnvironmentException(sprintf('The environment "%s" does not exists.', $environment), 100); throw new RuntimeException(sprintf('The environment "%s" does not exists.', $environment), 100);
} }
/** /**
@ -305,7 +304,6 @@ class Runtime
* Retrieve the defined Tasks for the current Environment and Stage * Retrieve the defined Tasks for the current Environment and Stage
* *
* @return array * @return array
* @throws InvalidEnvironmentException
*/ */
public function getTasks() public function getTasks()
{ {
@ -405,7 +403,6 @@ class Runtime
* @param bool $jail Jail the command * @param bool $jail Jail the command
* @param int $timeout Seconds to wait * @param int $timeout Seconds to wait
* @return Process * @return Process
* @throws InvalidEnvironmentException
*/ */
public function runRemoteCommand($cmd, $jail = true, $timeout = 120) public function runRemoteCommand($cmd, $jail = true, $timeout = 120)
{ {

View File

@ -10,6 +10,7 @@
namespace Mage\Task\BuiltIn\Deploy; namespace Mage\Task\BuiltIn\Deploy;
use Mage\Task\Exception\ErrorException;
use Mage\Task\ExecuteOnRollbackInterface; use Mage\Task\ExecuteOnRollbackInterface;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;
@ -33,6 +34,10 @@ class ReleaseTask extends AbstractTask implements ExecuteOnRollbackInterface
public function execute() public function execute()
{ {
if (!$this->runtime->getEnvironmentConfig('releases', false)) {
throw new ErrorException('This task is only available with releases enabled', 40);
}
$hostPath = rtrim($this->runtime->getEnvironmentConfig('host_path'), '/'); $hostPath = rtrim($this->runtime->getEnvironmentConfig('host_path'), '/');
$releaseId = $this->runtime->getReleaseId(); $releaseId = $this->runtime->getReleaseId();

View File

@ -10,7 +10,7 @@
namespace Mage\Task\BuiltIn\Deploy; namespace Mage\Task\BuiltIn\Deploy;
use Mage\Task\ErrorException; use Mage\Task\Exception\ErrorException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;

View File

@ -10,7 +10,7 @@
namespace Mage\Task\BuiltIn\Deploy\TarGz; namespace Mage\Task\BuiltIn\Deploy\TarGz;
use Mage\Task\ErrorException; use Mage\Task\Exception\ErrorException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;

View File

@ -10,7 +10,7 @@
namespace Mage\Task\BuiltIn\Deploy\TarGz; namespace Mage\Task\BuiltIn\Deploy\TarGz;
use Mage\Task\ErrorException; use Mage\Task\Exception\ErrorException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;

View File

@ -10,7 +10,7 @@
namespace Mage\Task\BuiltIn\Deploy\TarGz; namespace Mage\Task\BuiltIn\Deploy\TarGz;
use Mage\Task\ErrorException; use Mage\Task\Exception\ErrorException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;

View File

@ -10,7 +10,7 @@
namespace Mage\Task\BuiltIn\FS; namespace Mage\Task\BuiltIn\FS;
use Mage\Runtime\Exception\RuntimeException; use Mage\Task\Exception\ErrorException;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;
/** /**
@ -26,7 +26,7 @@ abstract class AbstractFileTask extends AbstractTask
foreach ($mandatory as $parameter) { foreach ($mandatory as $parameter) {
if (!array_key_exists($parameter, $this->options)) { if (!array_key_exists($parameter, $this->options)) {
throw new RuntimeException(sprintf('Parameter "%s" is not defined', $parameter)); throw new ErrorException(sprintf('Parameter "%s" is not defined', $parameter));
} }
} }

View File

@ -11,6 +11,7 @@
namespace Mage\Task\BuiltIn\FS; namespace Mage\Task\BuiltIn\FS;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Exception;
/** /**
* File System Task - Copy a File * File System Task - Copy a File
@ -26,7 +27,12 @@ class CopyTask extends AbstractFileTask
public function getDescription() public function getDescription()
{ {
return sprintf('[FS] Copy "%s" to "%s"', $this->getFile('from'), $this->getFile('to')); try {
return sprintf('[FS] Copy "%s" to "%s"', $this->getFile('from'), $this->getFile('to'));
} catch (Exception $exception) {
return '[FS] Copy [missing parameters]';
}
} }
public function execute() public function execute()

View File

@ -11,6 +11,7 @@
namespace Mage\Task\BuiltIn\FS; namespace Mage\Task\BuiltIn\FS;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Exception;
/** /**
* File System Task - Symlink a File * File System Task - Symlink a File
@ -26,7 +27,12 @@ class LinkTask extends AbstractFileTask
public function getDescription() public function getDescription()
{ {
return sprintf('[FS] Link "%s" to "%s"', $this->getFile('from'), $this->getFile('to')); try {
return sprintf('[FS] Link "%s" to "%s"', $this->getFile('from'), $this->getFile('to'));
} catch (Exception $exception) {
return '[FS] Link [missing parameters]';
}
} }
public function execute() public function execute()

View File

@ -11,6 +11,7 @@
namespace Mage\Task\BuiltIn\FS; namespace Mage\Task\BuiltIn\FS;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Exception;
/** /**
* File System Task - Move a File * File System Task - Move a File
@ -26,7 +27,12 @@ class MoveTask extends AbstractFileTask
public function getDescription() public function getDescription()
{ {
return sprintf('[FS] Move "%s" to "%s"', $this->getFile('from'), $this->getFile('to')); try {
return sprintf('[FS] Move "%s" to "%s"', $this->getFile('from'), $this->getFile('to'));
} catch (Exception $exception) {
return '[FS] Move [missing parameters]';
}
} }
public function execute() public function execute()

View File

@ -11,6 +11,7 @@
namespace Mage\Task\BuiltIn\FS; namespace Mage\Task\BuiltIn\FS;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Exception;
/** /**
* File System Task - Remove a File * File System Task - Remove a File
@ -26,7 +27,12 @@ class RemoveTask extends AbstractFileTask
public function getDescription() public function getDescription()
{ {
return sprintf('[FS] Remove "%s"', $this->getFile('file')); try {
return sprintf('[FS] Remove "%s"', $this->getFile('file'));
} catch (Exception $exception) {
return '[FS] Remove [missing parameters]';
}
} }
public function execute() public function execute()

View File

@ -10,7 +10,7 @@
namespace Mage\Task\BuiltIn\Git; namespace Mage\Task\BuiltIn\Git;
use Mage\Task\SkipException; use Mage\Task\Exception\SkipException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;

View File

@ -8,7 +8,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Mage\Task; namespace Mage\Task\Exception;
use Exception; use Exception;

View File

@ -8,7 +8,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Mage\Task; namespace Mage\Task\Exception;
use Exception; use Exception;

View File

@ -13,8 +13,6 @@ namespace Mage\Tests\Command\BuiltIn;
use Mage\Command\BuiltIn\DeployCommand; use Mage\Command\BuiltIn\DeployCommand;
use Mage\Tests\MageApplicationMockup; use Mage\Tests\MageApplicationMockup;
use Mage\Command\AbstractCommand; use Mage\Command\AbstractCommand;
use Mage\Runtime\Exception\RuntimeException;
use Exception;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;
@ -95,12 +93,8 @@ class DeployCommandMiscTasksTest extends TestCase
$tester = new CommandTester($command); $tester = new CommandTester($command);
try { $tester->execute(['command' => $command->getName(), 'environment' => 'test']);
$tester->execute(['command' => $command->getName(), 'environment' => 'test']); $this->assertEquals(7, $tester->getStatusCode());
$this->assertTrue(false, 'Command did not failed'); $this->assertContains('Invalid task name "invalid/task"', $tester->getDisplay());
} catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException);
$this->assertEquals('Invalid task name "invalid/task"', $exception->getMessage());
}
} }
} }

View File

@ -192,7 +192,6 @@ class DeployCommandMiscTest extends TestCase
3 => 'composer install --optimize-autoloader', 3 => 'composer install --optimize-autoloader',
4 => 'composer dump-autoload --optimize', 4 => 'composer dump-autoload --optimize',
5 => 'rsync -e "ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -avz --exclude=.git --exclude=./var/cache/* --exclude=./var/log/* --exclude=./web/app_dev.php ./ tester@testhost:/var/www/test', 5 => 'rsync -e "ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -avz --exclude=.git --exclude=./var/cache/* --exclude=./var/log/* --exclude=./web/app_dev.php ./ tester@testhost:/var/www/test',
6 => 'git checkout master',
); );
// Check total of Executed Commands // Check total of Executed Commands

View File

@ -76,13 +76,9 @@ class ListCommandTest extends TestCase
$tester = new CommandTester($command); $tester = new CommandTester($command);
try { $tester->execute(['command' => $command->getName(), 'environment' => 'test']);
$tester->execute(['command' => $command->getName(), 'environment' => 'test']); $this->assertNotEquals(0, $tester->getStatusCode());
$this->assertTrue(false, 'Command did not failed'); $this->assertContains('Releases are not enabled', $tester->getDisplay());
} catch (Exception $exception) {
$this->assertTrue($exception instanceof DeploymentException);
$this->assertEquals('Releases are not enabled', $exception->getMessage());
}
} }
public function testFailToGetCurrentRelease() public function testFailToGetCurrentRelease()
@ -96,13 +92,9 @@ class ListCommandTest extends TestCase
$tester = new CommandTester($command); $tester = new CommandTester($command);
try { $tester->execute(['command' => $command->getName(), 'environment' => 'test']);
$tester->execute(['command' => $command->getName(), 'environment' => 'test']); $this->assertNotEquals(0, $tester->getStatusCode());
$this->assertTrue(false, 'Command did not failed'); $this->assertContains('Unable to retrieve current release from host "host1"', $tester->getDisplay());
} catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException);
$this->assertEquals('Unable to retrieve current release from host "host1"', $exception->getMessage());
}
} }
public function testNoReleasesAvailable() public function testNoReleasesAvailable()
@ -131,13 +123,9 @@ class ListCommandTest extends TestCase
$tester = new CommandTester($command); $tester = new CommandTester($command);
try { $tester->execute(['command' => $command->getName(), 'environment' => 'test']);
$tester->execute(['command' => $command->getName(), 'environment' => 'test']); $this->assertNotEquals(0, $tester->getStatusCode());
$this->assertTrue(false, 'Command did not failed'); $this->assertContains('Unable to retrieve releases from host "host3"', $tester->getDisplay());
} catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException);
$this->assertEquals('Unable to retrieve releases from host "host3"', $exception->getMessage());
}
} }
public function testNoHosts() public function testNoHosts()

View File

@ -75,13 +75,9 @@ class RollbackCommandTest extends TestCase
$tester = new CommandTester($command); $tester = new CommandTester($command);
try { $tester->execute(['command' => $command->getName(), 'environment' => 'test', 'release' => '20170101015115']);
$tester->execute(['command' => $command->getName(), 'environment' => 'test', 'release' => '20170101015115']); $this->assertNotEquals(0, $tester->getStatusCode());
$this->assertTrue(false, 'Command did not failed'); $this->assertContains('Releases are not enabled', $tester->getDisplay());
} catch (Exception $exception) {
$this->assertTrue($exception instanceof DeploymentException);
$this->assertEquals('Releases are not enabled', $exception->getMessage());
}
} }
public function testRollbackReleaseNotAvailable() public function testRollbackReleaseNotAvailable()
@ -95,12 +91,8 @@ class RollbackCommandTest extends TestCase
$tester = new CommandTester($command); $tester = new CommandTester($command);
try { $tester->execute(['command' => $command->getName(), 'environment' => 'test', 'release' => '20170101015115']);
$tester->execute(['command' => $command->getName(), 'environment' => 'test', 'release' => '20170101015115']); $this->assertNotEquals(0, $tester->getStatusCode());
$this->assertTrue(false, 'Command did not failed'); $this->assertContains('Release "20170101015115" is not available on all hosts', $tester->getDisplay());
} catch (Exception $exception) {
$this->assertTrue($exception instanceof DeploymentException);
$this->assertEquals('Release "20170101015115" is not available on all hosts', $exception->getMessage());
}
} }
} }

View File

@ -10,8 +10,8 @@
namespace Mage\Tests\Runtime; namespace Mage\Tests\Runtime;
use Mage\Runtime\Exception\RuntimeException;
use Mage\Runtime\Runtime; use Mage\Runtime\Runtime;
use Mage\Runtime\Exception\InvalidEnvironmentException;
use Exception; use Exception;
use Monolog\Logger; use Monolog\Logger;
use Monolog\Handler\TestHandler; use Monolog\Handler\TestHandler;
@ -66,7 +66,7 @@ class RuntimeTest extends TestCase
$runtime = new Runtime(); $runtime = new Runtime();
$runtime->setEnvironment('invalid'); $runtime->setEnvironment('invalid');
} catch (Exception $exception) { } catch (Exception $exception) {
$this->assertTrue($exception instanceof InvalidEnvironmentException); $this->assertTrue($exception instanceof RuntimeException);
} }
try { try {
@ -74,7 +74,7 @@ class RuntimeTest extends TestCase
$runtime->setConfiguration(['environments' => ['valid' => []]]); $runtime->setConfiguration(['environments' => ['valid' => []]]);
$runtime->setEnvironment('invalid'); $runtime->setEnvironment('invalid');
} catch (Exception $exception) { } catch (Exception $exception) {
$this->assertTrue($exception instanceof InvalidEnvironmentException); $this->assertTrue($exception instanceof RuntimeException);
} }
} }

View File

@ -10,7 +10,7 @@
namespace Mage\Tests\Task; namespace Mage\Tests\Task;
use Mage\Task\ErrorException; use Mage\Task\Exception\ErrorException;
use Exception; use Exception;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;

View File

@ -10,7 +10,7 @@
namespace Mage\Tests\Task\BuiltIn; namespace Mage\Tests\Task\BuiltIn;
use Mage\Runtime\Exception\RuntimeException; use Mage\Task\Exception\ErrorException;
use Mage\Task\BuiltIn\FS\CopyTask; use Mage\Task\BuiltIn\FS\CopyTask;
use Mage\Task\BuiltIn\FS\LinkTask; use Mage\Task\BuiltIn\FS\LinkTask;
use Mage\Task\BuiltIn\FS\MoveTask; use Mage\Task\BuiltIn\FS\MoveTask;
@ -121,10 +121,11 @@ class FileSystemTaskTest extends TestCase
$task->setRuntime($runtime); $task->setRuntime($runtime);
try { try {
$this->assertContains('[missing parameters]', $task->getDescription());
$task->execute(); $task->execute();
$this->assertTrue(false, 'Task did not failed'); $this->assertTrue(false, 'Task did not failed');
} catch (Exception $exception) { } catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException); $this->assertTrue($exception instanceof ErrorException);
$this->assertEquals('Parameter "from" is not defined', $exception->getMessage()); $this->assertEquals('Parameter "from" is not defined', $exception->getMessage());
} }
} }
@ -198,10 +199,11 @@ class FileSystemTaskTest extends TestCase
$task->setRuntime($runtime); $task->setRuntime($runtime);
try { try {
$this->assertContains('[missing parameters]', $task->getDescription());
$task->execute(); $task->execute();
$this->assertTrue(false, 'Task did not failed'); $this->assertTrue(false, 'Task did not failed');
} catch (Exception $exception) { } catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException); $this->assertTrue($exception instanceof ErrorException);
$this->assertEquals('Parameter "from" is not defined', $exception->getMessage()); $this->assertEquals('Parameter "from" is not defined', $exception->getMessage());
} }
} }
@ -273,10 +275,11 @@ class FileSystemTaskTest extends TestCase
$task->setRuntime($runtime); $task->setRuntime($runtime);
try { try {
$this->assertContains('[missing parameters]', $task->getDescription());
$task->execute(); $task->execute();
$this->assertTrue(false, 'Task did not failed'); $this->assertTrue(false, 'Task did not failed');
} catch (Exception $exception) { } catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException); $this->assertTrue($exception instanceof ErrorException);
$this->assertEquals('Parameter "file" is not defined', $exception->getMessage()); $this->assertEquals('Parameter "file" is not defined', $exception->getMessage());
} }
} }
@ -350,10 +353,11 @@ class FileSystemTaskTest extends TestCase
$task->setRuntime($runtime); $task->setRuntime($runtime);
try { try {
$this->assertContains('[missing parameters]', $task->getDescription());
$task->execute(); $task->execute();
$this->assertTrue(false, 'Task did not failed'); $this->assertTrue(false, 'Task did not failed');
} catch (Exception $exception) { } catch (Exception $exception) {
$this->assertTrue($exception instanceof RuntimeException); $this->assertTrue($exception instanceof ErrorException);
$this->assertEquals('Parameter "from" is not defined', $exception->getMessage()); $this->assertEquals('Parameter "from" is not defined', $exception->getMessage());
} }
} }

View File

@ -10,7 +10,7 @@
namespace Mage\Tests\Task; namespace Mage\Tests\Task;
use Mage\Task\ErrorException; use Mage\Task\Exception\ErrorException;
use Mage\Task\AbstractTask; use Mage\Task\AbstractTask;
class TestCaseFailTask extends AbstractTask class TestCaseFailTask extends AbstractTask

View File

@ -19,9 +19,9 @@ class UtilsTest extends TestCase
{ {
public function testStageNames() public function testStageNames()
{ {
$this->assertEquals('Pre Deployment', Utils::getStageName(Runtime::PRE_DEPLOY)); $this->assertEquals('Pre Deploy', Utils::getStageName(Runtime::PRE_DEPLOY));
$this->assertEquals('On Deployment', Utils::getStageName(Runtime::ON_DEPLOY)); $this->assertEquals('On Deploy', Utils::getStageName(Runtime::ON_DEPLOY));
$this->assertEquals('Post Deployment', Utils::getStageName(Runtime::POST_DEPLOY)); $this->assertEquals('Post Deploy', Utils::getStageName(Runtime::POST_DEPLOY));
$this->assertEquals('On Release', Utils::getStageName(Runtime::ON_RELEASE)); $this->assertEquals('On Release', Utils::getStageName(Runtime::ON_RELEASE));
$this->assertEquals('Post Release', Utils::getStageName(Runtime::POST_RELEASE)); $this->assertEquals('Post Release', Utils::getStageName(Runtime::POST_RELEASE));
$this->assertEquals('invalid-stage', Utils::getStageName('invalid-stage')); $this->assertEquals('invalid-stage', Utils::getStageName('invalid-stage'));

View File

@ -30,15 +30,15 @@ class Utils
{ {
switch ($stage) { switch ($stage) {
case Runtime::PRE_DEPLOY: case Runtime::PRE_DEPLOY:
return 'Pre Deployment'; return 'Pre Deploy';
break; break;
case Runtime::ON_DEPLOY: case Runtime::ON_DEPLOY:
return 'On Deployment'; return 'On Deploy';
break; break;
case Runtime::POST_DEPLOY: case Runtime::POST_DEPLOY:
return 'Post Deployment'; return 'Post Deploy';
break; break;
case Runtime::ON_RELEASE: case Runtime::ON_RELEASE: