Last active
January 7, 2023 11:54
-
-
Save webjay/3915531 to your computer and use it in GitHub Desktop.
Php hook script that can git pull, apc_clear_cache() etc
This file contains hidden or 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 | |
ignore_user_abort(true); | |
function syscall ($cmd, $cwd) { | |
$descriptorspec = array( | |
1 => array('pipe', 'w'), // stdout is a pipe that the child will write to | |
2 => array('pipe', 'w') // stderr | |
); | |
$resource = proc_open($cmd, $descriptorspec, $pipes, $cwd); | |
if (is_resource($resource)) { | |
$output = stream_get_contents($pipes[2]); | |
$output .= PHP_EOL; | |
$output .= stream_get_contents($pipes[1]); | |
$output .= PHP_EOL; | |
fclose($pipes[1]); | |
fclose($pipes[2]); | |
proc_close($resource); | |
return $output; | |
} | |
} | |
function git_current_branch ($cwd) { | |
$result = syscall('git branch', $cwd); | |
if (preg_match('/\\* (.*)/', $result, $matches)) { | |
return $matches[1]; | |
} | |
} | |
// make sure the request is coming from GitHub | |
// https://help.github.com/articles/what-ip-addresses-does-github-use-that-i-should-whitelist | |
/* | |
$gh_ips = array('207.97.227.253', '50.57.128.197', '108.171.174.178'); | |
if (in_array($_SERVER['REMOTE_ADDR'], $gh_ips) === false) { | |
header('Status: 403 Your IP is not on our list; bugger off', true, 403); | |
mail('root', 'GitHub hook error: bad ip', $_SERVER['REMOTE_ADDR']); | |
exit(); | |
} | |
*/ | |
// cd .. | |
// $cwd = dirname(__DIR__); | |
// GitHub will hit us with POST (http://help.github.com/post-receive-hooks/) | |
if (!empty($_POST['payload'])) { | |
$payload = json_decode($_POST['payload']); | |
// which branch was committed? | |
$branch = substr($payload->ref, strrpos($payload->ref, '/') + 1); | |
// If your website directories have the same name as your repository this would work. | |
$repository = $payload->repository->name; | |
$cwd = '/var/www/'.$repository; | |
// only pull if we are on the same branch | |
if ($branch == git_current_branch($cwd)) { | |
// pull from $branch | |
$cmd = sprintf('git pull origin %s', $branch); | |
$result = syscall($cmd, $cwd); | |
$output = ''; | |
// append commits | |
foreach ($payload->commits as $commit) { | |
$output .= $commit->author->name.' a.k.a. '.$commit->author->username; | |
$output .= PHP_EOL; | |
foreach (array('added', 'modified', 'removed') as $action) { | |
if (count($commit->{$action})) { | |
$output .= sprintf('%s: %s; ', $action, implode(',', $commit->{$action})); | |
} | |
} | |
$output .= PHP_EOL; | |
$output .= sprintf('because: %s', $commit->message); | |
$output .= PHP_EOL; | |
$output .= $commit->url; | |
$output .= PHP_EOL; | |
} | |
// append git result | |
$output .= PHP_EOL; | |
$output .= $result; | |
// send us the output | |
mail('root', 'GitHub hook `'.$cmd.'` result', $output); | |
// if you use APC, especially if you use apc.stat=0, we should clear APC | |
// if (apc_clear_cache('opcode') == false || apc_clear_cache('user') == false) { | |
// mail('root', 'Unable to apc_clear_cache', ''); | |
// } | |
} | |
} | |
?> |
Figured it out. I had several things going on.
- Copied .ssh folder to /var/www so apache could connect to github
- git repo-config core.sharedRepository true
- chown/chmod g+rw .git folder specifically (-R . or -R * doesn't hit the .git folder)
I also modified the function above to have better error output if there is a fatal error in the command executed.
private function _syscall ($cmd, $cwd)
{
$descriptorspec = array(
1 => array('pipe', 'w'), // stdout is a pipe that the child will write to
2 => array('pipe', 'w') //stderr will pipe back
);
$resource = proc_open($cmd, $descriptorspec, $pipes, $cwd);
if (is_resource($resource)) {
stream_set_blocking($pipes[2], 0);
if ($err = stream_get_contents($pipes[2]))
{
return 'Process could not be started [' . $err . ']';
}
$output = stream_get_contents($pipes[1]);
if ($err = stream_get_contents($pipes[2]))
{
return $err;
}
fclose($pipes[1]);
proc_close($resource);
return $output;
} else {
return "No resource provided.";
}
}
@joefresco Or you can just use [suPHP|http://www.suphp.org/Home.html] to make your php script that does git pull
execute under your user instead of apache. No more crazy chmod/chown :)
Thanks for your feedback @joefresco.
I have just recently done this again, and updated my guide.
Hey guys, I've made a stripped down version https://gist.github.com/phedoreanu/11321236.
It's worth noting that in your guide there's a more straightforward way to update your known_hosts
file that more closely follows github documentation:
sudo -u www-data ssh -T [email protected]
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
All I ever get from this is a blank $result and no results from the git pull. I've even modified your code to help me try to diagnose the problem. I followed your guide but used my own name (smart) in place of www-data as that's who already owns the repo.