Simple Github Webhook handler in PHP

Code for Github webhook handler in PHP

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 constant hash_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

This site uses Akismet to reduce spam. Learn how your comment data is processed.