-
-
Save cowboy/619858 to your computer and use it in GitHub Desktop.
<?php | |
// Use in the "Post-Receive URLs" section of your GitHub repo. | |
if ( $_POST['payload'] ) { | |
shell_exec( 'cd /srv/www/git-repo/ && git reset --hard HEAD && git pull' ); | |
} | |
?>hi |
Note that your repo SHOULD NOT include files that are changed on server. Maybe /uploads
folder or app/logs
or anything. git reset --hard HEAD
will delete everything. Put such files and folders in your .gitignore
.
Just an fyi: I had to change the following before it would work:
if ( $_POST['payload'] ) {
to
if ($_SERVER['HTTP_X_GITHUB_EVENT'] == 'push') {
also, as usually shell_exec is run from the user www-data I had to change permissions by executing the following command inside /var/www/html
sudo chown www-data:www-data -R my-repo/
Thanks @lmann that worked for me:
if ($_SERVER['HTTP_X_GITHUB_EVENT'] == 'push') {
Just figured out the difference. If you use the json content-type, then $_POST['payload'] will not work. You have to use the application/x-www-form-urlencoded for $_POST['payload'] to work.
i need to use that on final of string and work nice:
2>&1
so:
shell_exec( 'cd '.$path.' && git reset --hard HEAD && git pull 2>&1' );
@izeta application/x-www-form-urlencoded got $_POST['payload']
working, cheers!
You can also shell_exec("./pull.sh")
, remembering to chmod u+x pull.sh
.
I'm on SiteGround hosting, so need to worry about www-data .
etc/suoders
:
www-data ALL = (myuser) NOPASSWD: /usr/bin/git
www-data ALL = (myuser) NOPASSWD: /usr/bin/node
www-data ALL = (myuser) NOPASSWD: /usr/bin/drush
www-data ALL = (myuser) NOPASSWD: /usr/bin/whoami
github_post_recieve.php
:
<?php
if ( isset($_POST['payload']) && $_POST['payload'] ) {
echo shell_exec('cd /var/www/mydrupal/ && sudo -u myuser git pull');
echo shell_exec('cd /var/www/mydrupal/sites/all/themes/mytheme/ && sudo -u myuser node ./node_modules/gulp/bin/gulp.js mygulptask');
// Adding the drush will cause the delivery being displayed as unsuccessful. Means GitHub doesn't wait so long. The command will run nevertheless.
echo shell_exec('cd /var/www/mydrupal/ && sudo -u myuser drush @sites cc all -y');
}
// Should return www-data
echo shell_exec('whoami');
// Should return myuser
echo shell_exec('sudo -u myuser whoami');
?>
Thx for the simple gist!
I solved my issue with my shell_exec(...
command not running by changing the directory it was in ownership to www-data
(from root
), ie: sudo chown -R www-data /var/www/
<?php
// GitHub Webhook Secret.
// Keep it the same with the 'Secret' field on your Webhooks / Manage webhook page of your respostory.
$secret = "";
// Path to your respostory on your server.
// e.g. "/var/www/respostory"
$path = "";
// Headers deliveried from GitHub
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE'];
if ($signature) {
$hash = "sha1=".hash_hmac('sha1', file_get_contents("php://input"), $secret);
if (strcmp($signature, $hash) == 0) {
echo shell_exec("cd {$path} && /usr/bin/git reset --hard origin/master && /usr/bin/git clean -f && /usr/bin/git pull 2>&1");
exit();
}
}
http_response_code(404);
?>
@Luc45 thank you for the suggestion, it worked and was quite helpful !! 🙌
In addition, on my remote server, I have added a little line to the /etc/sudoers
file to allow the webserver user (usually www-data
) to execute /usr/bin/git
as the user that owns my repo files 😉
Here is my example: www-data ALL = (repo_owner) NOPASSWD : /usr/bin/git
Always be cautious when running shell commands from web scripts backpack battles for security reasons. Sanitize inputs, restrict access, and log activities to avoid potential vulnerabilities.
@webjay It works, you just need to generate the web server's ssh keys. I've merged your security code with this gist and the ssh keys: https://gist.github.com/phedoreanu/11321236.