Last active
November 3, 2017 13:52
-
-
Save Stichoza/c4f0fddc09daef41abe7 to your computer and use it in GitHub Desktop.
Laravel 4.2 Push-to-Deploy controller for GitHub webhooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Deployment controller | |
* | |
* @author Stichoza <me@stichoza.com> | |
*/ | |
class DeployController extends BaseController | |
{ | |
const DEPLOY_SECRET_KEY = 'YOUR-GITHUB-WEBHOOK-SECRET-KEY-HERE'; | |
private $deployStatus = false; | |
public static $sshLog = []; | |
private $errorMsg = 'Message not set'; | |
private $payload = []; | |
private static $commands = [ | |
'uptime', | |
'whoami', | |
'cd /var/www/stichoza.com', | |
'php artisan down', | |
'git reset --hard HEAD', | |
'git pull github master', | |
'php artisan migrate', | |
'php artisan up' | |
]; | |
public static function log($str) { | |
self::$sshLog[] = [ | |
'time' => microtime(1), | |
'output' => $str | |
]; | |
} | |
/** | |
* This should be in laravel framework | |
*/ | |
public static function getRequestBody() { | |
return @file_get_contents('php://input'); | |
// File::get('php://input'); // This does not work! | |
} | |
/** | |
* | |
*/ | |
private function checkHMAC() { | |
$sign = substr(Request::header('X-Hub-Signature', 'sha1=null'), 5); | |
$hmac = hash_hmac('sha1', self::getRequestBody(), self::DEPLOY_SECRET_KEY); | |
return $sign == $hmac; | |
} | |
private function fail($errorMsg) { | |
return $this->makeResponse(false, $errorMsg); | |
} | |
private function makeResponse($status = null, $errorMsg = null) { | |
if ($status !== null) $this->deployStatus = !!$status; | |
if (!empty($errorMsg)) $this->errorMsg = $errorMsg; | |
$response = ['deployed' => $this->deployStatus]; | |
if (!empty($this->errorMsg)) { | |
$response['message'] = $this->errorMsg; | |
} | |
if (count(self::$sshLog)) { | |
$response['log'] = self::$sshLog; | |
} | |
return $response; | |
} | |
/** | |
* Deploy from github | |
* | |
* @access public | |
* @return array | |
*/ | |
public function deploy() { | |
// Require HTTPS | |
if (!Request::secure()) return $this->fail('HTTPS required'); | |
try { | |
$this->payload = json_decode(self::getRequestBody()); | |
} catch (Exception $e) { | |
return $this->fail('Payload decoding failed.'); | |
} | |
// Check HMAC signature | |
if (!$this->checkHMAC()) return $this->fail('Invalid secret key'); | |
// Abort if pushed on nonmaster | |
if ($this->payload->ref != 'refs/heads/master') | |
return $this->fail('Not on master branch'); | |
self::log('Deployment started'); | |
// Execute commands and log output | |
SSH::into('capsule')->run(self::$commands, function($line) { | |
self::log(trim($line)); | |
}); | |
return $this->makeResponse(true, 'Deployment finnished'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment