Skip to content

Commit

Permalink
Merge pull request #41 from tamagokun/better_deploy_update
Browse files Browse the repository at this point in the history
[Review] Improving deploy:update closes #39
  • Loading branch information
tamagokun committed Jan 19, 2014
2 parents 9ca70cb + 59342a3 commit 2ee7baa
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
vendor
deploy
tests/test_release
.idea
2 changes: 1 addition & 1 deletion lib/Pomander/Cli.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace Pomander;

use phake\Application;
use \phake\Application;

class Cli
{
Expand Down
15 changes: 8 additions & 7 deletions lib/Pomander/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public function set($options)
public function setup()
{
if($this->name == "development") $this->releases = false;
if($this->branch) $this->revision = $this->branch;
if ($this->releases === false) {
$this->current_dir = $this->deploy_to;
$this->releases_dir = $this->deploy_to;
Expand All @@ -58,9 +57,9 @@ public function __call($name, $arguments)

public function __get($prop)
{
if(array_key_exists($prop, $this->config)) return $this->config[$prop];

return null;
if(!array_key_exists($prop, $this->config)) return null;
$value = $this->config[$prop];
return is_callable($value)? $value() : $value;
}

public function __isset($prop) { return isset($this->config[$prop]); }
Expand Down Expand Up @@ -151,7 +150,8 @@ private function defaults()
"url"=>"",
"user"=>"",
"repository"=>"",
"revision"=>"origin/master",
"revision"=>"",
"branch"=>"master",
"remote_cache"=>true,
"releases"=>false,
"keep_releases"=>false,
Expand All @@ -170,7 +170,8 @@ private function defaults()
"rsync_cmd"=>"rsync",
"rsync_flags"=>"-avuzPO --quiet",
"db_backup_flags"=>"--lock-tables=FALSE --skip-add-drop-table | sed -e 's|INSERT INTO|REPLACE INTO|' -e 's|CREATE TABLE|CREATE TABLE IF NOT EXISTS|'",
"db_swap_url"=>true
"db_swap_url"=>true,
"composer"=>false
);

return $defaults;
Expand Down Expand Up @@ -199,7 +200,7 @@ private function init_scm_adapter()

private function inject_multi_role_after($role,$task_name)
{
info("injecting after $task_name");
info("injecting after $task_name", '');
after($task_name,function ($app) use ($task_name,$role) {
if ( $app->env->next_role($role) ) {
$app->reset();
Expand Down
80 changes: 68 additions & 12 deletions lib/Pomander/Scm/Git.php
Original file line number Diff line number Diff line change
@@ -1,34 +1,90 @@
<?php

namespace Pomander\Scm;

class Git extends \Pomander\Scm
use Pomander\Scm;

/**
* Class Git
* @package Pomander\Scm
*/
class Git extends Scm
{
/**
* @param $location
* @return string
*/
public function create($location)
{
return "git clone {$this->repository} {$location}";
return "git clone -q {$this->repository} {$location}";
}

/**
* @return string
*/
public function update()
{
if (!empty($this->app->env->branch)) {
$cmd = "git reset --hard --quiet && git checkout {$this->app->env->branch} --quiet && git pull --quiet";
} elseif (!empty($this->app->env->revision)) {
$cmd = "git reset --hard {$this->app->env->revision} --quiet";
} else {
$cmd = 'git reset --hard HEAD --quiet && git pull --quiet';
$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 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';
$cmd[] = 'git clean -q -d -x -f';
$cmd[] = 'git log --date=relative --format=format:"%C(bold blue)(%ar)%C(reset) %an \'%s\' %C(bold green)(%h)%C(reset)" | head -1';

return $cmd;
return implode(' && ', $cmd);
}

/**
* @return string
*/
public function revision()
{
return "echo -e `git log --pretty=format:'%H' -n 1`";
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;
}

}
2 changes: 2 additions & 0 deletions lib/tasks/composer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
desc("Install dependencies with Composer");
task('install', function ($app) {
if($app->env->composer === false) return;
info("composer", "install");
run(array(
"cd {$app->env->release_dir}",
"([ -e 'composer.json' ] && which composer &>/dev/null)",
Expand All @@ -14,6 +15,7 @@

task('update', function ($app) {
if($app->env->composer === false) return;
info("composer", "update");
run(array(
"cd {$app->env->release_dir}",
"([ -e 'composer.json' ] && which composer &>/dev/null)",
Expand Down
21 changes: 13 additions & 8 deletions lib/tasks/deploy.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
$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)) return abort("setup", "application has already been setup.");
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);
}
Expand All @@ -27,20 +27,22 @@
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)) return abort("deploy", "remote_cache folder not found. you should run deploy:setup or deploy:cold first.");
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)) return abort("deploy", "releases folder not found. you should run deploy:setup or deploy:cold first.");
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();
Expand Down Expand Up @@ -80,10 +82,10 @@
});

desc("First time deployment.");
task('cold','deploy:setup','deploy:update','composer:update','deploy:finalize');
task('cold','deploy:setup','deploy:update','composer:install','deploy:finalize');

});
task('deploy','deploy:update','composer:update','deploy:finalize');
task('deploy','deploy:update','composer:install','deploy:finalize');

//rollback
desc("Rollback to the previous release");
Expand All @@ -93,11 +95,11 @@

if ($app->env->releases) {
$releases = run("ls -1t {$app->env->releases_dir}", true);
if(count($releases) < 2) return abort("rollback", "no releases to roll back to.");
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) return abort("rollback", "can't rollback that far.");
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}";
Expand All @@ -110,8 +112,11 @@
}
}
} 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)) return abort("rollback", "no releases to roll back to.");
if(!count($revision)) abort("rollback", "no releases to roll back to.");

$app->env->revision = $revision[0];
$cmd[] = $app->scm->update();
Expand Down
29 changes: 15 additions & 14 deletions tests/DeployTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public function testSetup()
$app->invoke("norelease");
$app->invoke("deploy:setup");

$this->assertFileExists($app->env->deploy_to."/.git");
ob_end_clean();
$this->assertFileExists($app->env->deploy_to."/.git");
}

public function testUpdateCode()
Expand All @@ -51,9 +51,9 @@ public function testUpdateCode()
$app->invoke("deploy:update");
$new_sha = shell_exec("cd {$app->env->release_dir} && {$app->env->scm->revision()}");

ob_end_clean();
$this->assertFileExists($app->env->release_dir);
$this->assertTrue($sha == $new_sha);
ob_end_clean();
}

public function testDeployBranch()
Expand All @@ -72,20 +72,24 @@ public function testDeployBranch()

$app->env->branch = "gh-pages";
$app->invoke("deploy:update");
sleep(1);
$app->reset();
$current_branch = shell_exec("cd {$app->env->release_dir} && git rev-parse --abbrev-ref HEAD");
$expected_sha = $app->env->scm->get_commit_sha($app->env->branch);
$current_sha = shell_exec("cd {$app->env->release_dir} && {$app->env->scm->revision()}");

ob_end_clean();
$this->assertFileExists($app->env->release_dir);
$this->assertSame($app->env->branch, trim($current_branch));
$this->assertSame($expected_sha, trim($current_sha));

ob_start();
$app->env->branch = "";
$app->env->revision = "0.3.5";
$app->invoke("deploy:update");

$sha = shell_exec("cd {$app->env->release_dir} && git log --pretty=format:'%H' -n 1");
$this->assertSame($sha, "46bbf9cfe5cfa3656f1246870ff98656e27761e7");
$sha = shell_exec("cd {$app->env->release_dir} && {$app->env->scm->revision()}");

ob_end_clean();
$this->assertSame(trim($sha), "46bbf9cfe5cfa3656f1246870ff98656e27761e7");
}

public function testFinalize()
Expand All @@ -105,10 +109,10 @@ public function testFinalize()
$app->invoke("deploy:update");
$app->invoke("deploy:finalize");

ob_end_clean();
$this->assertFileExists($app->env->current_dir);
$this->assertTrue(is_link($app->env->current_dir));
$this->assertTrue(readlink($app->env->current_dir) == $app->env->release_dir);
ob_end_clean();
}

public function testCleanUp()
Expand All @@ -134,9 +138,9 @@ public function testCleanUp()
$app->invoke("deploy:update");
$app->invoke("deploy:cleanup");

ob_end_clean();
$this->assertFileExists($app->env->release_dir);
$this->assertCount(2, glob($app->env->releases_dir."/*"));
ob_end_clean();
}

public function testCold()
Expand All @@ -154,6 +158,7 @@ public function testCold()

$app->invoke("deploy:cold");

ob_end_clean();
$this->assertFileExists($app->env->release_dir);
$this->assertFileExists($app->env->releases_dir);
$this->assertFileExists($app->env->shared_dir);
Expand All @@ -163,8 +168,6 @@ public function testCold()
$this->assertFileExists($app->env->current_dir);
$this->assertTrue(is_link($app->env->current_dir));
$this->assertTrue(readlink($app->env->current_dir) == $app->env->release_dir);

ob_end_clean();
}

public function testDefault()
Expand All @@ -183,11 +186,10 @@ public function testDefault()

$app->invoke("deploy");

ob_end_clean();
$this->assertFileExists($app->env->current_dir);
$this->assertTrue(is_link($app->env->current_dir));
$this->assertTrue(readlink($app->env->current_dir) == $app->env->release_dir);

ob_end_clean();
}

public function testRollback()
Expand Down Expand Up @@ -216,12 +218,11 @@ public function testRollback()

$release = readlink($app->env->current_dir);

ob_end_clean();
$this->assertFileExists($app->env->current_dir);
$this->assertTrue(is_link($app->env->current_dir));
$this->assertFileExists($release);
$this->assertFalse(readlink($app->env->current_dir) == $app->env->release_dir);

ob_end_clean();
}

// private
Expand Down

0 comments on commit 2ee7baa

Please sign in to comment.