-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub-sync.php
More file actions
executable file
·143 lines (122 loc) · 4.21 KB
/
github-sync.php
File metadata and controls
executable file
·143 lines (122 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
/*
Plugin Name: GitHub Sync
Plugin URI: http://www.lesintegristes.net/
Description: Synchronize a local git branch with a remote, using the GitHub Post-Receive Hooks.
Author: Pierre Bertet
Version: 1.0.0
Author URI: http://pierrebertet.net/
*/
// Notice messages
add_action('admin_notices', function(){
$messages = array();
if (!function_exists('exec')) {
$messages[] = 'the PHP <code>exec()</code> function needs to be activated.';
}
if (!defined('GITHUB_SYNC_DIR')) {
$messages[] = 'you have to define the <code>GITHUB_SYNC_DIR</code> setting.';
}
if (!defined('GITHUB_SYNC_REPO_ID')) {
$messages[] = 'you have to define the <code>GITHUB_SYNC_REPO_ID</code> setting.';
}
foreach ($messages as $message) {
echo '<div class="error"><p>The GitHub Sync plugin is not working: '.$message.'</p></div>';
}
}, 0);
// Authorized IPs (default: GitHub IPs)
if (!defined('GITHUB_SYNC_IPS')) {
define('GITHUB_SYNC_IPS', '207.97.227.253, 50.57.128.197, 108.171.174.178');
}
// Git branch (default: master)
if (!defined('GITHUB_SYNC_BRANCH')) {
define('GITHUB_SYNC_BRANCH', 'master');
}
// Git remote (default: origin)
if (!defined('GITHUB_SYNC_REMOTE')) {
define('GITHUB_SYNC_REMOTE', 'origin');
}
// Log file (default: NULL)
if (!defined('GITHUB_SYNC_LOG')) {
define('GITHUB_SYNC_LOG', NULL);
}
// Repo directory (no default, required)
if (!defined('GITHUB_SYNC_DIR')) {
return;
}
// Repo GitHub ID, owner/project (eg. bpierre/wp-github-sync)
if (!defined('GITHUB_SYNC_REPO_ID')) {
return;
}
function log_msg($msg) {
if (GITHUB_SYNC_LOG !== NULL) {
file_put_contents(GITHUB_SYNC_LOG, $msg . "\n", FILE_APPEND);
}
}
function check_request() {
// HTTP method
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
log_msg('Error: the request method is not POST');
return FALSE;
}
// Authorized IPs
$authorized_ips = array_map(function($ip){ return trim($ip); }, explode(',', GITHUB_SYNC_IPS));
if (!in_array($_SERVER['REMOTE_ADDR'], $authorized_ips)) {
log_msg('Error: IP not authorized ('. $_SERVER['REMOTE_ADDR'] .')');
return FALSE;
}
// Payload parameter
if (!isset($_POST['payload'])) {
log_msg('Error: missing "payload" parameter.');
return FALSE;
}
return TRUE;
}
function update_repository($raw_content) {
$content = json_decode($raw_content);
if ($content == NULL
|| !property_exists($content, 'ref')
|| !property_exists($content, 'repository')
|| !property_exists($content->repository, 'name')
|| !property_exists($content->repository, 'owner')
|| !property_exists($content->repository->owner, 'name')) {
log_msg('Error: malformed JSON.');
return;
}
if ($content->ref === 'refs/heads/'.GITHUB_SYNC_BRANCH // Branch updated
&& "{$content->repository->owner->name}/{$content->repository->name}" === GITHUB_SYNC_REPO_ID) { // Valid repository
chdir(GITHUB_SYNC_DIR);
exec('git pull '.escapeshellarg(GITHUB_SYNC_REMOTE).' '.escapeshellarg(GITHUB_SYNC_BRANCH));
log_msg('Repository updated.');
} else {
log_msg('Error: wrong branch (configured: '. GITHUB_SYNC_BRANCH .', pushed: '. end(explode('/', $content->ref)) .')');
}
}
/* Adding the custom URL */
// First step: flush rewrite rules on activation.
register_activation_hook(__FILE__, function(){
flush_rewrite_rules(FALSE);
});
// Second step: add a new rewrite rule.
// This new rewrite rule should redirect to an existing file.
// We use index.php with a query var.
add_filter('rewrite_rules_array', function($rules) use($wp_rewrite) {
$new_rules = array('^github-sync\/?$' => 'index.php?github_sync=1');
return $new_rules + $rules;
});
// But this query var is not valid, so we need to add it manually.
add_filter('query_vars', function($qvars) {
$qvars[] = 'github_sync';
return $qvars;
});
// And we finally intercept the request, based on the query.
add_action('template_redirect', function(){
if (get_query_var('github_sync') == '1') {
log_msg("\n\nNew update request. Check...");
if (check_request()) {
log_msg('All check tests passed. Update repository...');
update_repository(stripcslashes($_POST['payload']));
} else {
wp_die(__('You are not authorized to view this page.'), '', array( 'response' => 403 ) );
}
}
});