diff --git a/Mage/Command/BuiltIn/DeployCommand.php b/Mage/Command/BuiltIn/DeployCommand.php
index 916d546..3140f2f 100644
--- a/Mage/Command/BuiltIn/DeployCommand.php
+++ b/Mage/Command/BuiltIn/DeployCommand.php
@@ -30,28 +30,28 @@ use Exception;
*/
class DeployCommand extends AbstractCommand implements RequiresEnvironment
{
- /**
- * Deploy has Failed
- * @var string
- */
- const FAILED = 'failed';
-
- /**
- * Deploy has Succeded
- * @var string
- */
- const SUCCEDED = 'succeded';
-
- /**
- * Deploy is in progress
- * @var string
- */
- const IN_PROGRESS = 'in_progress';
-
- /**
- * Time the Deployment has Started
- * @var integer
- */
+ /**
+ * Deploy has Failed
+ * @var string
+ */
+ const FAILED = 'failed';
+
+ /**
+ * Deploy has Succeded
+ * @var string
+ */
+ const SUCCEDED = 'succeded';
+
+ /**
+ * Deploy is in progress
+ * @var string
+ */
+ const IN_PROGRESS = 'in_progress';
+
+ /**
+ * Time the Deployment has Started
+ * @var integer
+ */
protected $startTime = null;
/**
@@ -91,7 +91,7 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
*/
public static function getStatus()
{
- return self::$deployStatus;
+ return self::$deployStatus;
}
/**
@@ -101,19 +101,19 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
public function run()
{
// Check if Environment is not Locked
- $lockFile = '.mage/' . $this->getConfig()->getEnvironment() . '.lock';
- if (file_exists($lockFile)) {
- Console::output('This environment is locked!', 1, 2);
- return;
- }
-
- // Check for running instance and Lock
- if (file_exists('.mage/~working.lock')) {
- Console::output('There is already an instance of Magallanes running!', 1, 2);
- return;
- } else {
- touch('.mage/~working.lock');
- }
+ $lockFile = '.mage/' . $this->getConfig()->getEnvironment() . '.lock';
+ if (file_exists($lockFile)) {
+ Console::output('This environment is locked!', 1, 2);
+ return;
+ }
+
+ // Check for running instance and Lock
+ if (file_exists('.mage/~working.lock')) {
+ Console::output('There is already an instance of Magallanes running!', 1, 2);
+ return;
+ } else {
+ touch('.mage/~working.lock');
+ }
// Release ID
$this->getConfig()->setReleaseId(date('YmdHis'));
@@ -126,15 +126,15 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
// Deploy Summary - Releases
if ($this->getConfig()->release('enabled', false)) {
- Console::output('Release ID: ' . $this->getConfig()->getReleaseId() . '', 2, 1);
+ Console::output('Release ID: ' . $this->getConfig()->getReleaseId() . '', 2, 1);
}
// Deploy Summary - SCM
if ($this->getConfig()->deployment('scm', false)) {
- $scmConfig = $this->getConfig()->deployment('scm');
- if (isset($scmConfig['branch'])) {
- Console::output('SCM Branch: ' . $scmConfig['branch'] . '', 2, 1);
- }
+ $scmConfig = $this->getConfig()->deployment('scm');
+ if (isset($scmConfig['branch'])) {
+ Console::output('SCM Branch: ' . $scmConfig['branch'] . '', 2, 1);
+ }
}
// Deploy Summary - Separator Line
@@ -147,21 +147,21 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
// Check Status
if (self::$failedTasks > 0) {
- self::$deployStatus = self::FAILED;
- Console::output('A total of ' . self::$failedTasks . ' deployment tasks failed: ABORTING', 1, 2);
+ self::$deployStatus = self::FAILED;
+ Console::output('A total of ' . self::$failedTasks . ' deployment tasks failed: ABORTING', 1, 2);
} else {
- // Run Deployment Tasks
- $this->runDeploymentTasks();
+ // Run Deployment Tasks
+ $this->runDeploymentTasks();
- // Check Status
- if (self::$failedTasks > 0) {
- self::$deployStatus = self::FAILED;
- Console::output('A total of ' . self::$failedTasks . ' deployment tasks failed: ABORTING', 1, 2);
- }
+ // Check Status
+ if (self::$failedTasks > 0) {
+ self::$deployStatus = self::FAILED;
+ Console::output('A total of ' . self::$failedTasks . ' deployment tasks failed: ABORTING', 1, 2);
+ }
- // Run Post-Deployment Tasks
- $this->runNonDeploymentTasks(AbstractTask::STAGE_POST_DEPLOY, $this->getConfig(), 'Post-Deployment');
+ // Run Post-Deployment Tasks
+ $this->runNonDeploymentTasks(AbstractTask::STAGE_POST_DEPLOY, $this->getConfig(), 'Post-Deployment');
}
// Time Information Hosts
@@ -182,7 +182,7 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
// Unlock
if (file_exists('.mage/~working.lock')) {
- unlink('.mage/~working.lock');
+ unlink('.mage/~working.lock');
}
}
@@ -200,33 +200,33 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
// PreDeployment Hook
if ($stage == AbstractTask::STAGE_PRE_DEPLOY) {
- // Look for Remote Source
- if (is_array($config->deployment('source', null))) {
- array_unshift($tasksToRun, 'scm/clone');
- }
-
- // Change Branch
- if ($config->deployment('scm', false)) {
- array_unshift($tasksToRun, 'scm/change-branch');
- }
+ // Look for Remote Source
+ if (is_array($config->deployment('source', null))) {
+ array_unshift($tasksToRun, 'scm/clone');
+ }
+
+ // Change Branch
+ if ($config->deployment('scm', false)) {
+ array_unshift($tasksToRun, 'scm/change-branch');
+ }
}
// PostDeployment Hook
if ($stage == AbstractTask::STAGE_POST_DEPLOY) {
- // If Deploy failed, clear post deploy tasks
- if (self::$deployStatus == self::FAILED) {
- $tasksToRun = array();
- }
-
- // Change Branch Back
- if ($config->deployment('scm', false)) {
- array_unshift($tasksToRun, 'scm/change-branch');
- $config->addParameter('_changeBranchRevert');
- }
-
- // Remove Remote Source
- if (is_array($config->deployment('source', null))) {
- array_push($tasksToRun, 'scm/remove-clone');
+ // If Deploy failed, clear post deploy tasks
+ if (self::$deployStatus == self::FAILED) {
+ $tasksToRun = array();
+ }
+
+ // Change Branch Back
+ if ($config->deployment('scm', false)) {
+ array_unshift($tasksToRun, 'scm/change-branch');
+ $config->addParameter('_changeBranchRevert');
+ }
+
+ // Remove Remote Source
+ if (is_array($config->deployment('source', null))) {
+ array_push($tasksToRun, 'scm/remove-clone');
}
}
@@ -246,7 +246,7 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
if ($this->runTask($task)) {
$completedTasks++;
} else {
- self::$failedTasks++;
+ self::$failedTasks++;
}
}
@@ -262,173 +262,177 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
protected function runDeploymentTasks()
{
- if (self::$deployStatus == self::FAILED) {
- return;
- }
-
- // Run Tasks for Deployment
- $hosts = $this->getConfig()->getHosts();
- $this->hostsCount = count($hosts);
- self::$failedTasks = 0;
-
- if ($this->hostsCount == 0) {
- Console::output('Warning! No hosts defined, skipping deployment tasks.', 1, 3);
-
- } else {
- $this->startTimeHosts = time();
- foreach ($hosts as $hostKey => $host) {
-
- // Check if Host has specific configuration
- $hostConfig = null;
- if (is_array($host)) {
- $hostConfig = $host;
- $host = $hostKey;
- }
-
- // Set Host and Host Specific Config
- $this->getConfig()->setHost($host);
- $this->getConfig()->setHostConfig($hostConfig);
-
- // Prepare Tasks
- $tasks = 0;
- $completedTasks = 0;
-
- Console::output('Deploying to ' . $this->getConfig()->getHost() . '');
-
- $tasksToRun = $this->getConfig()->getTasks();
-
- // Guess a Deploy Strategy
- switch ($this->getConfig()->deployment('strategy', 'guess')) {
- case 'disabled':
- $deployStrategy = 'deployment/strategy/disabled';
- break;
-
- case 'rsync':
- $deployStrategy = 'deployment/strategy/rsync';
- break;
-
- case 'targz':
- $deployStrategy = 'deployment/strategy/tar-gz';
- break;
-
- case 'guess':
- default:
- if ($this->getConfig()->release('enabled', false) == true) {
- $deployStrategy = 'deployment/strategy/tar-gz';
- } else {
- $deployStrategy = 'deployment/strategy/rsync';
- }
- break;
- }
-
- array_unshift($tasksToRun, $deployStrategy);
-
- if (count($tasksToRun) == 0) {
- Console::output('Warning! No Deployment tasks defined.', 2);
- Console::output('Deployment to ' . $host . ' skipped!', 1, 3);
-
- } else {
- foreach ($tasksToRun as $taskData) {
- $tasks++;
- $task = Factory::get($taskData, $this->getConfig(), false, AbstractTask::STAGE_DEPLOY);
-
- if ($this->runTask($task)) {
- $completedTasks++;
- } else {
- self::$failedTasks++;
- }
- }
-
- if ($completedTasks == $tasks) {
- $tasksColor = 'green';
- } else {
- $tasksColor = 'red';
- }
-
- Console::output('Deployment to ' . $this->getConfig()->getHost() . ' completed: <' . $tasksColor . '>' . $completedTasks . '/' . $tasks . '' . $tasksColor . '> tasks done.', 1, 3);
- }
-
- // Reset Host Config
- $this->getConfig()->setHostConfig(null);
- }
- $this->endTimeHosts = time();
-
- if (self::$failedTasks > 0) {
- self::$deployStatus = self::FAILED;
- } else {
- self::$deployStatus = self::SUCCEDED;
- }
-
- // Releasing
- if (self::$deployStatus == self::SUCCEDED && $this->getConfig()->release('enabled', false) == true) {
- // Execute the Releases
- Console::output('Starting the Releasing');
- foreach ($hosts as $hostKey => $host) {
-
- // Check if Host has specific configuration
- $hostConfig = null;
- if (is_array($host)) {
- $hostConfig = $host;
- $host = $hostKey;
- }
-
- // Set Host
- $this->getConfig()->setHost($host);
- $this->getConfig()->setHostConfig($hostConfig);
-
- $task = Factory::get('deployment/release', $this->getConfig(), false, AbstractTask::STAGE_DEPLOY);
-
- if ($this->runTask($task, 'Releasing on host ' . $host . ' ... ')) {
- $completedTasks++;
- }
-
- // Reset Host Config
- $this->getConfig()->setHostConfig(null);
- }
- Console::output('Finished the Releasing', 1, 3);
-
- // Execute the Post-Release Tasks
- foreach ($hosts as $hostKey => $host) {
-
- // Check if Host has specific configuration
- $hostConfig = null;
- if (is_array($host)) {
- $hostConfig = $host;
- $host = $hostKey;
- }
-
- // Set Host
- $this->getConfig()->setHost($host);
- $this->getConfig()->setHostConfig($hostConfig);
-
- $tasksToRun = $this->getConfig()->getTasks(AbstractTask::STAGE_POST_RELEASE);
- $tasks = count($tasksToRun);
- $completedTasks = 0;
-
- if (count($tasksToRun) > 0) {
- Console::output('Starting Post-Release tasks for ' . $host . ':');
-
- foreach ($tasksToRun as $task) {
- $task = Factory::get($task, $this->getConfig(), false, AbstractTask::STAGE_POST_RELEASE);
-
- if ($this->runTask($task)) {
- $completedTasks++;
- }
- }
-
- if ($completedTasks == $tasks) {
- $tasksColor = 'green';
- } else {
- $tasksColor = 'red';
- }
- Console::output('Finished Post-Release tasks for ' . $host . ': <' . $tasksColor . '>' . $completedTasks . '/' . $tasks . '' . $tasksColor . '> tasks done.', 1, 3);
- }
-
- // Reset Host Config
- $this->getConfig()->setHostConfig(null);
- }
- }
- }
+ if (self::$deployStatus == self::FAILED) {
+ return;
+ }
+
+ // Run Tasks for Deployment
+ $hosts = $this->getConfig()->getHosts();
+ $this->hostsCount = count($hosts);
+ self::$failedTasks = 0;
+
+ if ($this->hostsCount == 0) {
+ Console::output('Warning! No hosts defined, skipping deployment tasks.', 1, 3);
+
+ } else {
+ $this->startTimeHosts = time();
+ foreach ($hosts as $hostKey => $host) {
+
+ // Check if Host has specific configuration
+ $hostConfig = null;
+ if (is_array($host)) {
+ $hostConfig = $host;
+ $host = $hostKey;
+ }
+
+ // Set Host and Host Specific Config
+ $this->getConfig()->setHost($host);
+ $this->getConfig()->setHostConfig($hostConfig);
+
+ // Prepare Tasks
+ $tasks = 0;
+ $completedTasks = 0;
+
+ Console::output('Deploying to ' . $this->getConfig()->getHost() . '');
+
+ $tasksToRun = $this->getConfig()->getTasks();
+
+ // Guess a Deploy Strategy
+ switch ($this->getConfig()->deployment('strategy', 'guess')) {
+ case 'disabled':
+ $deployStrategy = 'deployment/strategy/disabled';
+ break;
+
+ case 'rsync':
+ $deployStrategy = 'deployment/strategy/rsync';
+ break;
+
+ case 'targz':
+ $deployStrategy = 'deployment/strategy/tar-gz';
+ break;
+
+ case 'remote-cache':
+ $deployStrategy = 'deployment/strategy/git-remote-cache';
+ break;
+
+ case 'guess':
+ default:
+ if ($this->getConfig()->release('enabled', false) == true) {
+ $deployStrategy = 'deployment/strategy/tar-gz';
+ } else {
+ $deployStrategy = 'deployment/strategy/rsync';
+ }
+ break;
+ }
+
+ array_unshift($tasksToRun, $deployStrategy);
+
+ if (count($tasksToRun) == 0) {
+ Console::output('Warning! No Deployment tasks defined.', 2);
+ Console::output('Deployment to ' . $host . ' skipped!', 1, 3);
+
+ } else {
+ foreach ($tasksToRun as $taskData) {
+ $tasks++;
+ $task = Factory::get($taskData, $this->getConfig(), false, AbstractTask::STAGE_DEPLOY);
+
+ if ($this->runTask($task)) {
+ $completedTasks++;
+ } else {
+ self::$failedTasks++;
+ }
+ }
+
+ if ($completedTasks == $tasks) {
+ $tasksColor = 'green';
+ } else {
+ $tasksColor = 'red';
+ }
+
+ Console::output('Deployment to ' . $this->getConfig()->getHost() . ' completed: <' . $tasksColor . '>' . $completedTasks . '/' . $tasks . '' . $tasksColor . '> tasks done.', 1, 3);
+ }
+
+ // Reset Host Config
+ $this->getConfig()->setHostConfig(null);
+ }
+ $this->endTimeHosts = time();
+
+ if (self::$failedTasks > 0) {
+ self::$deployStatus = self::FAILED;
+ } else {
+ self::$deployStatus = self::SUCCEDED;
+ }
+
+ // Releasing
+ if (self::$deployStatus == self::SUCCEDED && $this->getConfig()->release('enabled', false) == true) {
+ // Execute the Releases
+ Console::output('Starting the Releasing');
+ foreach ($hosts as $hostKey => $host) {
+
+ // Check if Host has specific configuration
+ $hostConfig = null;
+ if (is_array($host)) {
+ $hostConfig = $host;
+ $host = $hostKey;
+ }
+
+ // Set Host
+ $this->getConfig()->setHost($host);
+ $this->getConfig()->setHostConfig($hostConfig);
+
+ $task = Factory::get('deployment/release', $this->getConfig(), false, AbstractTask::STAGE_DEPLOY);
+
+ if ($this->runTask($task, 'Releasing on host ' . $host . ' ... ')) {
+ $completedTasks++;
+ }
+
+ // Reset Host Config
+ $this->getConfig()->setHostConfig(null);
+ }
+ Console::output('Finished the Releasing', 1, 3);
+
+ // Execute the Post-Release Tasks
+ foreach ($hosts as $hostKey => $host) {
+
+ // Check if Host has specific configuration
+ $hostConfig = null;
+ if (is_array($host)) {
+ $hostConfig = $host;
+ $host = $hostKey;
+ }
+
+ // Set Host
+ $this->getConfig()->setHost($host);
+ $this->getConfig()->setHostConfig($hostConfig);
+
+ $tasksToRun = $this->getConfig()->getTasks(AbstractTask::STAGE_POST_RELEASE);
+ $tasks = count($tasksToRun);
+ $completedTasks = 0;
+
+ if (count($tasksToRun) > 0) {
+ Console::output('Starting Post-Release tasks for ' . $host . ':');
+
+ foreach ($tasksToRun as $task) {
+ $task = Factory::get($task, $this->getConfig(), false, AbstractTask::STAGE_POST_RELEASE);
+
+ if ($this->runTask($task)) {
+ $completedTasks++;
+ }
+ }
+
+ if ($completedTasks == $tasks) {
+ $tasksColor = 'green';
+ } else {
+ $tasksColor = 'red';
+ }
+ Console::output('Finished Post-Release tasks for ' . $host . ': <' . $tasksColor . '>' . $completedTasks . '/' . $tasks . '' . $tasksColor . '> tasks done.', 1, 3);
+ }
+
+ // Reset Host Config
+ $this->getConfig()->setHostConfig(null);
+ }
+ }
+ }
}
/**
@@ -466,8 +470,8 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
$result = false;
}
} catch (ErrorWithMessageException $e) {
- Console::output('FAIL [Message: ' . $e->getMessage() . ']', 0);
- $result = false;
+ Console::output('FAIL [Message: ' . $e->getMessage() . ']', 0);
+ $result = false;
} catch (SkipException $e) {
Console::output('SKIPPED', 0);
@@ -519,11 +523,11 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
*/
protected function sendNotification($result)
{
- $projectName = $this->getConfig()->general('name', false);
- $projectEmail = $this->getConfig()->general('email', false);
- $notificationsEnabled = $this->getConfig()->general('notifications', false);
+ $projectName = $this->getConfig()->general('name', false);
+ $projectEmail = $this->getConfig()->general('email', false);
+ $notificationsEnabled = $this->getConfig()->general('notifications', false);
- // We need notifications enabled, and a project name and email to send the notification
+ // We need notifications enabled, and a project name and email to send the notification
if (!$projectName || !$projectEmail || !$notificationsEnabled) {
return false;
}
diff --git a/Mage/Task/BuiltIn/Deployment/Strategy/GitRemoteCacheTask.php b/Mage/Task/BuiltIn/Deployment/Strategy/GitRemoteCacheTask.php
new file mode 100644
index 0000000..43296c3
--- /dev/null
+++ b/Mage/Task/BuiltIn/Deployment/Strategy/GitRemoteCacheTask.php
@@ -0,0 +1,137 @@
+
+ */
+class GitRemoteCacheTask extends AbstractTask implements IsReleaseAware
+{
+ /**
+ * Returns the Title of the Task
+ * @return string
+ */
+ public function getName()
+ {
+ return 'Deploy via remote cached git repository [built-in]';
+ }
+
+ /**
+ * Runs the task
+ *
+ * @return boolean
+ * @throws Exception
+ * @throws ErrorWithMessageException
+ * @throws SkipException
+ */
+ public function run()
+ {
+ $overrideRelease = $this->getParameter('overrideRelease', false);
+
+ if ($overrideRelease == true) {
+ $releaseToOverride = false;
+ $resultFetch = $this->runCommandRemote('ls -ld current | cut -d"/" -f2', $releaseToOverride);
+ if ($resultFetch && is_numeric($releaseToOverride)) {
+ $this->getConfig()->setReleaseId($releaseToOverride);
+ }
+ }
+
+ $excludes = array(
+ '.git',
+ '.svn',
+ '.mage',
+ '.gitignore',
+ '.gitkeep',
+ 'nohup.out'
+ );
+
+ // Look for User Excludes
+ $userExcludes = $this->getConfig()->deployment('excludes', array());
+
+ $deployToDirectory = $this->getConfig()->deployment('to');
+ if ($this->getConfig()->release('enabled', false) == true) {
+ $releasesDirectory = $this->getConfig()->release('directory', 'releases');
+
+ $deployToDirectory = rtrim($this->getConfig()->deployment('to'), '/')
+ . '/' . $releasesDirectory
+ . '/' . $this->getConfig()->getReleaseId();
+ $this->runCommandRemote('mkdir -p ' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId());
+ }
+
+ $branch = $this->getParameter('branch');
+ $remote = $this->getParameter('remote', 'origin');
+
+ $remoteCacheParam = $this->getParameter('remote_cache', 'shared/git-remote-cache');
+ $remoteCacheFolder = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $remoteCacheParam;
+
+ // Don't use -C as git 1.7 does not support it
+ $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git fetch ' . $remote;
+ $result = $this->runCommandRemote($command);
+
+ $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git checkout ' . $branch;
+ $result = $this->runCommandRemote($command) && $result;
+
+ $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git pull --rebase ' . $branch;
+ $result = $this->runCommandRemote($command) && $result;
+
+ $excludes = array_merge($excludes, $userExcludes);
+ $excludeCmd = '';
+ foreach ($excludes as $excludeFile) {
+ $excludeCmd .= ' --exclude=' . $excludeFile;
+ }
+
+ $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git archive ' . $branch . ' | tar -x -C ' . $deployToDirectory . ' ' . $excludeCmd;
+ $result = $this->runCommandRemote($command) && $result;
+
+ // Count Releases
+ if ($this->getConfig()->release('enabled', false) == true) {
+ $releasesDirectory = $this->getConfig()->release('directory', 'releases');
+ $symlink = $this->getConfig()->release('symlink', 'current');
+
+ if (substr($symlink, 0, 1) == '/') {
+ $releasesDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory;
+ }
+
+ $maxReleases = $this->getConfig()->release('max', false);
+ if (($maxReleases !== false) && ($maxReleases > 0)) {
+ $releasesList = '';
+ $countReleasesFetch = $this->runCommandRemote('ls -1 ' . $releasesDirectory, $releasesList);
+ $releasesList = trim($releasesList);
+
+ if ($countReleasesFetch && $releasesList != '') {
+ $releasesList = explode(PHP_EOL, $releasesList);
+ if (count($releasesList) > $maxReleases) {
+ $releasesToDelete = array_diff($releasesList, array($this->getConfig()->getReleaseId()));
+ sort($releasesToDelete);
+ $releasesToDeleteCount = count($releasesToDelete) - $maxReleases;
+ $releasesToDelete = array_slice($releasesToDelete, 0, $releasesToDeleteCount + 1);
+
+ foreach ($releasesToDelete as $releaseIdToDelete) {
+ $directoryToDelete = $releasesDirectory . '/' . $releaseIdToDelete;
+ if ($directoryToDelete != '/') {
+ $command = 'rm -rf ' . $directoryToDelete;
+ $result = $result && $this->runCommandRemote($command);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return $result;
+ }
+}