Git WebHook PHP Post Receive Pull Method

I hope this finds someone well. I spent a few hours trying to iron out the process of deploying to git from my laptop and then automatically initiating a pull request on my server using Github’s Web Hooks.

There is an article called “The Perfect Workflow” on NetTuts that describes the method to create a connection between your GitHub repo and the directory stored on your server using Github Web Hooks and PHP. For example, if you update source files on your local machine, and then push the changes to Github it will automatically run a “git pull” on your server.

Here is the steps I took.

Step 1 – Create git-puller.sh file in your existing Github repo.

cd /srv/www/www.domain.com/public_html && /usr/lib/git-core/git pull && cd -

Things to note:

  • You must use full paths to your working directory.
  • The must use the full path to git. It can be found using “git –exec-path”.

Step 2 – Create a git-hook.php file in your existing Github repo.

<?php #!/usr/bin/env /usr/bin/php
error_reporting(E_ALL);
ini_set('display_errors', '1');
set_time_limit(0);

try {

  $payload = json_decode($_REQUEST['payload']);

}
catch(Exception $e) {

	//log the error
	file_put_contents('/srv/www/www.domain.com/logs/github.txt', $e . ' ' . $payload, FILE_APPEND);

	  exit(0);
}

if ($payload->ref === 'refs/heads/master') {

	$project_directory = '/srv/www/www.domain.com/public_html/';

	$output = shell_exec("/srv/www/www.domain.com/public_html/git-puller.sh");

	//log the request
	file_put_contents('/srv/www/www.domain.com/logs/github.txt', $output, FILE_APPEND);

}
?>

Things to note:

  • The path to PHP is set at the top of the file may be different on your system. or php -i can help you find it.
  • As you see I’m logging all output to log/github.txt this file must be writable by the web user. (CHMOD 777)

Step 3 – Push your Repo and set Webhook

  • The next step is to commit your files to your github repo.
  • Then visit Github and setup your Webook to point to the URL of your PHP file.

Github Webhook

  • Next SSH into your web server and visit the directory where you want your files be cloned.
  • If it is a blank directory (works best) run:
    git clone https://github.com/username/myrepo.git ./
  • Make sure your files are all owned by the web user of Apache or Nginx (mine is www-data)
    chown www-data:www-data *

Step 4 – Setup sudo file and test

  • In order to allow the “git-puller.sh” script to run as superuser you need to add it to your sudoers file. Type “visudo” at the bash shell (logged in as root).
  • Add
    www-data ALL=NOPASSWD: /srv/www/www.domain.com/public_html/git-puller.sh
  • Then su www-data and CHMOD git-puller.sh 777 to make it executable
  • Finally try making commits and pushing to Github locally. Wait a few seconds and see it the changes are reflected on your server.

Final notes

This process may take some tinkering. Problems can usually be attributed to incorrect permissions. Everything must run as the Apache or Nginx user. Make sure the “git-puller.sh” script is executable. You can always test the script in bash by

sudo -u www-data ./git-puller.ph

It also helps to log the data to “github.txt” to see if you are getting results back. Make sure that is also writable. This process won’t work with PHP SafeMode on.

Hope this helps someone. If you find any errors or have a better suggestion let me know.

  • skube

    I’m confused by your very first step. Can you explain that line further?

    • tegan

      Sure just create a file called git-puller.sh and put the path to your application:

      cd /full_server_path/to/my/application/on/my/server_or_webhost && /usr/lib/git-core/git pull && cd -
      
  • Private

    this should be working with private git repository? since locally any git pull requires user/pass for git access. Same request will be raised by /git pull in bash file.

  • Xavier

    hi ;; pls i need help ,, i make a php script to get the payload and write it into a txt file but nothing work ,, i name my php script getjson.php

    i add the http://www.domaine.com/getjson.php to webhook but it do t work.
    help me if u can plz

  • Xavier

    this is my script

    error_reporting(E_ALL);

    ini_set(‘display_errors’, ‘1’);

    set_time_limit(0);

    try {

    $payload = json_decode($_REQUEST['payload']);

    file_put_contents(‘/var/www/filetest.txt’, ‘ca marche’);

    }

    catch(Exception $e) {

    //log the error

    file_put_contents(‘/var/www/filetest.txt’, $e . ‘ ‘ . $payload, FILE_APPEND);

    exit(0);

    }

  • tegansnyder

    For those of your finding this now. I recommend checking out: https://github.com/markomarkovic/simple-php-git-deploy