Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ccf8266

Browse files
author
Unknown
committed
Implemented plugin system
- added plugin autoloader - plugin interface (which plugins must implement from) - implemented class method checks - new defined configuration key - plugin error handling (non-breaking because a webhook not firing should not fatal throw and be silently logged) - added more success callback keys - added the discord plugin as a default example - fixed an issue with the recent change to `endScript()` where it would display the same message after `errorPage()`
1 parent 9e66f72 commit ccf8266

File tree

4 files changed

+167
-18
lines changed

4 files changed

+167
-18
lines changed

‎deploy-config.orig.php‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,14 @@
116116
*/
117117
define('CLEANUP_WORK_TREE', false);
118118

119-
/* CALLBACK_FILE:
120-
* Filename of a PHP script containing callback functions to
119+
/* CALLBACK_CLASSES:
120+
* Classnames containing callback functions to
121121
* be triggered at the end of the script on success or failure.
122122
* Useful to connect to your preferred notification system.
123+
* Note:
124+
* - Classes must implement Plugin Interface
125+
* - Class names have to match their file-name (case-sensitive), e.g. "Discord.class.php" has class "Discord"
126+
* - The array keys contain only the class name, e.g. array("Discord")
123127
*/
124-
define('CALLBACK_FILE', '');
128+
define('CALLBACK_CLASSES', array(
129+
));

‎deploy.php‎

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88
// Measure execution time
99
$time = -microtime(true);
1010

11+
// Autoloader for plugin classes
12+
spl_autoload_register(function($className){
13+
$namespace=str_replace("\\","/",__NAMESPACE__);
14+
$className=str_replace("\\","/",$className);
15+
$class="plugins/".(empty($namespace)?"":$namespace."/")."{$className}.class.php";
16+
include_once($class);
17+
});
18+
1119
/* Functions */
1220

1321
// Output buffering handler
@@ -29,36 +37,59 @@ function errorPage($msg) {
2937
}
3038

3139
// Command to execute at the end of the script
32-
function endScript($msg = "") {
40+
function endScript($msg = "",$display = false) {
3341
// Remove lock file
3442
unlink(__DIR__ . '/deploy.lock');
43+
3544
// Flush buffer and prepare output for log and email
3645
ob_end_flush();
3746
global $output;
47+
3848
// Remove <head>, <script>, and <style> tags, including content
3949
$output = preg_replace('/<head[\s\w\W\n]+<\/head>/m', '', $output);
4050
$output = preg_replace('/<script[\s\w\W\n]+<\/script>/m', '', $output);
4151
$output = preg_replace('/<style[\s\w\W\n]+<\/style>/m', '', $output);
52+
4253
// Add heading and strip tags
4354
$output = str_repeat("~", 80) . "\n"
4455
. '[' . date('c') . '] - ' . $_SERVER['REMOTE_ADDR'] . " - b=" . $_GET['b'] . ' c=' . $_GET['c'] . "\n"
4556
. strip_tags($output);
57+
4658
// Decode HTML entities
4759
$output = html_entity_decode($output);
60+
4861
// Collapse multiple blank lines into one
4962
$output = preg_replace('/^\n+/m', "\n", $output);
63+
5064
// Save to log file
5165
if(defined('LOG_FILE') && LOG_FILE !== '') error_log($output, 3, LOG_FILE);
66+
5267
// Send email notification
5368
if(defined('EMAIL_NOTIFICATIONS') && EMAIL_NOTIFICATIONS !== '') error_log($output, 1, EMAIL_NOTIFICATIONS);
69+
5470
// Send error callback
55-
if($msg && defined('CALLBACK_FILE') && file_exists(CALLBACK_FILE)){
56-
require_once CALLBACK_FILE;
57-
if(function_exists(callbackError)) {
58-
callbackError($msg);
71+
if(!empty($msg) && defined('CALLBACK_CLASSES') && !empty(CALLBACK_CLASSES)){
72+
foreach (CALLBACK_CLASSES as $class) {
73+
if(is_callable(array($class,"errorWebhook"))){
74+
$callback = $class::errorWebhook($msg);
75+
// prevent outputting after errorPage()
76+
if($display === true){
77+
if($callback === true){
78+
echo "\n[Plugin: ".$class."] webhook successfully sent\n";
79+
}else{
80+
echo "ERR! Plugin '".$class."' returned: ".$callback;
81+
}
82+
}
83+
}
5984
}
6085
}
61-
die($msg);
86+
87+
// prevent outputting same error message from errorPage()
88+
if($display === true){
89+
die($msg);
90+
}else{
91+
die();
92+
}
6293
}
6394

6495
/* Begin Script Execution */
@@ -484,14 +515,23 @@ function cmd($command, $print = true, $dir = GIT_DIR) {
484515
));
485516

486517
// Send success callback
487-
if(defined('CALLBACK_FILE') && file_exists(CALLBACK_FILE)){
488-
require_once CALLBACK_FILE;
489-
if(function_exists(callbackSuccess)) {
490-
callbackSuccess(array(
491-
'branch' => $branch,
492-
'commit' => $checkout,
493-
'execTime' => $time + microtime(true)
494-
));
518+
if(defined('CALLBACK_CLASSES') && !empty(CALLBACK_CLASSES)){
519+
foreach (CALLBACK_CLASSES as $class) {
520+
if(is_callable(array($class,"successWebhook"))){
521+
$callback = $class::successWebhook(array(
522+
'remote' => REMOTE_REPOSITORY,
523+
'branch' => $branch,
524+
'targetDirectory' => TARGET_DIR,
525+
'commit' => $checkout,
526+
'execTime' => $time + microtime(true)
527+
));
528+
529+
if($callback === true){
530+
echo "\n[Plugin: ".$class."] webhook successfully sent\n";
531+
}else{
532+
echo "ERR! Plugin '".$class."' returned: ".$callback;
533+
}
534+
}
495535
}
496536
}
497537
?>
@@ -501,4 +541,4 @@ function cmd($command, $print = true, $dir = GIT_DIR) {
501541
</body>
502542
</html>
503543
<?php
504-
endScript();
544+
endScript("",true);

‎plugins/Discord.class.php‎

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
/* DISCORD WEBHOOK CONFIGS:
4+
* (OPTIONAL/DEFAULT TO FALSE) DISCORD_WEBHOOK: enables discord webhook notifications
5+
* (REQUIRED) DISCORD_WEBHOOK_URL: the URL generated by Discord to receive webhooks
6+
* (OPTIONAL) DISCORD_USER_NAME: the name that should be shown as the user sending the message
7+
* (OPTIONAL) DISCORD_AVATAR_URL: the image to be used as the avatar for the user sending the message
8+
*/
9+
10+
define("DISCORD_WEBHOOK",false);
11+
define("DISCORD_WEBHOOK_URL","");
12+
define("DISCORD_USER_NAME","");
13+
define("DISCORD_AVATAR_URL","");
14+
15+
class Discord implements Plugin {
16+
public static function successWebhook($params){
17+
$deployedMessage = "**Execution:** ".$params["execTime"]." seconds \n";
18+
$deployedMessage .= "**Deployed:** \n(".$params["branch"].") ".$params["remote"]."\n";
19+
$deployedMessage .= "**To:** ".$params["targetDirectory"]."\n";
20+
21+
return self::discordMessage($deployedMessage);
22+
}
23+
24+
public static function errorWebhook($errorMessage){
25+
return self::discordMessage($errorMessage,true);
26+
}
27+
28+
private static function discordMessage($message,$error = false) {
29+
// check configuration errors and correct them
30+
if(!defined("DISCORD_WEBHOOK")) define("DISCORD_WEBHOOK",false);
31+
32+
// prevent execution if discord webhook not enabled
33+
if(DISCORD_WEBHOOK === false) return "Discord webhook is not enabled";
34+
35+
// only check other discord configuration values, if discord webhook is enabled
36+
if(!defined("DISCORD_WEBHOOK_URL") || empty(DISCORD_WEBHOOK_URL)){
37+
return 'Discord webook url not configured';
38+
}
39+
40+
// abort if no message set
41+
if(empty($message)) return "No message provided";
42+
43+
if($error === false){
44+
$data = array(
45+
'username' => DISCORD_USER_NAME,
46+
'avatar_url' => DISCORD_AVATAR_URL,
47+
'embeds' => [[
48+
"title" => "Deploy successful!",
49+
"description" => strip_tags($message),
50+
"color" => "3932074"
51+
]]
52+
);
53+
}else{
54+
$data = array(
55+
'username' => DISCORD_USER_NAME,
56+
'avatar_url' => DISCORD_AVATAR_URL,
57+
'embeds' => [[
58+
"title" => "Deploy failed..",
59+
"description" => strip_tags($message),
60+
"color" => "16727357"
61+
]]
62+
);
63+
}
64+
65+
$data_string = json_encode($data);
66+
$curl = curl_init();
67+
curl_setopt($curl, CURLOPT_URL, DISCORD_WEBHOOK_URL);
68+
curl_setopt($curl, CURLOPT_POST, 1);
69+
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
70+
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
71+
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
72+
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
73+
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
74+
75+
$output = curl_exec($curl);
76+
$output = json_decode($output, true);
77+
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) != 204) {
78+
return $output["message"];
79+
}
80+
81+
curl_close($curl);
82+
return true;
83+
}
84+
}

‎plugins/Plugin.class.php‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
interface Plugin
4+
{
5+
/**
6+
* successWebhook
7+
*
8+
* @param [array] $params information passed down to the plugin
9+
* @return bool|string Returns true if no errors occured, else returns error message
10+
*/
11+
public static function successWebhook($params);
12+
13+
/**
14+
* errorWebhook
15+
*
16+
* @param [string] $errorMessage the error message(s) passed down to the plugin
17+
* @return bool|string Returns true if no errors occured, else returns error message
18+
*/
19+
public static function errorWebhook($errorMessage);
20+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /