]> 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",
 
 __all__ = [
         "force_scheduler", "deploy_scheduler", "hook_scheduler",
-        "clean_branch", "package_and_upload", "SlackStatusPush"
+        "clean_branch", "package_and_upload", "SlackStatusPush",
+        "XMPPStatusPush"
         ]
 
 # Small helpers"
         ]
 
 # 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)])
 
             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 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"
 
 class SlackStatusPush(HttpStatusPushBase):
     name = "SlackStatusPush"
@@ -188,5 +192,66 @@ class SlackStatusPush(HttpStatusPushBase):
                 "attachments": attachments,
                 }
 
                 "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