launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #26123
[Merge] lp:~twom/lpbuildbot/mattermost-notifier into lp:lpbuildbot
Tom Wardill has proposed merging lp:~twom/lpbuildbot/mattermost-notifier into lp:lpbuildbot.
Commit message:
Add mattermost notifier
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~twom/lpbuildbot/mattermost-notifier/+merge/397038
Add notifier code for sending a mattermost webhook. The webhook url is considered a secret, so defend against it not being defined in this branch master.cfg.
Also name the build steps so they produce prettier output.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~twom/lpbuildbot/mattermost-notifier into lp:lpbuildbot.
=== added file 'lpbuildbot/mattermost.py'
--- lpbuildbot/mattermost.py 1970-01-01 00:00:00 +0000
+++ lpbuildbot/mattermost.py 2021-01-27 17:36:58 +0000
@@ -0,0 +1,110 @@
+import json
+
+import requests
+from twisted.python import log as twlog
+
+from buildbot.status.base import StatusReceiverMultiService
+from buildbot.status.results import Results
+
+
+class MattermostNotifier(StatusReceiverMultiService):
+
+ def __init__(self, webhook_url, channel, author):
+ StatusReceiverMultiService.__init__(self)
+ self.webhook_url = webhook_url
+ self.channel = channel
+ self.author = author
+
+ def _transmit(self, payload):
+ payload["channel"] = self.channel
+ payload["author_name"] = self.author
+
+ requests.post(
+ self.webhook_url,
+ data=json.dumps(payload),
+ headers={"Content-type": "application/json"}
+ )
+
+ def builderAdded(self, builderName, builder):
+ twlog.msg("Mattermost notifier: builder added")
+ builder.subscribe(self)
+
+ def buildStarted(self, builderName, build):
+ twlog.msg("Mattermost notifier: build started")
+ build.subscribe(self)
+
+ payload = {
+ "attachments": [{
+ "title": "Build started",
+ "title_link": self.status.getURLForThing(build),
+ "color": "#0000FF",
+ "text": "Build number {} of {} has started on {}".format(
+ build.getNumber(), builderName, build.getSlavename()),
+ "fields": [
+ {
+ "short": True,
+ "title": "Revision",
+ "value": build.getSourceStamp().revision
+ },
+ {
+ "short": True,
+ "title": "Reason",
+ "value": build.getReason()
+ }]
+ }]
+ }
+
+ self._transmit(payload)
+
+ def buildFinished(self, builderName, build, results):
+
+ word = Results[results]
+ colors = ["#00FF00", "#00FFFF", "#FF0000",
+ "#00FFFF", "#FFFF00", "#00FFFF"]
+ color = colors[results]
+
+ payload = {
+ "attachments": [{
+ "title": "Build {}: {}".format(build.getNumber(), word),
+ "title_link": self.status.getURLForThing(build),
+ "color": color,
+ "text": "Build number {} of {} has completed with {}.".format(
+ build.getNumber(), builderName, word),
+ "fields": [{
+ "short": False,
+ "title": "Responsible users",
+ "value": build.getResponsibleUsers()
+ },
+ {
+ "short": True,
+ "title": "Revision",
+ "value": build.getSourceStamp().revision
+ },
+ {
+ "short": True,
+ "title": "Reason",
+ "value": build.getReason()
+ }]
+ }]
+ }
+
+ for count, step in enumerate(build.getSteps()):
+ result, _ = step.getResults()
+ if result != 0:
+ payload['attachments'][0]['fields'].append({
+ "short": True,
+ "title": "Failed step: {}".format(count),
+ "value": step.getName()
+ })
+ break
+
+ self._transmit(payload)
+
+
+ def setServiceParent(self, parent):
+ StatusReceiverMultiService.setServiceParent(self, parent)
+ self.status = parent.getStatus()
+
+ self.status.subscribe(self)
+
+ twlog.msg("Mattermost notifier configured")
=== modified file 'master.cfg'
--- master.cfg 2021-01-07 09:32:46 +0000
+++ master.cfg 2021-01-27 17:36:58 +0000
@@ -76,44 +76,52 @@
def addEnvironmentPrepSteps(fac, tree, container, variables=None):
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="link-external-sourcecode",
command=['./utilities/link-external-sourcecode',
'-p', "{}/dependencies".format(tree)],
description=['linking', 'dependencies'],
descriptionDone=['link', 'dependencies'],
workdir="{}/devel".format(tree)))
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="update-sourcecode",
command=['./utilities/update-sourcecode', '--use-http'],
description=['pulling', 'new', 'sourcecode', 'revisions'],
descriptionDone=['pull', 'new', 'sourcecode', 'revisions'],
workdir="{}/devel".format(tree)))
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="git pull download-cache",
command=['git', 'pull'],
description=['updating', 'download', 'cache'],
descriptionDone=['update', 'download', 'cache'],
workdir="{}/devel/download-cache".format(tree)))
fac.addStep(transfer.FileDownload(
+ name="Download testr.conf",
mastersrc='testr.conf',
slavedest='.testr.conf',
mode=0o644,
workdir="{}/devel".format(tree)))
# Clean up any potential cruft left around by lxd from a previous run.
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="lp-setup-lxd-cleanup",
command=['/usr/bin/lp-setup-lxd-cleanup', container],
description=['cleanup','previous','lxd','containers'],
descriptionDone=['cleaned','previous','lxd','containers'],
workdir="{}/devel".format(tree)))
fac.addStep(transfer.FileDownload(
+ name="Downlad init_testr.py",
mastersrc='scripts/init_testr.py',
slavedest='init_testr.py',
mode=0o544,
workdir="{}/devel".format(tree)))
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="init_testr.py",
command=['./init_testr.py'],
description=['initializing', 'testrepository'],
descriptionDone=['initialized', 'testrepository'],
workdir="{}/devel".format(tree)))
# Make a temp dir, to work around bug 808557.
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="make temp dir",
command=['mkdir', 'temp'],
workdir="{}/devel".format(tree)))
build_command = ['/usr/bin/lp-setup-lxd-build', container, tree]
@@ -121,6 +129,7 @@
for key, value in variables.items():
build_command.append("--variable={}={}".format(key, value))
fac.addStep(lpbuildbot.shell.ShellCommand(
+ name="Build in base lxd",
command=build_command,
description=['building', 'in', 'base', 'lxd', 'container'],
descriptionDone=['build', 'in', 'base', 'lxd', 'container'],
@@ -223,12 +232,16 @@
lookup=lpbuildbot.mail.PassThroughLookup(),
builders=['lp-devel-xenial', 'lp-db-devel-xenial']))
-# at the time of this writing, the buildbot IRC client does not support SSL
-# so we would need to modify buildbot to use this. Supposedly Twisted's IRC
-# code does support SSL, so this might not be hard to change.
-# from buildbot.status import words
-# c['status'].append(words.IRC(host="irc.example.com", nick="bb",
-# channels=["#example"]))
+# Notify the mattermost channel
+# this is defined in the production config branch
+mattermost_hook_url = None
+if mattermost_hook_url:
+ import lpbuildbot.mattermost
+ c['status'].append(
+ lpbuildbot.mattermost.MattermostNotifier(
+ mattermost_hook_url,
+ "launchpad-alerts",
+ "lpbuildbot")) # this is ignored by chat.c.c config
####### DEBUGGING OPTIONS
Follow ups