Dans Google code il y a la possibilité d’utiliser un gestionnaire de version tel que subversion (svn) ou mercurial (hg). C’est bien pratique, mais malheureusement, de base, rien n’est prévu pour prévenir (excepté par flux RSS) les gens de ces mises à jour. Cependant, Google code permet d’utiliser un webhook en post commit.
Qu’est-ce qu’un webhook?
Un webhook c’est un « crochet web », c’est-à-dire une URL a appelée après (avant ou pendant) une action X. Dans notre cas, après chaque commit une URL est appelée.
Utilisation
Voici un exemple de code que j’utilise pour plusieurs de mes projets :
<?php
// project name
$projects = array('mon-super-projet');
// google code webhook key
$keys = array(
'b-box' => 'Top-Secret_key_fourni_par_google-dans-l-adminsitration'
);
//user agent from google code
$useragent = 'Google Code Project Hosting (+http://code.google.com/p/support/wiki/PostCommitWebHooks)';
//email of all owner (eg. project chief)
$owners = array('vous@example.com');
//email of all team members except owners
$users = array('toi@example.com');
//sender of email
$sender = 'WebHook mailer<webmaster@exemple.com>';
//----------------------------------------------------------------------
$project = (isset($_GET['p']))?$_GET['p']:'';
$revision = (isset($_GET['r']))?intval($_GET['r']):-99;
$data = file_get_contents('php://input');
$digest = (isset($_SERVER['HTTP_GOOGLE_CODE_PROJECT_HOSTING_HOOK_HMAC']))?$_SERVER['HTTP_GOOGLE_CODE_PROJECT_HOSTING_HOOK_HMAC']:'';
//----------------------------------------------------------------------
/**
* Send a mail
* @param string $from email of the sender : sample@example.com or "name"<sample@example.com>;
* @param array $to [a] => list of email [cc], [bcc] (hidden), ...
* @param string $subject
* @param string $body
* @return bool true if success
*/
function mailer($from, array $to, $subject, $body)
{
if (empty($to))
{
return false;
}
$headers = 'From: ' . $from . "\n";
$a = '';
if (isset($to['a']) && !empty($to['a']))
{
$a = implode(',', $to['a']);
}
if (isset($to['bcc']) && !empty($to['bcc']))
{
$headers .= 'Bcc: ' . implode(',', $to['bcc']) . "\n";
}
if (isset($to['cc']) && !empty($to['cc']))
{
$headers .= 'Cc: ' . implode(',', $to['cc']) . "\n";
}
$headers .= 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-Type: text/plain; charset="UTF-8"' . "\n";
$headers .= 'Content-Transfer-Encoding: 8bit' . "\n";
$headers .= 'X-Mailer: PHP/' . phpversion();
return mail($a, '[webhook]' . $subject, $body, $headers);
}
function failed($test_id, $msg)
{
global $sender, $owners;
$msg .= "\n--\nWebHook mail from the Google code project";
mailer($sender, array('bcc' => $owners), 'failed test #' . $test_id, $msg);
die('KO');
}
function get_ip()
{
return (isset($_SERVER['HTTP_X_FORWARDED_FOR']))?$_SERVER['HTTP_X_FORWARDED_FOR']:(isset($_SERVER['HTTP_CLIENT_IP']))?$_SERVER['HTTP_CLIENT_IP']:$_SERVER['REMOTE_ADDR'];
}
//----------------------------------------------------------------------
if ($useragent != $_SERVER['HTTP_USER_AGENT'])
{
// failed 1
failed(1, 'User agent is bad : ' . htmlspecialchars($_SERVER['HTTP_USER_AGENT']) . "\n\nFrom : " . get_ip());
}
elseif (empty($project) || !in_array($project, $projects))
{
// failed 2
failed(2, 'No project set : ' . htmlspecialchars($project) . "\n\nFrom : " . get_ip());
}
else
{
$hmac = hash_hmac('md5', $data, $keys[ $project ]);
$data = json_decode($data, true);
if (empty($digest) || $digest != $hmac)
{
// failed 3
failed(3, 'Bad digest : ' . $digest . ' vs ' . $hmac . "\n\nFrom : " . get_ip());
}
elseif (intval($data['revision_count']) != count($data['revisions']))
{
// failed 4
failed(4, 'Bad count : ' . count($data['revisions']) . ' vs ' . intval($data['revision_count']) . "\n\nFrom : " . get_ip());
}
else
{
$mail_body = '';
foreach($data['revisions'] as $_revision)
{
$mail_body .= 'Revision : ' . "\t" . htmlentities($_revision['revision']) . ' from ' . htmlentities($_revision['author']) . ' at ' . date('Y-m-d H:i', intval($_revision['timestamp'])) . "\n";
$mail_body .= 'Added : ' . "\t" . implode("\n\t\t", htmlentities($_revision['added'])) . "\n";
$mail_body .= 'Modified : ' . "\t" . implode("\n\t\t\t", htmlentities($_revision['modified'])) . "\n";
$mail_body .= 'Removed : ' . "\t" . implode("\n\t\t\t", htmlentities($_revision['removed'])) . "\n\n";
// $mail_body .= 'URL : ' . "\t\t" . htmlentities($_revision['url']) . "\n\n";
$mail_body .= 'Message : ' . "\t" . htmlentities($_revision['message']) . "\n\n\n";
// $_revision['path_count'];
}
$mail_body .= "\n--\nWebHook mail from the Google code project : " . $project . "\nhttp://code.google.com/p/" . $project . "/\n";
mailer($sender, array('bcc' => $owners + $users), '[' . $project . ']New revision #' . $revision, $mail_body);
}
}
exit('OK');
# EOF |
<?php
// project name
$projects = array('mon-super-projet');
// google code webhook key
$keys = array(
'b-box' => 'Top-Secret_key_fourni_par_google-dans-l-adminsitration'
);
//user agent from google code
$useragent = 'Google Code Project Hosting (+http://code.google.com/p/support/wiki/PostCommitWebHooks)';
//email of all owner (eg. project chief)
$owners = array('vous@example.com');
//email of all team members except owners
$users = array('toi@example.com');
//sender of email
$sender = 'WebHook mailer<webmaster@exemple.com>';
//----------------------------------------------------------------------
$project = (isset($_GET['p']))?$_GET['p']:'';
$revision = (isset($_GET['r']))?intval($_GET['r']):-99;
$data = file_get_contents('php://input');
$digest = (isset($_SERVER['HTTP_GOOGLE_CODE_PROJECT_HOSTING_HOOK_HMAC']))?$_SERVER['HTTP_GOOGLE_CODE_PROJECT_HOSTING_HOOK_HMAC']:'';
//----------------------------------------------------------------------
/**
* Send a mail
* @param string $from email of the sender : sample@example.com or "name"<sample@example.com>;
* @param array $to [a] => list of email [cc], [bcc] (hidden), ...
* @param string $subject
* @param string $body
* @return bool true if success
*/
function mailer($from, array $to, $subject, $body)
{
if (empty($to))
{
return false;
}
$headers = 'From: ' . $from . "\n";
$a = '';
if (isset($to['a']) && !empty($to['a']))
{
$a = implode(',', $to['a']);
}
if (isset($to['bcc']) && !empty($to['bcc']))
{
$headers .= 'Bcc: ' . implode(',', $to['bcc']) . "\n";
}
if (isset($to['cc']) && !empty($to['cc']))
{
$headers .= 'Cc: ' . implode(',', $to['cc']) . "\n";
}
$headers .= 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-Type: text/plain; charset="UTF-8"' . "\n";
$headers .= 'Content-Transfer-Encoding: 8bit' . "\n";
$headers .= 'X-Mailer: PHP/' . phpversion();
return mail($a, '[webhook]' . $subject, $body, $headers);
}
function failed($test_id, $msg)
{
global $sender, $owners;
$msg .= "\n--\nWebHook mail from the Google code project";
mailer($sender, array('bcc' => $owners), 'failed test #' . $test_id, $msg);
die('KO');
}
function get_ip()
{
return (isset($_SERVER['HTTP_X_FORWARDED_FOR']))?$_SERVER['HTTP_X_FORWARDED_FOR']:(isset($_SERVER['HTTP_CLIENT_IP']))?$_SERVER['HTTP_CLIENT_IP']:$_SERVER['REMOTE_ADDR'];
}
//----------------------------------------------------------------------
if ($useragent != $_SERVER['HTTP_USER_AGENT'])
{
// failed 1
failed(1, 'User agent is bad : ' . htmlspecialchars($_SERVER['HTTP_USER_AGENT']) . "\n\nFrom : " . get_ip());
}
elseif (empty($project) || !in_array($project, $projects))
{
// failed 2
failed(2, 'No project set : ' . htmlspecialchars($project) . "\n\nFrom : " . get_ip());
}
else
{
$hmac = hash_hmac('md5', $data, $keys[ $project ]);
$data = json_decode($data, true);
if (empty($digest) || $digest != $hmac)
{
// failed 3
failed(3, 'Bad digest : ' . $digest . ' vs ' . $hmac . "\n\nFrom : " . get_ip());
}
elseif (intval($data['revision_count']) != count($data['revisions']))
{
// failed 4
failed(4, 'Bad count : ' . count($data['revisions']) . ' vs ' . intval($data['revision_count']) . "\n\nFrom : " . get_ip());
}
else
{
$mail_body = '';
foreach($data['revisions'] as $_revision)
{
$mail_body .= 'Revision : ' . "\t" . htmlentities($_revision['revision']) . ' from ' . htmlentities($_revision['author']) . ' at ' . date('Y-m-d H:i', intval($_revision['timestamp'])) . "\n";
$mail_body .= 'Added : ' . "\t" . implode("\n\t\t", htmlentities($_revision['added'])) . "\n";
$mail_body .= 'Modified : ' . "\t" . implode("\n\t\t\t", htmlentities($_revision['modified'])) . "\n";
$mail_body .= 'Removed : ' . "\t" . implode("\n\t\t\t", htmlentities($_revision['removed'])) . "\n\n";
// $mail_body .= 'URL : ' . "\t\t" . htmlentities($_revision['url']) . "\n\n";
$mail_body .= 'Message : ' . "\t" . htmlentities($_revision['message']) . "\n\n\n";
// $_revision['path_count'];
}
$mail_body .= "\n--\nWebHook mail from the Google code project : " . $project . "\nhttp://code.google.com/p/" . $project . "/\n";
mailer($sender, array('bcc' => $owners + $users), '[' . $project . ']New revision #' . $revision, $mail_body);
}
}
exit('OK');
# EOF
Plus d’info : PostCommitWebHooks