Skip to content

Instantly share code, notes, and snippets.

@adrenalinkin
Created August 1, 2017 12:28
Show Gist options
  • Save adrenalinkin/52ed405a1cb1470d5b339c385c3ec4d8 to your computer and use it in GitHub Desktop.
Save adrenalinkin/52ed405a1cb1470d5b339c385c3ec4d8 to your computer and use it in GitHub Desktop.
Symfony2 deployment by Github webhook which provides logging in file and integration with slack.
<?php
// main deployment commands registration
$commands = [
'git pull',
'git status',
'rm -rf app/cache/*',
'export SYMFONY_ENV=prod; export HOME=~; php composer.phar install',
'php app/console doctrine:migration:migrate -n',
];
if (!isset($_POST['payload'])) {
exit('Request should contain "payload" offset in the POST');
}
$payload = json_decode($_POST['payload'], true);
$supportBranch = 'refs/heads/master';
if (!isset($payload['ref']) || $payload['ref'] != $supportBranch) {
exit(sprintf('Supports only changes in the "%s"', $supportBranch));
}
// register log file
$output = [];
$logDir = '../app/logs/deployment';
$logName = sprintf('%s.log', date('Y-m-d'));
if (!is_dir($logDir)) {
$commands = array_merge(['mkdir app/logs/deployment'], $commands);
} else {
$logStr = sprintf('START (%s)', date('H:i:s')) . PHP_EOL;
$logStr .= str_repeat('=', 50) . PHP_EOL . PHP_EOL;
file_put_contents($logDir . '/' . $logName, $logStr, FILE_APPEND);
}
// main commands call
foreach ($commands as $command) {
$result = shell_exec('cd .. ;' . $command . ' 2>&1');
$header = sprintf('%s (%s)', $command, date('H:i:s'));
$logStr = $header . PHP_EOL;
$logStr .= str_repeat('-', 50) . PHP_EOL;
$logStr .= $result . PHP_EOL;
file_put_contents($logDir . '/' . $logName, $logStr, FILE_APPEND);
$result = preg_replace('/[[:cntrl:]]+/', PHP_EOL, $result);
$output[$header] = nl2br($result);
}
// slack WEB Hook
$link = sprintf('%s://%s', isset($_SERVER['HTTPS']) ? 'https' : 'http', $_SERVER['HTTP_HOST']);
$channel = '#general';
$mainMessage = sprintf('Hey! Deployment has been done. Visit <%s> for checking', $link);
$attachments = [];
if (isset($payload['head_commit'])) {
$attachments[] = [
'color' => '#9304FF',
'author_name' => 'Send by: ' . $payload['sender']['login'],
'author_link' => $payload['sender']['html_url'],
'author_icon' => $payload['sender']['avatar_url'],
'title' => 'Compare changes',
'title_link' => $payload['compare'],
'mrkdwn_in' => ['text'],
'footer' => sprintf('Has been pushed %s commits', count($payload['commits'])),
'text' => sprintf(
'<%s|Head commit> message: ```%s```',
$payload['head_commit']['url'],
$payload['head_commit']['message']
),
'fields' => [
[
'title' => 'Head commit author:',
'short' => true,
'value' => sprintf(
'%s (%s)',
$payload['head_commit']['author']['username'],
$payload['head_commit']['author']['name']
),
],
[
'title' => 'Head commit committer:',
'short' => true,
'value' => sprintf(
'%s (%s)',
$payload['head_commit']['committer']['username'],
$payload['head_commit']['committer']['name']
),
],
[
'title' => 'Pusher:',
'short' => true,
'value' => $payload['pusher']['name'],
],
],
];
}
$data = 'payload=' . json_encode([
'channel' => $channel,
'text' => $mainMessage,
'icon_emoji' => ':rocket:',
'attachments' => $attachments,
]);
$ch = curl_init('https://hooks.slack.com/services/.../.../...');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$header = sprintf('slack (%s)', date('H:i:s'));
$output[$header] = $result;
$logStr = $header . PHP_EOL;
$logStr .= str_repeat('-', 50) . PHP_EOL;
$logStr .= $result . PHP_EOL;
file_put_contents($logDir . '/' . $logName, $logStr, FILE_APPEND);
// delimiter for the next deployment call
file_put_contents($logDir . '/' . $logName, str_repeat(PHP_EOL, 3), FILE_APPEND);
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="robots" content="noindex,nofollow" />
<title>Deployment result</title>
<style>
html {
background: #eee;
}
body {
font: 11px Verdana, Arial, sans-serif;
color: #333;
font-size: 14px;
font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
}
#content {
width: 970px;
margin: 0 auto;
}
.sf-reset h1 {
font-family: Georgia, "Times New Roman", Times, serif;
font-size: 20px;
color: #313131;
word-wrap: break-word;
}
.sf-reset p {
font-size: 14px;
line-height: 20px;
padding-bottom: 20px;
}
.sf-reset .block {
-moz-border-radius: 16px;
-webkit-border-radius: 16px;
border-radius: 16px;
margin-bottom: 20px;
background-color: #FFFFFF;
border: 1px solid #dfdfdf;
padding: 40px 50px;
word-break: break-all;
}
.sf-reset h1.title {
font-size: 45px;
padding-bottom: 30px;
}
.sf-reset ul li {
list-style-type: none;
}
</style>
</head>
<body>
<div id="content">
<div class="sf-reset">
<div class="block">
<div class="symfony-block-content">
<h1 class="title">Deployment result</h1>
<ul>
<?php foreach ($output as $commandName => $result) :?>
<li>
<b style="color: #6BE234;">$</b>
<b style="color: #729FCF;"><?php echo $commandName ?></b>
<p style="border-bottom: solid darkgrey 1px;padding-left: 40px">
<?php echo $result ?>
</p>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment