Skip to content

Instantly share code, notes, and snippets.

@wturnerharris
Created September 1, 2015 22:52
Show Gist options
  • Save wturnerharris/b17038c064ed19325f0a to your computer and use it in GitHub Desktop.
Save wturnerharris/b17038c064ed19325f0a to your computer and use it in GitHub Desktop.
This script will perform some tasks on a staging environment to simulate a full-on auto-deployment routine in gitlab
<?php
/**
* Auto Deployment Script for GitLab. Uses apache + php to perform tasks.
*
*
* @since deploy 0.2
*/
/**
* @internal The following variables are assumed to be valid but minimal validation is performed.
* Assumes a git webhook to deploy.php?auth=DEFINE_MD5_AUTH
*
*/
$auth = md5('DEFINE_MD5_AUTH'); // set a private hash to validate against
$event_type = "Merge Request Hook"; // identified by http request header
$event_kind = "merge_request"; // identified by object_kind key on payload root
$request_type = @$_SERVER['HTTP_X_GITLAB_EVENT']; // available from http request header
$raw_post = file_get_contents('php://input'); // json payload
$target_branch = "staging";
$merge_status = "can_be_merged"; // [ "unchecked" | "can_be_merged" ]
$action = "merge"; // after accepted... [ "merge" | "update" ]
$data = !empty($raw_post) ? @json_decode($raw_post) : false;
$errors = array();
$date = date('Y-m-d H:i:s');
// minimal check for authorized access
if ( empty($_GET['auth']) || $_GET['auth'] !== $auth ) {
$errors['authorization'] = "Unauthorized access";
}
// check for existence of json decoded object
if ( !$data || empty($data->object_kind) ) {
$errors['payload'] = "Payload missing or invalid";
}
// checks for correct event type
if ( (trim($event_type) !== trim($request_type)) || ($event_kind !== $data->object_kind)) {
$errors['event_type'] = "Specified event type is invalid";
}
// check for target branch
if ( $target_branch !== $data->object_attributes->target_branch ) {
$errors['target_branch'] = "Specified target branch does not match";
}
// check if mergeable
if ( $merge_status !== $data->object_attributes->merge_status ) {
$errors['status'] = "Not checked or cannot merge cleanly";
}
// check merge request action
if ( $action !== $data->object_attributes->action ) {
$errors['approved'] = "Merge request has not yet been approved";
}
// complete failure checks
if ( !$data || count($errors) > 0 ) {
$errors['failure'] = sprintf("Deployment failed. See deployment.log (%s)", $date);
$errors['data'] = !$data ? 'No data' : $data;
}
// log data and errors
$_data = empty($errors) ? sprintf("Last deployed: %s", $date) : print_r($errors, true);
shell_exec("cat > ./deployment.log <<DELIM\n$_data\nDELIM");
if (count($errors) > 0) {
echo "Nope";
exit;
}
$args = array(
'target' => './wp-content/themes/wcapital',
'git' => '/usr/local/bin/git',
'mailto' => false,
'commands' => array(
'echo $PWD',
"git fetch origin"
"git branch",
"git reset --hard HEAD",
"git stash save --keep-index",
"git stash drop",
"git pull origin staging",
"git status",
"git rev-parse HEAD | cut -c1-7",
)
);
function deploy($args) {
chdir( $args['target'] );
$git = trim(exec('which git'));
if (empty($git)) $git = $args['git'];
$whoami = trim(shell_exec('whoami'));
$output = array(
"<b>$whoami\$ php deploy.php</b>",
"<span>Git Deployment Script, version 0.1 (apache)",
"Creative Commons Attribution-NoDerivs 3.0 Unported",
"Copyright (C) 2013 Wes Turner, Barrel LLC, All Rights Reserved</span>"
);
foreach($args['commands'] as $command){
$command = str_replace('git', $git, $command);
$tmp = shell_exec($command);
if (empty($tmp)) $tmp = "No output.";
$output[] = "<b>$whoami\$ {$command}\n</b>".htmlentities(trim($tmp));
usleep(2000000);
}
$return = implode("\n", $output);
// debug emailing
if ( $args['mailto'] ) {
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: '.$args['mailto'] . "\r\n" .
$headers .= 'Reply-To: '.$args['mailto'] . "\r\n" .
$headers .= 'X-Mailer: PHP/' . phpversion();
mail( $args['mailto'], 'Latest commit deployed', $output, $headers );
}
return $return;
}
ob_start();
?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>deploy.php</title>
<style>
body {
background-color: black;
line-height: 1.1em;
margin: 0;
}
pre {
background-color: black;
color: white;
margin: 0;
padding: 5%;
white-space: pre-line;
}
span {
color: #829AAE;
}
b {
color: #6BE234;
font-weight: normal;
}
</style>
</head>
<body>
<pre>
<?php echo deploy($args); ?>
</pre>
</body>
</html>
<?php
$output = ob_get_clean();
// put this output in main directory or above web access
shell_exec("cat >> ../../../deployment.html <<DELIM\n$output\nDELIM");
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment