From ffd2747757dcc6ed9bf0636fa93165102d072bd6 Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Thu, 16 Jan 2014 12:50:28 -0500 Subject: [PATCH 1/9] stubbing things out. --- lib/Pomander.php | 17 +++++++++++------ lib/Pomander/Environment.php | 15 ++++++++------- lib/Pomander/Method.php | 28 ++++++++++++++++++++++++++++ lib/Pomander/Method/Git.php | 25 +++++++++++++++++++++++++ lib/Pomander/Method/Rsync.php | 0 lib/Pomander/Method/Svn.php | 0 6 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 lib/Pomander/Method.php create mode 100644 lib/Pomander/Method/Git.php create mode 100644 lib/Pomander/Method/Rsync.php create mode 100644 lib/Pomander/Method/Svn.php diff --git a/lib/Pomander.php b/lib/Pomander.php index 1b81455..e4a45b0 100644 --- a/lib/Pomander.php +++ b/lib/Pomander.php @@ -54,19 +54,24 @@ function after($task, $lambda) { builder()->after($task, $lambda); } function desc($description) { builder()->desc($description); } //utils -function info($status,$msg) +function info($status, $msg, $output = true) { - puts(" * ".ansicolor("info ",32).ansicolor("$status ",35).$msg); + $line = " * ".ansicolor("info ", 32).ansicolor("$status ", 35).$msg; + return $output? puts($line) : $line; } -function warn($status,$msg) +function warn($status, $msg, $output = true) { - puts(" * ".ansicolor("warn ",33).ansicolor("$status ",35).$msg); + $line = " * ".ansicolor("warn ", 33).ansicolor("$status ", 35).$msg; + return $output? puts($line) : $line; } -function abort($status, $msg, $code=1) +function abort($status, $msg, $code=1, $output = true) { - puts(" * ".ansicolor("abort ",31).ansicolor("$status ",35).$msg); + $line = " * ".ansicolor("abort ", 31).ansicolor("$status ", 35).$msg; + if( !$output ) return $line . " && false"; + + puts($line); die($code); } diff --git a/lib/Pomander/Environment.php b/lib/Pomander/Environment.php index 1037936..e3a1ae9 100644 --- a/lib/Pomander/Environment.php +++ b/lib/Pomander/Environment.php @@ -3,7 +3,7 @@ class Environment { - public $name, $target, $scm, $adapter; + public $name, $target, $method, $adapter; private $config, $shell, $mysql; private $roles; @@ -45,7 +45,7 @@ public function setup() $this->shared_dir = $this->deploy_to.'/shared'; $this->cache_dir = $this->shared_dir.'/cached_copy'; } - $this->init_scm_adapter(); + $this->init_method_adapter(); } public function __call($name, $arguments) @@ -160,7 +160,6 @@ private function defaults() "app"=>"", "db"=>"", "method"=>"git", - "scm"=>"git", "adapter"=>"mysql", "port"=>22, "umask"=>"002", @@ -187,11 +186,13 @@ private function update_target($target) return true; } - private function init_scm_adapter() + private function init_method_adapter() { - $scm = "\\Pomander\\Scm\\".ucwords(strtolower($this->config["scm"])); - if( !$this->scm = new $scm($this->repository) ) - abort("scm","There is no recipe for {$this->config["scm"]}, perhaps create your own?"); + $method = $this->config["method"]; + if( empty($this->config["method"]) && isset($this->config["scm"]) ) $method = $this->config["scm"]; + $method = "\\Pomander\\Method\\".ucwords(strtolower($method)); + if( !$this->method = new $method($this->repository) ) + abort("method","There is no recipe for {$this->config["method"]}, perhaps create your own?"); $adapter = "\\Pomander\\Db\\".ucwords(strtolower($this->config["adapter"])); if( !$this->adapter = new $adapter($this->database) ) abort("db","There is no recipe for {$this->config["adapter"]}, perhaps create your own?"); diff --git a/lib/Pomander/Method.php b/lib/Pomander/Method.php new file mode 100644 index 0000000..7da527c --- /dev/null +++ b/lib/Pomander/Method.php @@ -0,0 +1,28 @@ +repository = $repository; + $this->app = builder()->get_application(); + } + + public function setup() + { + + } + + public function update() + { + + } + + public function finalize() + { + + } +} diff --git a/lib/Pomander/Method/Git.php b/lib/Pomander/Method/Git.php new file mode 100644 index 0000000..6f7961c --- /dev/null +++ b/lib/Pomander/Method/Git.php @@ -0,0 +1,25 @@ +app->env->releases === false ) { + + } + + } + + public function update() + { + + } + + public function finalize() + { + + } +} diff --git a/lib/Pomander/Method/Rsync.php b/lib/Pomander/Method/Rsync.php new file mode 100644 index 0000000..e69de29 diff --git a/lib/Pomander/Method/Svn.php b/lib/Pomander/Method/Svn.php new file mode 100644 index 0000000..e69de29 From 941216a632630aaddd95a42eab34b64262381374 Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Thu, 30 Jan 2014 16:28:37 -0500 Subject: [PATCH 2/9] first shot at the default method with git --- lib/Pomander.php | 38 +++++---- lib/Pomander/Method.php | 148 +++++++++++++++++++++++++++++++++++- lib/Pomander/Method/Git.php | 73 ++++++++++++++++-- lib/tasks/deploy.php | 75 +++--------------- 4 files changed, 241 insertions(+), 93 deletions(-) diff --git a/lib/Pomander.php b/lib/Pomander.php index 6d19bba..d726b8c 100644 --- a/lib/Pomander.php +++ b/lib/Pomander.php @@ -18,7 +18,7 @@ public static function version() // phake helpers function builder() { - if(!isset(Builder::$global)) Builder::$global = new Builder; + if (!isset(Builder::$global)) Builder::$global = new Builder; return Builder::$global; } @@ -27,7 +27,7 @@ function task() { $deps = func_get_args(); $name = array_shift($deps); - if($deps[count($deps) - 1] instanceof Closure) + if ($deps[count($deps) - 1] instanceof Closure) $work = array_pop($deps); else $work = null; @@ -56,26 +56,26 @@ function desc($description) { builder()->desc($description); } //utils function info($status, $msg, $output = true) { - $line = " * ".ansicolor("info ", 32).ansicolor("$status ", 35).$msg; + $line = " * " . ansicolor("info ", 32) . ansicolor("$status ", 35) . $msg; return $output? puts($line) : $line; } function warn($status, $msg, $output = true) { - $line = " * ".ansicolor("warn ", 33).ansicolor("$status ", 35).$msg; + $line = " * " . ansicolor("warn ", 33) . ansicolor("$status ", 35) . $msg; return $output? puts($line) : $line; } function abort($status, $msg, $code=1, $output = true) { - $line = " * ".ansicolor("abort ", 31).ansicolor("$status ", 35).$msg; + $line = " * " . ansicolor("abort ", 31) . ansicolor("$status ", 35) . $msg; if( !$output ) return $line . " && false"; puts($line); die($code); } -function ansicolor($text,$color) +function ansicolor($text, $color) { #31 red #32 green @@ -90,8 +90,7 @@ function puts($text) { echo $text.PHP_EOL; } function home() { $app = builder()->get_application(); - if(!isset($app->home)) - $app->home = trim(shell_exec("cd && pwd"),"\r\n"); + if (!isset($app->home)) $app->home = trim(shell_exec('cd && pwd'), "\r\n"); return $app->home; } @@ -99,21 +98,21 @@ function home() function run() { $cmd = array(); - $silent = false; $args = func_get_args(); - if(is_bool($args[count($args)-1])) $silent = array_pop($args); + $silent = is_bool($args[count($args)-1])? array_pop($args) : false; array_walk_recursive($args, function ($v) use (&$cmd) { $cmd[] = $v; }); - $cmd = implode(" && ",$cmd); + $cmd = implode(' && ', $cmd); + if (empty($cmd)) return; $app = builder()->get_application(); list($status, $output) = !isset($app->env)? run_local($cmd) : $app->env->exec($cmd); - if(!$silent && count($output)) puts(implode("\n", $output)); + if (!$silent && count($output)) puts(implode("\n", $output)); if ($status > 0) { if ($app->can_rollback) { - warn("fail","Rolling back..."); + warn("fail", "Rolling back..."); $app->invoke('rollback'); - info("rollback","rollback complete."); + info("rollback", "rollback complete."); exit($status); return; @@ -126,26 +125,23 @@ function run() function run_local($cmd) { - $cmd = is_array($cmd)? implode(" && ",$cmd) : $cmd; + $cmd = is_array($cmd)? implode(" && ", $cmd) : $cmd; exec($cmd, $output, $status); return array($status, $output); } // Deprecated: use run_local() -function exec_cmd($cmd) -{ - return run_local($cmd); -} +function exec_cmd($cmd) { return run_local($cmd); } function put($what,$where) { - if(!isset(builder()->get_application()->env)) return run_local("cp -R $what $where"); + if (!isset(builder()->get_application()->env)) return run_local("cp -R $what $where"); builder()->get_application()->env->put($what,$where); } function get($what,$where) { - if(!isset(builder()->get_application()->env)) return run_local("cp -R $what $where"); + if (!isset(builder()->get_application()->env)) return run_local("cp -R $what $where"); builder()->get_application()->env->get($what,$where); } diff --git a/lib/Pomander/Method.php b/lib/Pomander/Method.php index 7da527c..d83855b 100644 --- a/lib/Pomander/Method.php +++ b/lib/Pomander/Method.php @@ -11,18 +11,164 @@ public function __construct($repository) $this->app = builder()->get_application(); } + /** + * @return string|array + */ public function setup() { + $env = $this->app->env; + if ($env->releases === false) { + $dir = $env->deploy_to; + $setup = "rm -rf $dir && {$this->setup_code($dir)}"; + } else { + $dir = $env->current_dir; + $setup = ""; + if ($env->remote_cache === true) $setup = $this->setup_code($env->cache_dir); + } + return array( + "umask {$env->umask}", + "mkdir -p {$env->deploy_to}", + "[ test -d \"$dir\" ] && ( " + . abort("setup", "application has already been setup.", false) + . " ) || ( $setup )" + ); } - public function update() + /** + * @return string|array + */ + public function deploy() { + $env = $this->app->env; + if ($env->releases === false) { + $dir = $env->deploy_to; + $deploy = "{$this->version()} > VERSION && {$this->update_code()}"; + } else { + $env->release_dir = $env->releases_dir.'/'.$env->new_release(); + if ($env->remote_cache === true) { + $dir = $env->cache_dir; + $deploy = "{$this->update_code()} && cp -R {$env->cache_dir} {$env->release_dir}"; + } else { + $dir = $env->release_dir; + $deploy = $this->setup_code(); + } + } + return array( + "cd \"$dir\"", + "( $deploy ) || ( " + . abort("deploy", "deploy folder not accessible. try running deploy:setup or deploy:cold first.", false) + . " )" + ); } + /** + * @return string|array + */ public function finalize() { + $env = $this->app->env; + //if ($env->backup === false) $cmd[] = "rm -rf {$env->shared_dir}/backup/{$env->merged}"; + if ($env->releases === false) return; + return array( + "cd \"{$env->releases_dir}\"", + "current=`ls -1t | head -n 1`", + "ln -nfs \"{$env->releases_dir}/\$current\" \"{$env->current_dir}\"" + ); + } + + /** + * @return string|array + */ + public function cleanup() + { + $env = $this->app->env; + if($env->releases === false) return; + if($env->keep_releases === false) return; + $keep = max(1, $env->keep_releases); + + info('deploy', "cleaning up old releases"); + + return array( + "cd \"{$env->releases_dir}\"", + "count=`ls -1t | wc -l`", + "old=$((count > {$keep} ? count - {$keep} : 0))", + "ls -1t | tail -n \$old | xargs rm -rf {}" + ); + } + + /** + * @return string|array + */ + public function rollback() + { + $env = $this->app->env; + if ($env->releases === false) { + $version = run(array( + "[ -e \"{$env->release_dir}/VERSION\" ]", + "(cat \"{$env->release_dir}/VERSION\") &>/dev/null" + ), true); + if (!count($version) || empty($version[0])) { + abort('rollback', "no releases to roll back to"); + } + + $env->revision = $version[0]; + return $this->update_code(); + } + + $rollback_to = isset($this->app['releases'])? $this->app['releases'] : 2; + $failed = ""; + + if ($env->release_dir !== $env->current_dir) { + // remove broken release + info('rollback', "removing failed release."); + $failed = info('rollback', "removing failed release.", false) . " && rm -rf \"{$env->release_dir}\""; + } + + //if($app->env->merged) + //{ + //info("rollback", "restoring database to before merge."); + //$backup = "{$app->env->shared_dir}/backup/{$app->env->merged}"; + //$cmd[] = $app->env->adapter->restore($backup); + //if($app->env->backup === false) $cmd[] = "rm -rf $backup"; + //} + + return array( + "count=`ls -1t \"{$env->releases_dir}\" | wc -l`", + "previous=`ls -1t \"{$env->releases_dir}\" | head -n {$rollback_to} | tail -1`", + "([ -e \"{$env->releases_dir}/\$previous\" ] && \$count >= {$rollback_to} )", + "( $failed ", + info('rollback', "pointing to previous release.", false), + "ln -nfs {$env->releases_dir}/\$previous {$env->current_dir} ) || (" + . abort('rollback', "", false) + . " )" + ); + } + + /** + * @param $location + * @return string + */ + public function setup_code($location) + { + return ""; + } + + /** + * @return string + */ + public function update_code() + { + return ""; + } + + /** + * @return string + */ + public function version() + { + return ""; } } diff --git a/lib/Pomander/Method/Git.php b/lib/Pomander/Method/Git.php index 6f7961c..4389fae 100644 --- a/lib/Pomander/Method/Git.php +++ b/lib/Pomander/Method/Git.php @@ -3,23 +3,84 @@ use Pomander\Method; +/** + * Class Git + * @package Pomander\Method + */ class Git extends Method { - public function setup() + /** + * @param $location + * @return string + */ + public function setup_code($location) { - if( $this->app->env->releases === false ) { - + return "git clone -q {$this->repository} {$location}"; + } + + /** + * @return string + */ + public function update_code() + { + $cmd = array(); + + // Fetch remote + $remote = isset($this->app->env->remote)? $this->app->env->remote : "origin"; + $cmd[] = "git fetch -q {$remote}"; + $cmd[] = "git fetch --tags -q {$remote}"; + + // Search revision + if (!empty($this->app->env->revision)) { + $commit = $this->app->env->revision; + } else { + if (!empty($this->app["branch"])) { + $commit = $this->get_commit_sha($this->app["branch"]); + } elseif (!empty($this->app->env->branch)) { + $commit = $this->get_commit_sha($this->app->env->branch); + } else { + $commit = 'HEAD'; + } } + // Reset HARD commit + $cmd[] = "git reset -q --hard {$commit}"; + + if ($this->app->env->submodule !== false) { + $cmd[] = 'git submodule update --init --recursive --quiet'; + } + + $cmd[] = 'git log --date=relative --format=format:"%C(bold blue)(%ar)%C(reset) %an \'%s\' %C(bold green)(%h)%C(reset)" | head -1'; + + return implode(' && ', $cmd); } - public function update() + /** + * @return string + */ + public function version() { - + return "git rev-parse HEAD"; } - public function finalize() + /** + * @param $ref + * @return string|void + */ + public function get_commit_sha($ref) { + // if specifying a remote ref, just grab the branch name + if (strpos($ref, "/") !== false) { + $ref = explode("/", $ref); + $ref = end($ref); + } + + list($status, $commit) = run_local("git ls-remote {$this->app->env->repository} {$ref}"); + if ($status > 0 || !$commit) abort("update", "failed to retrieve commit for {$ref}."); + + $commit = array_shift($commit); + $commit = substr($commit, 0, strpos($commit, "\t")); + return $commit; } } diff --git a/lib/tasks/deploy.php b/lib/tasks/deploy.php index 428a7ed..dccd46f 100644 --- a/lib/tasks/deploy.php +++ b/lib/tasks/deploy.php @@ -4,81 +4,26 @@ desc("Setup application in environment."); task('setup','app', function ($app) { - info("deploy","setting up environment"); - $cmd = array( - "umask {$app->env->umask}", - "mkdir -p {$app->env->deploy_to}" - ); - - if ($app->env->releases === false) { - $cmd[] = "rm -rf {$app->env->deploy_to}"; - $cmd[] = $app->env->scm->create($app->env->deploy_to); - } else { - $deployed = run("if test -d {$app->env->current_dir}; then echo \"exists\"; fi", true); - if(count($deployed)) abort("setup", "application has already been setup."); - $cmd[] = "mkdir -p {$app->env->releases_dir} {$app->env->shared_dir}"; - if($app->env->remote_cache === true) $cmd[] = $app->env->scm->create($app->env->cache_dir); - } - run($cmd); + info('deploy', "setting up environment"); + run($app->env->method->setup()); }); desc("Update code to latest changes."); task('update','app', function ($app) { - info("deploy","updating code"); - $cmd = array(); - if ($app->env->releases === false) { - $frozen = run("if test -d {$app->env->deploy_to}; then echo \"ok\"; fi", true); - if(empty($frozen)) abort("deploy", "deploy_to folder not found. you should run deploy:setup or deploy:cold first."); - $cmd[] = "cd {$app->env->deploy_to}"; - $cmd[] = "{$app->env->scm->revision()} > REVISION"; - $cmd[] = $app->env->scm->update(); - } else { - $app->env->release_dir = $app->env->releases_dir.'/'.$app->env->new_release(); - if ($app->env->remote_cache === true) { - $frozen = run("if test -d {$app->env->cache_dir}; then echo \"ok\"; fi", true); - if(empty($frozen)) abort("deploy", "remote_cache folder not found. you should run deploy:setup or deploy:cold first."); - $cmd[] = "cd {$app->env->cache_dir}"; - $cmd[] = $app->env->scm->update(); - $cmd[] = "cp -R {$app->env->cache_dir} {$app->env->release_dir}"; - } else { - $frozen = run("if test -d {$app->env->releases_dir}; then echo \"ok\"; fi", true); - if(empty($frozen)) abort("deploy", "releases folder not found. you should run deploy:setup or deploy:cold first."); - $cmd[] = $app->env->scm->create($app->env->release_dir); - $cmd[] = "cd {$app->env->release_dir}"; - $cmd[] = $app->env->scm->update(); - } - } - run($cmd); + info('deploy', "updating code"); + run($app->env->method->deploy()); $app->can_rollback = true; }); - task('finalize','deploy:cleanup', function ($app) { - //if($app->env->backup === false) $cmd[] = "rm -rf {$app->env->shared_dir}/backup/{$app->env->merged}"; - $deployed_to = basename($app->env->deploy_to); - if ($app->env->releases === true) { - $deployed_to = basename($app->env->release_dir); - run(array( - "cd {$app->env->releases_dir}", - "current=`ls -1t | head -n 1`", - "ln -nfs {$app->env->releases_dir}/\$current {$app->env->current_dir}" - )); - } + task('finalize', 'deploy:cleanup', function ($app) { + run($app->env->method->finalize()); $app->env->finalized = true; - info("complete", "deployed $deployed_to"); + $name = basename($app->env->release_dir); + info('complete', "deployed $name"); }); task('cleanup', function ($app) { - if($app->env->releases === false) return; - if($app->env->keep_releases === false) return; - $keep = max(1, $app->env->keep_releases); - - info('deploy', "cleaning up old releases"); - run(array( - "cd {$app->env->releases_dir}", - "count=`ls -1t | wc -l`", - "old=$((count > {$keep} ? count - {$keep} : 0))", - "ls -1t | tail -n \$old | xargs rm -rf {}" - )); + run($app->env->method->cleanup()); }); desc("First time deployment."); @@ -89,7 +34,7 @@ //rollback desc("Rollback to the previous release"); -task('rollback','app', function ($app) { +task('rollback', 'app', function ($app) { $cmd = array(); From 422bb8b27c81756dea849f293ac45f92531071db Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Mon, 3 Feb 2014 09:22:19 -0500 Subject: [PATCH 3/9] fixed tests --- lib/Pomander/Method.php | 13 ++++++------- tests/DeployTest.php | 15 ++++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/Pomander/Method.php b/lib/Pomander/Method.php index d83855b..ac41d42 100644 --- a/lib/Pomander/Method.php +++ b/lib/Pomander/Method.php @@ -22,15 +22,14 @@ public function setup() $setup = "rm -rf $dir && {$this->setup_code($dir)}"; } else { $dir = $env->current_dir; - $setup = ""; - if ($env->remote_cache === true) $setup = $this->setup_code($env->cache_dir); + $setup = "mkdir -p {$env->deploy_to} {$env->releases_dir} {$env->shared_dir}"; + if ($env->remote_cache === true) $setup .= ' && ' . $this->setup_code($env->cache_dir); } return array( "umask {$env->umask}", - "mkdir -p {$env->deploy_to}", - "[ test -d \"$dir\" ] && ( " - . abort("setup", "application has already been setup.", false) + "[ -e \"$dir\" ] && ( " + . abort("setup", "application has already been setup.", 1, false) . " ) || ( $setup )" ); } @@ -58,7 +57,7 @@ public function deploy() return array( "cd \"$dir\"", "( $deploy ) || ( " - . abort("deploy", "deploy folder not accessible. try running deploy:setup or deploy:cold first.", false) + . abort("deploy", "deploy folder not accessible. try running deploy:setup or deploy:cold first.", 1, false) . " )" ); } @@ -142,7 +141,7 @@ public function rollback() "( $failed ", info('rollback', "pointing to previous release.", false), "ln -nfs {$env->releases_dir}/\$previous {$env->current_dir} ) || (" - . abort('rollback', "", false) + . abort('rollback', "", 1, false) . " )" ); } diff --git a/tests/DeployTest.php b/tests/DeployTest.php index 6f14f38..a4a632e 100644 --- a/tests/DeployTest.php +++ b/tests/DeployTest.php @@ -8,10 +8,11 @@ public function testSetup() { ob_start(); // releases - $this->clean(); + shell_exec("rm -rf ".__DIR__."/test_release"); $app = $this->app(array("test", "deploy:setup")); $app->invoke("test"); + $app->invoke("deploy:setup"); $this->assertFileExists($app->env->releases_dir); @@ -20,7 +21,7 @@ public function testSetup() $this->assertFileExists($app->env->cache_dir."/.git"); // (no releases) - $this->clean(); + shell_exec("rm -rf ".__DIR__."/test_release"); $app = $this->app(array("norelease", "deploy:setup")); $app->invoke("norelease"); @@ -45,11 +46,11 @@ public function testUpdateCode() $app->env->setup(); // copy current sha and go back a bit. - $sha = shell_exec("cd {$app->env->cache_dir} && {$app->env->scm->revision()}"); + $sha = shell_exec("cd {$app->env->cache_dir} && {$app->env->method->version()}"); shell_exec("cd {$app->env->cache_dir} && git reset --hard HEAD~3"); $app->invoke("deploy:update"); - $new_sha = shell_exec("cd {$app->env->release_dir} && {$app->env->scm->revision()}"); + $new_sha = shell_exec("cd {$app->env->release_dir} && {$app->env->method->version()}"); ob_end_clean(); $this->assertFileExists($app->env->release_dir); @@ -74,8 +75,8 @@ public function testDeployBranch() $app->invoke("deploy:update"); sleep(1); $app->reset(); - $expected_sha = $app->env->scm->get_commit_sha($app->env->branch); - $current_sha = shell_exec("cd {$app->env->release_dir} && {$app->env->scm->revision()}"); + $expected_sha = $app->env->method->get_commit_sha($app->env->branch); + $current_sha = shell_exec("cd {$app->env->release_dir} && {$app->env->method->version()}"); ob_end_clean(); $this->assertFileExists($app->env->release_dir); @@ -86,7 +87,7 @@ public function testDeployBranch() $app->env->revision = "0.3.5"; $app->invoke("deploy:update"); - $sha = shell_exec("cd {$app->env->release_dir} && {$app->env->scm->revision()}"); + $sha = shell_exec("cd {$app->env->release_dir} && {$app->env->method->version()}"); ob_end_clean(); $this->assertSame(trim($sha), "46bbf9cfe5cfa3656f1246870ff98656e27761e7"); From 040e8c549ce072a296285441fb215ee2e0078dc6 Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Mon, 3 Feb 2014 09:48:41 -0500 Subject: [PATCH 4/9] removed Scm classes. Added Svn method and Rsync method. --- lib/Pomander/Method/Rsync.php | 57 +++++++++++++++++++++++ lib/Pomander/Method/Svn.php | 36 ++++++++++++++ lib/Pomander/Scm/Git.php | 88 ----------------------------------- lib/Pomander/Scm/Svn.php | 21 --------- lib/tasks/deploy.php | 43 +---------------- 5 files changed, 94 insertions(+), 151 deletions(-) delete mode 100644 lib/Pomander/Scm/Git.php delete mode 100644 lib/Pomander/Scm/Svn.php diff --git a/lib/Pomander/Method/Rsync.php b/lib/Pomander/Method/Rsync.php index e69de29..0c40f33 100644 --- a/lib/Pomander/Method/Rsync.php +++ b/lib/Pomander/Method/Rsync.php @@ -0,0 +1,57 @@ +app->env; + if ($env->releases === false) { + $dir = $env->deploy_to; + } else { + $env->release_dir = $env->releases_dir.'/'.$env->new_release(); + $dir = $env->release_dir; + } + + $env->put("./", $dir); + return ""; + } + + /** + * @return string|array + */ + public function rollback() + { + if ($this->app->env->releases === false) { + abort('rollback', "no releases to roll back to"); + } + + return parent::rollback(); + } + + /** + * @param $location + * @return string + */ + public function setup_code($location) + { + return "mkdir -p \"$location\""; + } + + /** + * @return string + */ + public function version() + { + return warn("version", "rsync method does not support code versions.", false); + } +} diff --git a/lib/Pomander/Method/Svn.php b/lib/Pomander/Method/Svn.php index e69de29..dd9b076 100644 --- a/lib/Pomander/Method/Svn.php +++ b/lib/Pomander/Method/Svn.php @@ -0,0 +1,36 @@ +repository} {$location} --quiet"; + } + + /** + * @return string + */ + public function update_code() + { + return "svn update"; + } + + /** + * @return string + */ + public function version() + { + return "svn info | grep 'Revision:' | cut -f2 -d\\"; + } +} diff --git a/lib/Pomander/Scm/Git.php b/lib/Pomander/Scm/Git.php deleted file mode 100644 index 53592f2..0000000 --- a/lib/Pomander/Scm/Git.php +++ /dev/null @@ -1,88 +0,0 @@ -repository} {$location}"; - } - - /** - * @return string - */ - public function update() - { - $cmd = array(); - - // Fetch remote - $remote = isset($this->app->env->remote)? $this->app->env->remote : "origin"; - $cmd[] = "git fetch -q {$remote}"; - $cmd[] = "git fetch --tags -q {$remote}"; - - // Search revision - if(!empty($this->app->env->revision)) { - $commit = $this->app->env->revision; - } else { - if(!empty($this->app["branch"])) { - $commit = $this->get_commit_sha($this->app["branch"]); - } elseif(!empty($this->app->env->branch)) { - $commit = $this->get_commit_sha($this->app->env->branch); - } else { - $commit = 'HEAD'; - } - } - - // Reset HARD commit - $cmd[] = "git reset -q --hard {$commit}"; - - if ($this->app->env->submodule !== false) { - $cmd[] = 'git submodule update --init --recursive --quiet'; - } - - $cmd[] = 'git log --date=relative --format=format:"%C(bold blue)(%ar)%C(reset) %an \'%s\' %C(bold green)(%h)%C(reset)" | head -1'; - - return implode(' && ', $cmd); - } - - /** - * @return string - */ - public function revision() - { - return "git rev-parse HEAD"; - } - - /** - * @param $ref - * @return string|void - */ - public function get_commit_sha($ref) - { - // if specifying a remote ref, just grab the branch name - if(strpos($ref, "/") !== false) { - $ref = explode("/", $ref); - $ref = end($ref); - } - - list($status, $commit) = run_local("git ls-remote {$this->app->env->repository} {$ref}"); - if($status > 0 || !$commit) abort("update", "failed to retrieve commit for {$ref}."); - - $commit = array_shift($commit); - $commit = substr($commit, 0, strpos($commit, "\t")); - - return $commit; - } - -} diff --git a/lib/Pomander/Scm/Svn.php b/lib/Pomander/Scm/Svn.php deleted file mode 100644 index 75c1aec..0000000 --- a/lib/Pomander/Scm/Svn.php +++ /dev/null @@ -1,21 +0,0 @@ -repository} {$location} --quiet"; - } - - public function update() - { - return "svn update"; - } - - public function revision() - { - return "svn info | grep 'Revision:' | cut -f2 -d\\"; - } - -} diff --git a/lib/tasks/deploy.php b/lib/tasks/deploy.php index dccd46f..30f1720 100644 --- a/lib/tasks/deploy.php +++ b/lib/tasks/deploy.php @@ -35,46 +35,5 @@ //rollback desc("Rollback to the previous release"); task('rollback', 'app', function ($app) { - - $cmd = array(); - - if ($app->env->releases) { - $releases = run("ls -1t {$app->env->releases_dir}", true); - if(count($releases) < 2) abort("rollback", "no releases to roll back to."); - - if ($app->env->release_dir == $app->env->current_dir) { - $count = isset($app['releases'])? $app['releases'] : 1; - if(count($releases) < $count + 1) abort("rollback", "can't rollback that far."); - if($count > 1) info("rollback", "rolling back to {$releases[$count]}."); - info("rollback", "pointing application to previous release."); - $cmd[] = "ln -nfs {$app->env->releases_dir}/{$releases[$count]} {$app->env->current_dir}"; - } else { - info("rollback", "removing failed release."); - $cmd[] = "rm -rf {$app->env->releases_dir}/{$releases[0]}"; - if ($app->env->finalized) { - info("rollback", "pointing application to last good release."); - $cmd[] = "ln -nfs {$app->env->releases_dir}/{$releases[1]} {$app->env->current_dir}"; - } - } - } else { - $frozen = run("if test -f {$app->env->release_dir}/REVISION; then echo \"ok\"; fi", true); - if(empty($frozen)) abort("rollback", "no releases to roll back to."); - - $revision = run("cat {$app->env->release_dir}/REVISION", true); - if(!count($revision)) abort("rollback", "no releases to roll back to."); - - $app->env->revision = $revision[0]; - $cmd[] = $app->scm->update(); - } - - //if($app->env->merged) - //{ - //info("rollback", "restoring database to before merge."); - //$backup = "{$app->env->shared_dir}/backup/{$app->env->merged}"; - //$cmd[] = $app->env->adapter->restore($backup); - //if($app->env->backup === false) $cmd[] = "rm -rf $backup"; - //} - - run($cmd); - + run($app->env->method->rollback()); }); From 437d909f70365e3f3d19a3c02a7887cfc6d0fea9 Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Mon, 3 Feb 2014 11:41:27 -0500 Subject: [PATCH 5/9] fixed rollback --- lib/Pomander.php | 47 +++++++++++++++++++++++------------------ lib/Pomander/Method.php | 33 ++++++++++++++++------------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/lib/Pomander.php b/lib/Pomander.php index d726b8c..a2d281c 100644 --- a/lib/Pomander.php +++ b/lib/Pomander.php @@ -57,19 +57,19 @@ function desc($description) { builder()->desc($description); } function info($status, $msg, $output = true) { $line = " * " . ansicolor("info ", 32) . ansicolor("$status ", 35) . $msg; - return $output? puts($line) : $line; + return $output? puts($line) : "echo \"$line\""; } function warn($status, $msg, $output = true) { $line = " * " . ansicolor("warn ", 33) . ansicolor("$status ", 35) . $msg; - return $output? puts($line) : $line; + return $output? puts($line) : "echo \"$line\""; } function abort($status, $msg, $code=1, $output = true) { $line = " * " . ansicolor("abort ", 31) . ansicolor("$status ", 35) . $msg; - if( !$output ) return $line . " && false"; + if( !$output ) return "echo \"$line\" && false"; puts($line); die($code); @@ -108,17 +108,7 @@ function run() list($status, $output) = !isset($app->env)? run_local($cmd) : $app->env->exec($cmd); if (!$silent && count($output)) puts(implode("\n", $output)); - if ($status > 0) { - if ($app->can_rollback) { - warn("fail", "Rolling back..."); - $app->invoke('rollback'); - info("rollback", "rollback complete."); - exit($status); - - return; - } - abort("fail","aborted!",$status); - } + check_rollback($status); return $output; } @@ -134,14 +124,31 @@ function run_local($cmd) // Deprecated: use run_local() function exec_cmd($cmd) { return run_local($cmd); } -function put($what,$where) +function put($what, $where) { - if (!isset(builder()->get_application()->env)) return run_local("cp -R $what $where"); - builder()->get_application()->env->put($what,$where); + $app = builder()->get_application(); + list($status, $output) = isset($app->env)? $app->env->put($what, $where) : run_local("cp -R $what $where"); + check_rollback($status); } -function get($what,$where) +function get($what, $where) { - if (!isset(builder()->get_application()->env)) return run_local("cp -R $what $where"); - builder()->get_application()->env->get($what,$where); + $app = builder()->get_application(); + list($status, $output) = isset($app->env)? $app->env->get($what, $where) : run_local("cp -R $what $where"); + check_rollback($status); +} + +function check_rollback($status) { + if ($status < 1) return; + $app = builder()->get_application(); + + if ($app->can_rollback) { + warn("fail", "Rolling back..."); + $app->invoke('rollback'); + info("rollback", "rollback complete."); + exit($status); + + return; + } + abort("fail", "aborted!", $status); } diff --git a/lib/Pomander/Method.php b/lib/Pomander/Method.php index ac41d42..cf667c5 100644 --- a/lib/Pomander/Method.php +++ b/lib/Pomander/Method.php @@ -118,30 +118,33 @@ public function rollback() } $rollback_to = isset($this->app['releases'])? $this->app['releases'] : 2; - $failed = ""; + $rollback = array(); if ($env->release_dir !== $env->current_dir) { // remove broken release info('rollback', "removing failed release."); - $failed = info('rollback', "removing failed release.", false) . " && rm -rf \"{$env->release_dir}\""; + $rollback[] = info('rollback', "removing failed release.", false); + $rollback[] = "rm -rf \"{$env->release_dir}\""; } - //if($app->env->merged) - //{ - //info("rollback", "restoring database to before merge."); - //$backup = "{$app->env->shared_dir}/backup/{$app->env->merged}"; - //$cmd[] = $app->env->adapter->restore($backup); - //if($app->env->backup === false) $cmd[] = "rm -rf $backup"; - //} + $rollback[] = info('rollback', "pointing to previous release.", false); + $rollback[] = "ln -nfs \"{$env->releases_dir}/\$previous\" \"{$env->current_dir}\""; + $rollback = implode(' && ', $rollback); + + /*if($app->env->merged) + { + info("rollback", "restoring database to before merge."); + $backup = "{$app->env->shared_dir}/backup/{$app->env->merged}"; + $cmd[] = $app->env->adapter->restore($backup); + if($app->env->backup === false) $cmd[] = "rm -rf $backup"; + }*/ return array( "count=`ls -1t \"{$env->releases_dir}\" | wc -l`", - "previous=`ls -1t \"{$env->releases_dir}\" | head -n {$rollback_to} | tail -1`", - "([ -e \"{$env->releases_dir}/\$previous\" ] && \$count >= {$rollback_to} )", - "( $failed ", - info('rollback', "pointing to previous release.", false), - "ln -nfs {$env->releases_dir}/\$previous {$env->current_dir} ) || (" - . abort('rollback', "", 1, false) + "release=`ls -1t \"{$env->releases_dir}\" | head -n {$rollback_to} | tail -1`", + "([ -e \"{$env->releases_dir}/\$release\" ] && (( \$count >= {$rollback_to} )) )", + "( $rollback ) || ( " + . abort('rollback', "no releases to roll back to", 1, false) . " )" ); } From ddeeabd5b040232f0c31a036e292004472452a8d Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Mon, 3 Feb 2014 14:44:22 -0500 Subject: [PATCH 6/9] finished wrapping all paths in quotes --- lib/Pomander/Method.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Pomander/Method.php b/lib/Pomander/Method.php index cf667c5..2eb1dd3 100644 --- a/lib/Pomander/Method.php +++ b/lib/Pomander/Method.php @@ -19,10 +19,10 @@ public function setup() $env = $this->app->env; if ($env->releases === false) { $dir = $env->deploy_to; - $setup = "rm -rf $dir && {$this->setup_code($dir)}"; + $setup = "rm -rf \"$dir\" && {$this->setup_code($dir)}"; } else { $dir = $env->current_dir; - $setup = "mkdir -p {$env->deploy_to} {$env->releases_dir} {$env->shared_dir}"; + $setup = "mkdir -p \"{$env->deploy_to}\" \"{$env->releases_dir}\" \"{$env->shared_dir}\""; if ($env->remote_cache === true) $setup .= ' && ' . $this->setup_code($env->cache_dir); } @@ -47,7 +47,7 @@ public function deploy() $env->release_dir = $env->releases_dir.'/'.$env->new_release(); if ($env->remote_cache === true) { $dir = $env->cache_dir; - $deploy = "{$this->update_code()} && cp -R {$env->cache_dir} {$env->release_dir}"; + $deploy = "{$this->update_code()} && cp -R \"{$env->cache_dir}\" \"{$env->release_dir}\""; } else { $dir = $env->release_dir; $deploy = $this->setup_code(); From a4dde3b15d5528c78f1f3c0d448cbddb4629284c Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Mon, 3 Feb 2014 14:56:17 -0500 Subject: [PATCH 7/9] fixing rollback shell script issues (Again) --- lib/Pomander/Method.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pomander/Method.php b/lib/Pomander/Method.php index 2eb1dd3..12ce7f3 100644 --- a/lib/Pomander/Method.php +++ b/lib/Pomander/Method.php @@ -142,7 +142,7 @@ public function rollback() return array( "count=`ls -1t \"{$env->releases_dir}\" | wc -l`", "release=`ls -1t \"{$env->releases_dir}\" | head -n {$rollback_to} | tail -1`", - "([ -e \"{$env->releases_dir}/\$release\" ] && (( \$count >= {$rollback_to} )) )", + "([ -e \"{$env->releases_dir}/\$release\" ] && [ \$count -ge {$rollback_to} ] )", "( $rollback ) || ( " . abort('rollback', "no releases to roll back to", 1, false) . " )" From 882ecff5196ee44cd518aa315deeb87e1312afd9 Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Wed, 6 Aug 2014 09:07:48 -0400 Subject: [PATCH 8/9] removing SCM class --- lib/Pomander/Scm.php | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 lib/Pomander/Scm.php diff --git a/lib/Pomander/Scm.php b/lib/Pomander/Scm.php deleted file mode 100644 index 4822ed8..0000000 --- a/lib/Pomander/Scm.php +++ /dev/null @@ -1,28 +0,0 @@ -repository = $repository; - $this->app = builder()->get_application(); - } - - public function create($location) - { - return ""; - } - - public function update() - { - return ""; - } - - public function revision() - { - return ""; - } -} From 0b4be07376e098441dcc4f98c7a2406bc82a3074 Mon Sep 17 00:00:00 2001 From: Mike Kruk Date: Wed, 6 Aug 2014 09:08:04 -0400 Subject: [PATCH 9/9] ignore gh-pages build folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index eccff23..fa35ad0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor deploy tests/test_release .idea +_site