Last active
September 13, 2021 01:04
-
-
Save cblte/5263dad3642a39a80e8f9c3f4bc44706 to your computer and use it in GitHub Desktop.
PHP Script to execute shellscript (hookfile.sh) via Github Webhook in a secure way. Environment works for uberspace.de. Static site gen is hugo (gohugo.io)
This file contains 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
#!/bin/bash | |
# -------------------- | |
# place this file anywhere where it can be execute fromthe webhook.php file. | |
# make sure, you put the correct path to this file into the webhook.php | |
# webdirectory is a directory accessible via internet, but not the main websites directory | |
# .. ideally webdirectory is a access via subdomain | |
# -------------------- | |
# set PATH | |
PATH=$HOME/bin:/usr/bin:$PATH | |
export PATH | |
# change into directory of hugo website | |
cd $HOME/hugo_websites/zn80-net | |
echo "Fetching latest commits in dir: " $(pwd) | |
git pull | |
# git reset --hard origin/main | |
# executing hugo command | |
$HOME/bin/hugo --minify --gc --cleanDestinationDir | |
if [ $code -eq 0 ]; then | |
echo "Hugo build successfull with return code" $? | |
rsync -az --delete public/ /var/www/virtual/cblte/html/ | |
fi | |
# echo "Build succesfull. Syncing files" | |
cd - | |
This file contains 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 | |
/** | |
* Automated deploy from GitHub | |
* | |
* https://developer.github.com/webhooks/ | |
* Template from ServerPilot (https://serverpilot.io/community/articles/how-to-automatically-deploy-a-git-repo-from-bitbucket.html) | |
* Hash validation from Craig Blanchette (http://isometriks.com/verify-github-webhooks-with-php) | |
*/ | |
// --------------------------------------------------------- | |
// Variables | |
$secret = getenv('GH_DEPLOY_SECRET'); | |
// ^^ for this, you need to add a secret string into | |
// your .htaccess file along this webhook script | |
// example: SetEnv GH_DEPLOY_SECRET 22ee4659d87ac19378f356df6f467151a82e6d18e0e9e9583dc42d76b2e55bbd | |
// you the string should be random. Use CyberChef or your password manager | |
$hookfile = '/home/<user>/bin/hookfile.sh'; | |
// this is the path to the script you want to execute. | |
$logfile = '/var/www/virtual/<user>/<webdirectory>/deploy.log'; | |
// this is the logfile. ideally a secret file you can access via web | |
// webdirectory is a directory accessible via internet, but not the main websites directory | |
// ideally webdirectory is a access via subdomain | |
// --------------------------------------------------------- | |
function log_append($message, $time = null) | |
{ | |
global $logfile; | |
$time = $time === null ? time() : $time; | |
$date = date('Y-m-d H:i:s'); | |
$pre = $date . ' (' . $_SERVER['REMOTE_ADDR'] . '): '; | |
file_put_contents($logfile, $pre . $message . "\n", FILE_APPEND); | |
} | |
function exec_command($command) | |
{ | |
$output = array(); | |
exec($command, $output); | |
log_append('EXEC: ' . $command); | |
foreach ($output as $line) { | |
log_append('SHELL: ' . $line); | |
} | |
} | |
// Validate hook secret | |
if ($secret !== NULL) { | |
// Get signature | |
$hub_signature = $_SERVER['HTTP_X_HUB_SIGNATURE']; | |
// Make sure signature is provided | |
if (!isset($hub_signature)) { | |
log_append('ERROR: HTTP header "X-Hub-Signature" is missing.'); | |
die('HTTP header "X-Hub-Signature" is missing.'); | |
} elseif (!extension_loaded('hash')) { | |
log_append('ERROR: Missing "hash" extension to check the secret code validity.'); | |
die('Missing "hash" extension to check the secret code validity.'); | |
} | |
// Split signature into algorithm and hash | |
list($algo, $hash) = explode('=', $hub_signature, 2); | |
// Get payload | |
$payload = file_get_contents('php://input'); | |
// Calculate hash based on payload and the secret | |
$payload_hash = hash_hmac($algo, $payload, $secret); | |
// Check if hashes are equivalent | |
if (!hash_equals($hash, $payload_hash)) { | |
// Kill the script or do something else here. | |
log_append('ERROR: Bad Secret'); | |
die('Bad secret'); | |
} | |
}; | |
// Parse data from GitHub hook payload | |
$input = json_decode($_POST['payload']); | |
$commit_message = ""; | |
if (empty($data->commits)) { | |
// When merging and pushing to GitHub, the commits array will be empty. | |
// In this case there is no way to know what branch was pushed to, so we will do an update. | |
$commit_message .= 'true'; | |
} else { | |
foreach ($data->commits as $commit) { | |
$commit_message .= $commit->message; | |
} | |
} | |
if (!empty($commit_message)) { | |
log_append('INFO: Launching shell hook script...'); | |
exec_command('sh '.$hookfile); | |
log_append('INFO: Shell hook script finished'); | |
} else { | |
log_append('WARNING: Not commit message found. Command not executed.'); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment