diff --git a/Mage/Console.php b/Mage/Console.php
index b472701..b93dd8d 100644
--- a/Mage/Console.php
+++ b/Mage/Console.php
@@ -111,7 +111,12 @@ class Mage_Console
switch ($this->_args[1]) {
case 'list':
$task->setAction($this->_args[1]);
- break;
+ break;
+
+ case 'rollback':
+ $task->setAction($this->_args[1]);
+ $task->setRelease($this->_args[2]);
+ break;
}
$task->run($config);
break;
diff --git a/Mage/Task/BuiltIn/Deployment/Releases.php b/Mage/Task/BuiltIn/Deployment/Releases.php
index 7e6fddf..90be299 100644
--- a/Mage/Task/BuiltIn/Deployment/Releases.php
+++ b/Mage/Task/BuiltIn/Deployment/Releases.php
@@ -15,7 +15,14 @@ class Mage_Task_BuiltIn_Deployment_Releases
$currentCopy = $releasesDirectory . '/' . $this->_config->getReleaseId();
- $result = $this->_runRemoteCommand('ln -sf ' . $currentCopy . ' ' . $symlink);
+ $userGroup = '';
+ $resultFetch = $this->_runRemoteCommand('ls -ld ' . $currentCopy . ' | awk \'{print \$3\":\"\$4}\'', $userGroup);
+ $command = 'rm -f ' . $symlink
+ . ' && '
+ . 'ln -sf ' . $currentCopy . ' ' . $symlink
+ . ' && '
+ . 'chown -h ' . $userGroup . ' ' . $symlink;
+ $result = $this->_runRemoteCommand($command);
return $result;
} else {
diff --git a/Mage/Task/BuiltIn/Releases/List.php b/Mage/Task/BuiltIn/Releases/List.php
index e681043..02a793b 100644
--- a/Mage/Task/BuiltIn/Releases/List.php
+++ b/Mage/Task/BuiltIn/Releases/List.php
@@ -46,8 +46,11 @@ class Mage_Task_BuiltIn_Releases_List
}
}
+ Mage_Console::output('');
return $result;
+
} else {
+ Mage_Console::output('');
return false;
}
}
diff --git a/Mage/Task/BuiltIn/Releases/Rollback.php b/Mage/Task/BuiltIn/Releases/Rollback.php
new file mode 100644
index 0000000..74e8ec6
--- /dev/null
+++ b/Mage/Task/BuiltIn/Releases/Rollback.php
@@ -0,0 +1,126 @@
+_release = $releaseId;
+ return $this;
+ }
+
+ public function getRelease()
+ {
+ return $this->_release;
+ }
+
+ public function run()
+ {
+ if ($this->_config->release('enabled', false) == true) {
+ $releasesDirectory = $this->_config->release('directory', 'releases');
+ $symlink = $this->_config->release('symlink', 'current');
+
+ $output = '';
+ $result = $this->_runRemoteCommand('ls -1 ' . $releasesDirectory, $output);
+ $releases = ($output == '') ? array() : explode(PHP_EOL, $output);
+
+ if (count($releases) == 0) {
+ Mage_Console::output('Release are not available for ' . $this->_config->getHost() . ' ... FAIL');
+
+ } else {
+ rsort($releases);
+
+ $releaseIsAvailable = false;
+ if ($this->getRelease() == '') {
+ $releaseId = $releases[0];
+
+ } else if ($this->getRelease() <= 0) {
+ $index = $this->getRelease() * -1;
+ if (isset($releases[$index])) {
+ $releaseId = $releases[$index];
+ $releaseIsAvailable = true;
+ }
+ } else {
+ if (in_array($this->getRelease(), $releases)) {
+ $releaseId = $this->getRelease();
+ $releaseIsAvailable = true;
+ }
+ }
+
+ if (!$releaseIsAvailable) {
+ Mage_Console::output('Release ' . $this->getRelease() . ' is invalid or unavailable for ' . $this->_config->getHost() . ' ... FAIL');
+
+ } else {
+ Mage_Console::output('Rollback release on ' . $this->_config->getHost() . '');
+ $rollbackTo = $releasesDirectory . '/' . $releaseId;
+
+ // Tasks
+ $tasks = 1;
+ $completedTasks = 0;
+ $tasksToRun = $this->_config->getTasks();
+ $this->_config->setReleaseId($releaseId);
+
+ if (count($tasksToRun) == 0) {
+ Mage_Console::output('Warning! No Deployment tasks defined.', 2);
+ Mage_Console::output('Deployment to ' . $this->_config->getHost() . ' skipped!', 1, 3);
+
+ } else {
+ foreach ($tasksToRun as $taskName) {
+ $tasks++;
+ $task = Mage_Task_Factory::get($taskName, $this->_config);
+ $task->init();
+
+ Mage_Console::output('Running ' . $task->getName() . ' ... ', 2, false);
+ $result = $task->run();
+
+ if ($result == true) {
+ Mage_Console::output('OK', 0);
+ $completedTasks++;
+ } else {
+ Mage_Console::output('FAIL', 0);
+ }
+ }
+ }
+
+ // Changing Release
+ Mage_Console::output('Releasing to ' . $releaseId . ' ... ', 2, false);
+
+ $userGroup = '';
+ $resultFetch = $this->_runRemoteCommand('ls -ld ' . $rollbackTo . ' | awk \'{print \$3\":\"\$4}\'', $userGroup);
+ $command = 'rm -f ' . $symlink
+ . ' && '
+ . 'ln -sf ' . $rollbackTo . ' ' . $symlink
+ . ' && '
+ . 'chown -h ' . $userGroup . ' ' . $symlink;
+ $result = $this->_runRemoteCommand($command);
+
+ if ($result) {
+ Mage_Console::output('OK', 0);
+ $completedTasks++;
+ } else {
+ Mage_Console::output('FAIL', 0);
+ }
+
+ if ($completedTasks == $tasks) {
+ $tasksColor = 'green';
+ } else {
+ $tasksColor = 'red';
+ }
+
+ Mage_Console::output('Release rollback on ' . $this->_config->getHost() . ' compted: <' . $tasksColor . '>' . $completedTasks . '/' . $tasks . '' . $tasksColor . '> tasks done.', 1, 3);
+ }
+ }
+
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Mage/Task/Deploy.php b/Mage/Task/Deploy.php
index 434fd6b..aa91ed5 100644
--- a/Mage/Task/Deploy.php
+++ b/Mage/Task/Deploy.php
@@ -31,6 +31,8 @@ class Mage_Task_Deploy
Mage_Console::output('Deploying to ' . $host . '');
$tasksToRun = $config->getTasks();
+ array_unshift($tasksToRun, 'deployment/rsync');
+
if ($config->release('enabled', false) == true) {
$config->setReleaseId($this->_releaseId);
array_push($tasksToRun, 'deployment/releases');
@@ -57,8 +59,6 @@ class Mage_Task_Deploy
}
}
- // Run Post-Deployment Tasks
-
if ($completedTasks == $tasks) {
$tasksColor = 'green';
} else {
diff --git a/Mage/Task/Releases.php b/Mage/Task/Releases.php
index 190e65c..4275360 100644
--- a/Mage/Task/Releases.php
+++ b/Mage/Task/Releases.php
@@ -3,6 +3,7 @@ class Mage_Task_Releases
{
private $_config = null;
private $_action = null;
+ private $_release = null;
public function setAction($action)
{
@@ -15,6 +16,17 @@ class Mage_Task_Releases
return $this->_action;
}
+ public function setRelease($releaseId)
+ {
+ $this->_release = $releaseId;
+ return $this;
+ }
+
+ public function getRelease()
+ {
+ return $this->_release;
+ }
+
public function run(Mage_Config $config)
{
$this->_config = $config;
@@ -34,11 +46,16 @@ class Mage_Task_Releases
$task->init();
$result = $task->run();
break;
+
+ case 'rollback':
+ $task = Mage_Task_Factory::get('releases/rollback', $config);
+ $task->init();
+ $task->setRelease($this->getRelease());
+ $result = $task->run();
+ break;
}
- Mage_Console::output('');
}
}
-
}
private function _listReleases()
diff --git a/bin/mage.php b/bin/mage.php
index 67b3a51..6024338 100644
--- a/bin/mage.php
+++ b/bin/mage.php
@@ -7,10 +7,11 @@
# mage releases list to:production
# mage releases rollback to:production
-# mage releases rollback:-1 to:production
-# mage releases rollback:-2 to:production
-# mage releases rollback:-3 to:production
-# mage releases rollback:0 to:production
+# mage releases rollback -1 to:production
+# mage releases rollback -2 to:production
+# mage releases rollback -3 to:production
+# mage releases rollback 0 to:production
+# mage releases rollback 20120101172148 to:production
# mage add environment production --width-releases
# mage init
diff --git a/docs/example-config/.mage/config/environment/production.yaml b/docs/example-config/.mage/config/environment/production.yaml
index f50bb40..5874fb1 100644
--- a/docs/example-config/.mage/config/environment/production.yaml
+++ b/docs/example-config/.mage/config/environment/production.yaml
@@ -19,6 +19,5 @@ tasks:
pre-deploy:
- scm/update
on-deploy:
- - deployment/rsync
- privileges
#post-deploy:
\ No newline at end of file
diff --git a/docs/example-config/.mage/config/environment/staging.yaml b/docs/example-config/.mage/config/environment/staging.yaml
index 7fb44e0..97b604a 100644
--- a/docs/example-config/.mage/config/environment/staging.yaml
+++ b/docs/example-config/.mage/config/environment/staging.yaml
@@ -9,6 +9,5 @@ tasks:
pre-deploy:
- scm/update
on-deploy:
- - deployment/rsync
- privileges
#post-deploy:
\ No newline at end of file