]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - nixops/modules/buildbot/common/build_helpers.py
Add xmpp push notifications to buildbot and gitolite
[perso/Immae/Config/Nix.git] / nixops / modules / buildbot / common / build_helpers.py
index f51de5470ff2d0439f953a6485a64dbbf77deb47..63733e7b31ec4b264eba8e62d46657c992940e1e 100644 (file)
@@ -3,7 +3,8 @@ from buildbot_buildslist import BuildsList
 
 __all__ = [
         "force_scheduler", "deploy_scheduler", "hook_scheduler",
-        "clean_branch", "package_and_upload", "SlackStatusPush"
+        "clean_branch", "package_and_upload", "SlackStatusPush",
+        "XMPPStatusPush"
         ]
 
 # Small helpers"
@@ -71,13 +72,16 @@ def hook_scheduler(project, timer=10):
             change_filter=util.ChangeFilter(category="hooks", project=project),
             name=project, treeStableTimer=timer, builderNames=["{}_build".format(project)])
 
-# Slack status push
+# Slack/XMPP status push
 from buildbot.reporters.http import HttpStatusPushBase
 from twisted.internet import defer
 from twisted.python import log
 from buildbot.util import httpclientservice
 from buildbot.reporters import utils
 from buildbot.process import results
+from twisted.words.protocols.jabber.jid import JID
+from wokkel import client, xmppim
+
 
 class SlackStatusPush(HttpStatusPushBase):
     name = "SlackStatusPush"
@@ -188,5 +192,66 @@ class SlackStatusPush(HttpStatusPushBase):
                 "attachments": attachments,
                 }
 
+class XMPPStatusPush(HttpStatusPushBase):
+    name = "XMPPStatusPush"
+
+    @defer.inlineCallbacks
+    def reconfigService(self, password, recipients, **kwargs):
+        yield HttpStatusPushBase.reconfigService(self, **kwargs)
+        self.password = password
+        self.recipients = recipients
+
+    @defer.inlineCallbacks
+    def send(self, build):
+        yield utils.getDetailsForBuild(self.master, build, wantProperties=True)
+        body = self.format(build)
+        factory = client.DeferredClientFactory(JID("notify_bot@immae.fr/buildbot"), self.password)
+        factory.streamManager.logTraffic = True
+        d = client.clientCreator(factory)
+        def send_message(stream):
+            message = xmppim.Message(recipient=JID(recipient), body=body)
+            message.stanzaType = 'chat'
+            stream.send(message.toElement())
+            # To allow chaining
+            return stream
+        for recipient in self.recipients:
+            d.addCallback(send_message)
+        d.addCallback(lambda _: factory.streamManager.xmlstream.sendFooter())
+        d.addErrback(log.err)
+
+    def format(self, build):
+        if "environment" in build["properties"]:
+            msg = "{} environment".format(build["properties"]["environment"][0])
+            if "build" in build["properties"]:
+                msg = "of archive {} in ".format(build["properties"]["build"][0]) + msg
+        elif len(build["buildset"]["sourcestamps"][0]["branch"]) > 0:
+            msg = "revision {}".format(build["buildset"]["sourcestamps"][0]["branch"])
+        else:
+            msg = "build"
+
+        if build["complete"]:
+            timedelta = int((build["complete_at"] - build["started_at"]).total_seconds())
+            hours, rest = divmod(timedelta, 3600)
+            minutes, seconds = divmod(rest, 60)
+            if hours > 0:
+                duration = "{}h {}min {}s".format(hours, minutes, seconds)
+            elif minutes > 0:
+                duration = "{}min {}s".format(minutes, seconds)
+            else:
+                duration = "{}s".format(seconds)
 
+            text = "Build {} ( {} ) of {}'s {} was {} in {}.".format(
+                    build["buildid"], build["url"],
+                    build["builder"]["name"],
+                    msg,
+                    results.Results[build["results"]],
+                    duration,
+                    )
+        else:
+            text = "Build {} ( {} ) of {}'s {} started.".format(
+                    build["buildid"], build["url"],
+                    build["builder"]["name"],
+                    msg,
+                    )
 
+        return text