Author: Nikita Popov (nikic)
Date: 2021-04-07T16:47:34+02:00
Commit:
https://github.com/php/web-master/commit/07d7ac181bef1100f2ff79003323c98f267ea38f
Raw diff:
https://github.com/php/web-master/commit/07d7ac181bef1100f2ff79003323c98f267ea38f.diff
Avoid sending duplicate mails for commits
Store commits we saw in the DB, and don't send duplicate mails
for them. This removes the php-src specific hack that I put in
place previously.
Ideally the distinct flag would tell use whether or not a commit
mail should be sent, but it doesn't work the way we need it to.
Changed paths:
M public/github-webhook.php
M schema.sql
Diff:
diff --git a/public/github-webhook.php b/public/github-webhook.php
index 6191981..738829b 100644
--- a/public/github-webhook.php
+++ b/public/github-webhook.php
@@ -2,9 +2,7 @@
const DRY_RUN = false;
-if (!DRY_RUN) {
- require __DIR__ . '/../include/mailer.php';
-}
+require __DIR__ . '/../include/mailer.php';
function verify_signature($requestBody) {
if (isset($_SERVER['HTTP_X_HUB_SIGNATURE'])){
@@ -195,7 +193,25 @@ function handle_ref_change_mail($mailingList, $payload) {
send_mail($mailingList, $subject, $message,
MailAddress::noReply($pusherName));
}
-function handle_commit_mail($mailingList, $repoName, $ref, $pusherUser,
$commit) {
+function handle_commit_mail(PDO $dbh, $mailingList, $repoName, $ref,
$pusherUser, $commit) {
+ $query = $dbh->prepare('INSERT INTO commits (repo, hash) VALUES (?, ?)');
+ try {
+ $query->execute([$repoName, $commit->id]);
+ } catch (PDOException $e) {
+ if ($e->errorInfo[1] === 1062) {
+ // We don't want to send a mail when an existing commit gets
merged into a new branch.
+ // In that case, only a mail for the merge commit should be sent
(or a mail for the
+ // new branch). Unfortunately, the "distinct" flag that GitHub
provides for this purpose
+ // is buggy: If multiple branches are pushed at the same time,
then the commits will
+ // have distict=false for all pushes, rather than having the first
push with
+ // distinct=true and the rest with distinct=false. For this
reason, we store all the
+ // commit hashes we saw in the database and only send a mail for
new commits.
+ return;
+ }
+
+ throw $e;
+ }
+
$authorUser = isset($commit->author->username) ? $commit->author->username
: null;
$authorName = $commit->author->name;
$committerUser = isset($commit->committer->username) ?
$commit->committer->username : null;
@@ -268,16 +284,12 @@ function handle_push_mail($payload) {
handle_ref_change_mail($mailingList, $payload);
}
- // Ignore commits to PHP-x.y branches for now, to avoid duplicate commits
on upwards merges.
- // TODO: Find a better solution to this problem...
- if ($repoName === 'php-src' && preg_match('(^refs/heads/PHP-\d\.\d$)',
$ref)) {
- echo "Skipping commit mails for push to $payload->ref of $repoName";
- return;
- }
+ $dbh = new PDO('mysql:host=localhost;dbname=phpmasterdb', 'nobody', '');
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pusherName = $payload->pusher->name;
foreach ($payload->commits as $commit) {
- handle_commit_mail($mailingList, $repoName, $ref, $pusherName,
$commit);
+ handle_commit_mail($dbh, $mailingList, $repoName, $ref, $pusherName,
$commit);
}
}
diff --git a/schema.sql b/schema.sql
index b378fbc..778c148 100644
--- a/schema.sql
+++ b/schema.sql
@@ -25,6 +25,20 @@ CREATE TABLE `auth` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
+--
+-- Table structure for table `commits`
+--
+
+DROP TABLE IF EXISTS `commits`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `commits` (
+ `repo` varchar(100) NOT NULL,
+ `hash` binary(40) NOT NULL,
+ UNIQUE KEY `repo` (`repo`,`hash`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
--
-- Table structure for table `country`
--
--
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php