Created
December 30, 2016 15:32
-
-
Save pitchart/6d9c6a5e0f8b0969fa4cfd29e4d22f10 to your computer and use it in GitHub Desktop.
A simple php script to manage gitlab push webhook
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 | |
/** | |
* GitLab Web Hook | |
* See https://gitlab.com/kpobococ/gitlab-webhook | |
* | |
* This script should be placed within the web root of your desired deploy | |
* location. The GitLab repository should then be configured to call it for the | |
* "Push events" trigger via the Web Hooks settings page. | |
* | |
* Each time this script is called, it executes a hook shell script and logs all | |
* output to the log file. | |
* | |
* This hook uses php's exec() function, so make sure it can be executed. | |
* See http://php.net/manual/function.exec.php for more info | |
*/ | |
// CONFIGURATION | |
// ============= | |
/* Hook script location. The hook script is a simple shell script that executes | |
* the actual git push. Make sure the script is either outside the web root or | |
* inaccessible from the web | |
* | |
* This setting is REQUIRED | |
*/ | |
$hookfile = '/path/to/the/script/to/execute.sh'; | |
/* Log file location. Log file has both this script's and shell script's output. | |
* Make sure PHP can write to the location of the log file, otherwise no log | |
* will be created! | |
* | |
* This setting is REQUIRED | |
*/ | |
$logfile = '/path/to/the/log/file.log'; | |
/* Hook password. If set, this password should be passed as a GET parameter to | |
* this script on every call, otherwise the hook won't be executed. | |
* | |
* This setting is RECOMMENDED | |
*/ | |
$password = 'put_a_great_password_here'; | |
/* Ref name. This limits the hook to only execute the shell script if a push | |
* event was generated for a certain ref (most commonly - a master branch). | |
* | |
* Can also be an array of refs: | |
* | |
* $ref = array('refs/heads/master', 'refs/heads/develop'); | |
* | |
* This setting does not support the actual refspec, so the refs should match | |
* exactly. | |
* | |
* See http://git-scm.com/book/en/Git-Internals-The-Refspec for more info on | |
* the subject of Refspec | |
* | |
* This setting is OPTIONAL | |
*/ | |
$ref = 'refs/heads/master'; | |
// THE ACTUAL SCRIPT | |
// ----------------- | |
// You shouldn't edit beyond this point, | |
// unless you know what you're doing | |
// ===================================== | |
function log_append($message, $time = null) | |
{ | |
global $logfile; | |
$time = $time === null ? time() : $time; | |
$date = date('Y-m-d H:i:s'); | |
$pre = $date . ' (' . $_SERVER['REMOTE_ADDR'] . '): '; | |
file_put_contents($logfile, $pre . $message . "\n", FILE_APPEND); | |
} | |
function exec_command($command) | |
{ | |
$output = array(); | |
exec($command, $output); | |
log_append('EXEC: ' . $command); | |
foreach ($output as $line) { | |
log_append('SHELL: ' . $line); | |
} | |
} | |
if (isset($password)) | |
{ | |
if (empty($_REQUEST['p'])) { | |
log_append('Missing hook password'); | |
die(); | |
} | |
if ($_REQUEST['p'] !== $password) { | |
log_append('Invalid hook password'); | |
die(); | |
} | |
} | |
// GitLab sends the json as raw post data | |
$input = file_get_contents("php://input"); | |
$json = json_decode($input); | |
if (!is_object($json) || empty($json->ref)) { | |
log_append('Invalid push event data'); | |
die(); | |
} | |
if (isset($ref)) | |
{ | |
$_refs = (array) $ref; | |
if ($ref !== '*' && !in_array($json->ref, $_refs)) { | |
log_append('Ignoring ref ' . $json->ref); | |
die(); | |
} | |
} | |
log_append('Launching shell hook script...'); | |
exec_command('sh '.$hookfile); | |
log_append('Shell hook script finished'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the tricky part:
You must use the above method to get the data posted by GibLab. You cannot use
$_POST
in this case. Not knowing this took me several hours to debug +_+