Over the past month or so, I spent a bit of time working on setting up a local development environment for a project that I’m working on. As part of that, I also set up a deployment flow using a simple Github webhook handler in PHP.
I modeled this Github webhook handler very much after jplitza’s Gist here, but I simplified it even further since all I really cared about was whether an event happened since I’d already filtered on Github for push events.
This is the handler that I ended up with.
<?php
define( 'LOGFILE', '/DIR' );
define( 'SECRET', '0000000000' );
define( 'PULL_CMD', 'CMD_HERE' );
$post_data = file_get_contents( 'php://input' );
$signature = hash_hmac( 'sha1', $post_data, SECRET );
function log_msg( $message ) {
file_put_contents( LOGFILE, $message . "\n", FILE_APPEND );
}
if ( empty( $_SERVER['HTTP_X_HUB_SIGNATURE'] ) ) {
exit;
}
if ( ! hash_equals( 'sha1=' . $signature, $_SERVER['HTTP_X_HUB_SIGNATURE'] ) ) {
exit;
}
// At this point, we've verified the signature from Github, so we can do things.
$date = date(' m/d/Y h:i:s a', time() );
log_msg( "Deploying at {$date}" );
$output_lines = array();
exec( PULL_CMD, $output_lines );
if ( ! empty( $output_lines ) ) {
log_msg( implode( "\n", $output_lines ) );
}
exit;
Basically, all this file is doing is:
- Verifying that the request actually comes from Github by creating a signature using our
SECRET
and then comparing that to the signature that Github sent us with the time constanthash_equals
- Running whatever command is necessary. For me, this command is basically just
cd dir && git pull origin main
. - Writing logs so that we can keep track of how often the Github webhook handler is called and whether it’s successful or not.
To get this to work, you’ll roughly do the following:
- Create a log file and add the location to the
LOGFILE
constant. - Create a strong secret in the
SECRET
constant that can be shared on Github so that we can validate the webhook came from Github. - Update the
PULL_CMD
constant with the command that you’d like to run. - Upload this file to your server in a publicly accessible location and make note of what the URL will be.
- Go to Settings > Webhooks for one of the Github repos that you manage and create a new webhook.
- Ensure that you set the URL to the file that we uploaded earlier and ensure that you enter the value from the
SECRET
constant.
That seems like several steps, but in just a few minutes, you could have your own Github webhook handler in PHP up and running!
Leave a Reply