__all__ = [
"force_scheduler", "deploy_scheduler", "hook_scheduler",
- "clean_branch", "package_and_upload", "SlackStatusPush"
+ "clean_branch", "package_and_upload", "SlackStatusPush",
+ "XMPPStatusPush"
]
# Small helpers"
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"
"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