`_ for more options to pass to ``change_hook_auth``.
Note that not using ``change_hook_auth`` may expose you to security risks.
BitBucket hook
##############
The BitBucket hook is as simple as GitHub one and it also takes no options. ::
c['status'].append(html.WebStatus(...,
change_hook_dialects={ 'bitbucket' : True }))
When this is setup you should add a `POST` service pointing to ``/change_hook/bitbucket``
relative to the root of the web status. For example, it the grid URL is
``http://builds.mycompany.com/bbot/grid``, then point BitBucket to
``http://builds.mycompany.com/change_hook/bitbucket``. To specify a project associated
to the repository, append ``?project=name`` to the URL.
Note that there is a satandalone HTTP server available for receiving BitBucket
notifications, as well: :file:`contrib/bitbucket_buildbot.py`. This script may be
useful in cases where you cannot expose the WebStatus for public consumption.
.. warning::
As in the previous case, the incoming HTTP requests for this hook are not
authenticated bu default. Anyone who can access the web status can "fake"
a request from BitBucket, potentially causing the buildmaster to run
arbitrary code.
To protect URL against unauthorized access you should use ``change_hook_auth`` option. ::
c['status'].append(html.WebStatus(...,
change_hook_auth=["file:changehook.passwd"]))
Then, create a BitBucket service hook (see https://confluence.atlassian.com/display/BITBUCKET/POST+Service+Management) with a WebHook URL like ``http://user:password@builds.mycompany.com/bbot/change_hook/bitbucket``.
Note that as before, not using ``change_hook_auth`` can expose you to security risks.
Google Code hook
################
The Google Code hook is quite similar to the GitHub Hook. It has one option
for the "Post-Commit Authentication Key" used to check if the request is
legitimate::
c['status'].append(html.WebStatus(
# ...
change_hook_dialects={'googlecode': {'secret_key': 'FSP3p-Ghdn4T0oqX'}}
))
This will add a "Post-Commit URL" for the project in the Google Code
administrative interface, pointing to ``/change_hook/googlecode`` relative to
the root of the web status.
Alternatively, you can use the :ref:`GoogleCodeAtomPoller` :class:`ChangeSource`
that periodically poll the Google Code commit feed for changes.
.. note::
Google Code doesn't send the branch on which the changes were made. So, the
hook always returns ``'default'`` as the branch, you can override it with the
``'branch'`` option::
change_hook_dialects={'googlecode': {'secret_key': 'FSP3p-Ghdn4T0oqX', 'branch': 'master'}}
Poller hook
###########
The poller hook allows you to use GET or POST requests to trigger
polling. One advantage of this is your buildbot instance can poll
at launch (using the pollAtLaunch flag) to get changes that happened
while it was down, but then you can still use a commit hook to get
fast notification of new changes.
Suppose you have a poller configured like this::
c['change_source'] = SVNPoller(
svnurl="https://amanda.svn.sourceforge.net/svnroot/amanda/amanda",
split_file=split_file_branches,
pollInterval=24*60*60,
pollAtLaunch=True)
And you configure your WebStatus to enable this hook::
c['status'].append(html.WebStatus(
# ...
change_hook_dialects={'poller': True}
))
Then you will be able to trigger a poll of the SVN repository by poking the
``/change_hook/poller`` URL from a commit hook like this:
.. code-block:: bash
curl -s -F poller=https://amanda.svn.sourceforge.net/svnroot/amanda/amanda \
http://yourbuildbot/change_hook/poller
If no ``poller`` argument is provided then the hook will trigger polling of all
polling change sources.
You can restrict which pollers the webhook has access to using the ``allowed``
option::
c['status'].append(html.WebStatus(
# ...
change_hook_dialects={'poller': {'allowed': ['https://amanda.svn.sourceforge.net/svnroot/amanda/amanda']}}
))
GitLab hook
###########
The GitLab hook is as simple as GitHub one and it also takes no options. ::
c['status'].append(html.WebStatus(
# ...
change_hook_dialects={ 'gitlab' : True }
))
When this is setup you should add a `POST` service pointing to ``/change_hook/gitlab``
relative to the root of the web status. For example, it the grid URL is
``http://builds.mycompany.com/bbot/grid``, then point GitLab to
``http://builds.mycompany.com/change_hook/gitlab``. The project and/or codebase can
also be passed in the URL by appending ``?project=name`` or ``?codebase=foo`` to the URL.
These parameters will be passed along to the scheduler.
.. warning::
As in the previous case, the incoming HTTP requests for this hook are not
authenticated bu default. Anyone who can access the web status can "fake"
a request from your GitLab server, potentially causing the buildmaster to run
arbitrary code.
To protect URL against unauthorized access you should use ``change_hook_auth`` option. ::
c['status'].append(html.WebStatus(
# ...
change_hook_auth=["file:changehook.passwd"]
))
Then, create a GitLab service hook (see https://your.gitlab.server/help/web_hooks) with a WebHook URL like ``http://user:password@builds.mycompany.com/bbot/change_hook/gitlab``.
Note that as before, not using ``change_hook_auth`` can expose you to security risks.
Gitorious Hook
##############
The Gitorious hook is as simple as GitHub one and it also takes no options. ::
c['status'].append(html.WebStatus(
# ...
change_hook_dialects={'gitorious': True}
))
When this is setup you should add a `POST` service pointing to ``/change_hook/gitorious``
relative to the root of the web status. For example, it the grid URL is
``http://builds.mycompany.com/bbot/grid``, then point Gitorious to
``http://builds.mycompany.com/change_hook/gitorious``.
.. warning::
As in the previous case, the incoming HTTP requests for this hook are not
authenticated by default. Anyone who can access the web status can "fake"
a request from your Gitorious server, potentially causing the buildmaster to run
arbitrary code.
To protect URL against unauthorized access you should use ``change_hook_auth`` option. ::
c['status'].append(html.WebStatus(
# ...
change_hook_auth=["file:changehook.passwd"]
))
Then, create a Gitorious web hook (see http://gitorious.org/gitorious/pages/WebHooks) with a WebHook URL like ``http://user:password@builds.mycompany.com/bbot/change_hook/gitorious``.
Note that as before, not using ``change_hook_auth`` can expose you to security risks.
.. note::
Web hooks are only available for local Gitorious
installations, since this feature is not offered as part of
Gitorious.org yet.
.. bb:status:: MailNotifier
.. index:: single: email; MailNotifier
MailNotifier
~~~~~~~~~~~~
.. py:class:: buildbot.status.mail.MailNotifier
The buildbot can also send email when builds finish. The most common
use of this is to tell developers when their change has caused the
build to fail. It is also quite common to send a message to a mailing
list (usually named `builds` or similar) about every build.
The :class:`MailNotifier` status target is used to accomplish this. You
configure it by specifying who mail should be sent to, under what
circumstances mail should be sent, and how to deliver the mail. It can
be configured to only send out mail for certain builders, and only
send messages when the build fails, or when the builder transitions
from success to failure. It can also be configured to include various
build logs in each message.
If a proper lookup function is configured, the message will be sent to the
"interested users" list (:ref:`Doing-Things-With-Users`), which includes all
developers who made changes in the build. By default, however, Buildbot does
not know how to construct an email addressed based on the information from the
version control system. See the ``lookup`` argument, below, for more
information.
You can add additional, statically-configured, recipients with the
``extraRecipients`` argument. You can also add interested users by setting the
``owners`` build property to a list of users in the scheduler constructor
(:ref:`Configuring-Schedulers`).
Each :class:`MailNotifier` sends mail to a single set of recipients. To send
different kinds of mail to different recipients, use multiple
:class:`MailNotifier`\s.
The following simple example will send an email upon the completion of
each build, to just those developers whose :class:`Change`\s were included in
the build. The email contains a description of the :class:`Build`, its results,
and URLs where more information can be obtained. ::
from buildbot.status.mail import MailNotifier
mn = MailNotifier(fromaddr="buildbot@example.org", lookup="example.org")
c['status'].append(mn)
To get a simple one-message-per-build (say, for a mailing list), use
the following form instead. This form does not send mail to individual
developers (and thus does not need the ``lookup=`` argument,
explained below), instead it only ever sends mail to the `extra
recipients` named in the arguments::
mn = MailNotifier(fromaddr="buildbot@example.org",
sendToInterestedUsers=False,
extraRecipients=['listaddr@example.org'])
If your SMTP host requires authentication before it allows you to send emails,
this can also be done by specifying ``smtpUser`` and ``smptPassword``::
mn = MailNotifier(fromaddr="myuser@gmail.com",
sendToInterestedUsers=False,
extraRecipients=["listaddr@example.org"],
relayhost="smtp.gmail.com", smtpPort=587,
smtpUser="myuser@gmail.com", smtpPassword="mypassword")
If you want to require Transport Layer Security (TLS), then you can also
set ``useTls``::
mn = MailNotifier(fromaddr="myuser@gmail.com",
sendToInterestedUsers=False,
extraRecipients=["listaddr@example.org"],
useTls=True, relayhost="smtp.gmail.com", smtpPort=587,
smtpUser="myuser@gmail.com", smtpPassword="mypassword")
.. note:: If you see ``twisted.mail.smtp.TLSRequiredError`` exceptions in
the log while using TLS, this can be due *either* to the server not
supporting TLS or to a missing `PyOpenSSL`_ package on the buildmaster system.
In some cases it is desirable to have different information then what is
provided in a standard MailNotifier message. For this purpose MailNotifier
provides the argument ``messageFormatter`` (a function) which allows for the
creation of messages with unique content.
For example, if only short emails are desired (e.g., for delivery to phones) ::
from buildbot.status.builder import Results
def messageFormatter(mode, name, build, results, master_status):
result = Results[results]
text = list()
text.append("STATUS: %s" % result.title())
return {
'body' : "\n".join(text),
'type' : 'plain'
}
mn = MailNotifier(fromaddr="buildbot@example.org",
sendToInterestedUsers=False,
mode=('problem',),
extraRecipients=['listaddr@example.org'],
messageFormatter=messageFormatter)
Another example of a function delivering a customized html email
containing the last 80 log lines of logs of the last build step that
finished is given below::
from buildbot.status.builder import Results
import cgi, datetime
def html_message_formatter(mode, name, build, results, master_status):
"""Provide a customized message to Buildbot's MailNotifier.
The last 80 lines of the log are provided as well as the changes
relevant to the build. Message content is formatted as html.
"""
result = Results[results]
limit_lines = 80
text = list()
text.append(u'Build status: %s
' % result.upper())
text.append(u'')
text.append(u"Buildslave for this Build: | %s |
" % build.getSlavename())
if master_status.getURLForThing(build):
text.append(u'Complete logs for all build steps: | %s |
'
% (master_status.getURLForThing(build),
master_status.getURLForThing(build))
)
text.append(u'Build Reason: | %s |
' % build.getReason())
source = u""
for ss in build.getSourceStamps():
if ss.codebase:
source += u'%s: ' % ss.codebase
if ss.branch:
source += u"[branch %s] " % ss.branch
if ss.revision:
source += ss.revision
else:
source += u"HEAD"
if ss.patch:
source += u" (plus patch)"
if ss.patch_info: # add patch comment
source += u" (%s)" % ss.patch_info[1]
text.append(u"Build Source Stamp: | %s |
" % source)
text.append(u"Blamelist: | %s |
" % ",".join(build.getResponsibleUsers()))
text.append(u'
')
if ss.changes:
text.append(u'Recent Changes:
')
for c in ss.changes:
cd = c.asDict()
when = datetime.datetime.fromtimestamp(cd['when'] ).ctime()
text.append(u'')
text.append(u'Repository: | %s |
' % cd['repository'] )
text.append(u'Project: | %s |
' % cd['project'] )
text.append(u'Time: | %s |
' % when)
text.append(u'Changed by: | %s |
' % cd['who'] )
text.append(u'Comments: | %s |
' % cd['comments'] )
text.append(u'
')
files = cd['files']
if files:
text.append(u'Files |
')
for file in files:
text.append(u'%s: |
' % file['name'] )
text.append(u'
')
text.append(u'
')
# get all the steps in build in reversed order
rev_steps = reversed(build.getSteps())
# find the last step that finished
for step in rev_steps:
if step.isFinished():
break
# get logs for the last finished step
if step.isFinished():
logs = step.getLogs()
# No step finished, loop just exhausted itself; so as a special case we fetch all logs
else:
logs = build.getLogs()
# logs within a step are in reverse order. Search back until we find stdio
for log in reversed(logs):
if log.getName() == 'stdio':
break
name = "%s.%s" % (log.getStep().getName(), log.getName())
status, dummy = log.getStep().getResults()
content = log.getText().splitlines() # Note: can be VERY LARGE
url = u'%s/steps/%s/logs/%s' % (master_status.getURLForThing(build),
log.getStep().getName(),
log.getName())
text.append(u'Detailed log of last build step: %s'
% (url, url))
text.append(u'
')
text.append(u'Last %d lines of "%s"
' % (limit_lines, name))
unilist = list()
for line in content[len(content)-limit_lines:]:
unilist.append(cgi.escape(unicode(line,'utf-8')))
text.append(u'')
text.extend(unilist)
text.append(u'
')
text.append(u'
')
text.append(u'-The Buildbot')
return {
'body': u"\n".join(text),
'type': 'html'
}
mn = MailNotifier(fromaddr="buildbot@example.org",
sendToInterestedUsers=False,
mode=('failing',),
extraRecipients=['listaddr@example.org'],
messageFormatter=html_message_formatter)
MailNotifier arguments
++++++++++++++++++++++
``fromaddr``
The email address to be used in the 'From' header.
``sendToInterestedUsers``
(boolean). If ``True`` (the default), send mail to all of the Interested
Users. If ``False``, only send mail to the ``extraRecipients`` list.
``extraRecipients``
(list of strings). A list of email addresses to which messages should
be sent (in addition to the InterestedUsers list, which includes any
developers who made :class:`Change`\s that went into this build). It is a good
idea to create a small mailing list and deliver to that, then let
subscribers come and go as they please.
``subject``
(string). A string to be used as the subject line of the message.
``%(builder)s`` will be replaced with the name of the builder which
provoked the message.
``mode``
Mode is a list of strings; however there are two strings which can be used
as shortcuts instead of the full lists. The possible shortcuts are:
``all``
Always send mail about builds. Equivalent to (``change``, ``failing``,
``passing``, ``problem``, ``warnings``, ``exception``).
``warnings``
Equivalent to (``warnings``, ``failing``).
(list of strings). A combination of:
``change``
Send mail about builds which change status.
``failing``
Send mail about builds which fail.
``passing``
Send mail about builds which succeed.
``problem``
Send mail about a build which failed when the previous build has passed.
``warnings``
Send mail about builds which generate warnings.
``exception``
Send mail about builds which generate exceptions.
Defaults to (``failing``, ``passing``, ``warnings``).
``builders``
(list of strings). A list of builder names for which mail should be
sent. Defaults to ``None`` (send mail for all builds). Use either builders
or categories, but not both.
``categories``
(list of strings). A list of category names to serve status
information for. Defaults to ``None`` (all categories). Use either
builders or categories, but not both.
``addLogs``
(boolean). If ``True``, include all build logs as attachments to the
messages. These can be quite large. This can also be set to a list of
log names, to send a subset of the logs. Defaults to ``False``.
``addPatch``
(boolean). If ``True``, include the patch content if a patch was present.
Patches are usually used on a :class:`Try` server.
Defaults to ``True``.
``buildSetSummary``
(boolean). If ``True``, send a single summary email consisting of the
concatenation of all build completion messages rather than a
completion message for each build. Defaults to ``False``.
``relayhost``
(string). The host to which the outbound SMTP connection should be
made. Defaults to 'localhost'
``smtpPort``
(int). The port that will be used on outbound SMTP
connections. Defaults to 25.
``useTls``
(boolean). When this argument is ``True`` (default is ``False``)
``MailNotifier`` sends emails using TLS and authenticates with the
``relayhost``. When using TLS the arguments ``smtpUser`` and
``smtpPassword`` must also be specified.
``smtpUser``
(string). The user name to use when authenticating with the
``relayhost``.
``smtpPassword``
(string). The password that will be used when authenticating with the
``relayhost``.
``lookup``
(implementor of :class:`IEmailLookup`). Object which provides
:class:`IEmailLookup`, which is responsible for mapping User names (which come
from the VC system) into valid email addresses.
If the argument is not provided, the ``MailNotifier`` will attempt to build
the ``sendToInterestedUsers`` from the authors of the Changes that led to
the Build via :ref:`User-Objects`. If the author of one of the Build's
Changes has an email address stored, it will added to the recipients list.
With this method, ``owners`` are still added to the recipients. Note that,
in the current implementation of user objects, email addresses are not
stored; as a result, unless you have specifically added email addresses to
the user database, this functionality is unlikely to actually send any
emails.
Most of the time you can use a simple Domain instance. As a shortcut, you
can pass as string: this will be treated as if you had provided
``Domain(str)``. For example, ``lookup='twistedmatrix.com'`` will allow
mail to be sent to all developers whose SVN usernames match their
twistedmatrix.com account names. See :file:`buildbot/status/mail.py` for
more details.
Regardless of the setting of ``lookup``, ``MailNotifier`` will also send
mail to addresses in the ``extraRecipients`` list.
``messageFormatter``
This is a optional function that can be used to generate a custom mail message.
A :func:`messageFormatter` function takes the mail mode (``mode``), builder
name (``name``), the build status (``build``), the result code
(``results``), and the BuildMaster status (``master_status``). It
returns a dictionary. The ``body`` key gives a string that is the complete
text of the message. The ``type`` key is the message type ('plain' or
'html'). The 'html' type should be used when generating an HTML message. The
``subject`` key is optional, but gives the subject for the email.
``extraHeaders``
(dictionary) A dictionary containing key/value pairs of extra headers to add
to sent e-mails. Both the keys and the values may be a `Interpolate` instance.
``previousBuildGetter``
An optional function to calculate the previous build to the one at hand. A
:func:`previousBuildGetter` takes a :class:`BuildStatus` and returns a
:class:`BuildStatus`. This function is useful when builders don't process
their requests in order of arrival (chronologically) and therefore the order
of completion of builds does not reflect the order in which changes (and
their respective requests) arrived into the system. In such scenarios,
status transitions in the chronological sequence of builds within a builder
might not reflect the actual status transition in the topological sequence
of changes in the tree. What's more, the latest build (the build at hand)
might not always be for the most recent request so it might not make sense
to send a "change" or "problem" email about it. Returning None from this
function will prevent such emails from going out.
As a help to those writing :func:`messageFormatter` functions, the following
table describes how to get some useful pieces of information from the various
status objects:
Name of the builder that generated this event
``name``
Title of the buildmaster
:meth:`master_status.getTitle()`
MailNotifier mode
``mode`` (a combination of ``change``, ``failing``, ``passing``, ``problem``, ``warnings``,
``exception``, ``all``)
Builder result as a string ::
from buildbot.status.builder import Results
result_str = Results[results]
# one of 'success', 'warnings', 'failure', 'skipped', or 'exception'
URL to build page
``master_status.getURLForThing(build)``
URL to buildbot main page.
``master_status.getBuildbotURL()``
Build text
``build.getText()``
Mapping of property names to values
``build.getProperties()`` (a :class:`Properties` instance)
Slave name
``build.getSlavename()``
Build reason (from a forced build)
``build.getReason()``
List of responsible users
``build.getResponsibleUsers()``
Source information (only valid if ss is not ``None``)
A build has a set of sourcestamps::
for ss in build.getSourceStamp():
branch = ss.branch
revision = ss.revision
patch = ss.patch
changes = ss.changes # list
A change object has the following useful information:
``who``
(str) who made this change
``revision``
(str) what VC revision is this change
``branch``
(str) on what branch did this change occur
``when``
(str) when did this change occur
``files``
(list of str) what files were affected in this change
``comments``
(str) comments reguarding the change.
The ``Change`` methods :meth:`asText` and :meth:`asDict` can be used to format the
information above. :meth:`asText` returns a list of strings and :meth:`asDict` returns
a dictionary suitable for html/mail rendering.
Log information ::
logs = list()
for log in build.getLogs():
log_name = "%s.%s" % (log.getStep().getName(), log.getName())
log_status, dummy = log.getStep().getResults()
log_body = log.getText().splitlines() # Note: can be VERY LARGE
log_url = '%s/steps/%s/logs/%s' % (master_status.getURLForThing(build),
log.getStep().getName(),
log.getName())
logs.append((log_name, log_url, log_body, log_status))
.. bb:status:: IRC
.. index:: IRC
IRC Bot
~~~~~~~
.. py:class:: buildbot.status.words.IRC
The :class:`buildbot.status.words.IRC` status target creates an IRC bot
which will attach to certain channels and be available for status
queries. It can also be asked to announce builds as they occur, or be
told to shut up. ::
from buildbot.status import words
irc = words.IRC("irc.example.org", "botnickname",
useColors=False,
channels=[{"channel": "#example1"},
{"channel": "#example2",
"password": "somesecretpassword"}],
password="mysecretnickservpassword",
notify_events={
'exception': 1,
'successToFailure': 1,
'failureToSuccess': 1,
})
c['status'].append(irc)
Take a look at the docstring for :class:`words.IRC` for more details on
configuring this service. Note that the ``useSSL`` option requires
`PyOpenSSL`_. The ``password`` argument, if provided, will be sent to
Nickserv to claim the nickname: some IRC servers will not allow clients to send
private messages until they have logged in with a password. We can also specify
a different ``port`` number. Default value is 6667.
To use the service, you address messages at the buildbot, either
normally (``botnickname: status``) or with private messages
(``/msg botnickname status``). The buildbot will respond in kind.
The bot will add color to some of its messages. This is enabled by default,
you might turn it off with ``useColors=False`` argument to words.IRC().
If you issue a command that is currently not available, the buildbot
will respond with an error message. If the ``noticeOnChannel=True``
option was used, error messages will be sent as channel notices instead
of messaging. The default value is ``noticeOnChannel=False``.
Some of the commands currently available:
``list builders``
Emit a list of all configured builders
:samp:`status {BUILDER}`
Announce the status of a specific Builder: what it is doing right now.
``status all``
Announce the status of all Builders
:samp:`watch {BUILDER}`
If the given :class:`Builder` is currently running, wait until the :class:`Build` is
finished and then announce the results.
:samp:`last {BUILDER}`
Return the results of the last build to run on the given :class:`Builder`.
:samp:`join {CHANNEL}`
Join the given IRC channel
:samp:`leave {CHANNEL}`
Leave the given IRC channel
:samp:`notify on|off|list {EVENT}`
Report events relating to builds. If the command is issued as a
private message, then the report will be sent back as a private
message to the user who issued the command. Otherwise, the report
will be sent to the channel. Available events to be notified are:
``started``
A build has started
``finished``
A build has finished
``success``
A build finished successfully
``failure``
A build failed
``exception``
A build generated and exception
``xToY``
The previous build was x, but this one is Y, where x and Y are each
one of success, warnings, failure, exception (except Y is
capitalized). For example: ``successToFailure`` will notify if the
previous build was successful, but this one failed
:samp:`help {COMMAND}`
Describe a command. Use :command:`help commands` to get a list of known
commands.
:samp:`shutdown {ARG}`
Control the shutdown process of the buildbot master.
Available arguments are:
``check``
Check if the buildbot master is running or shutting down
``start``
Start clean shutdown
``stop``
Stop clean shutdown
``now``
Shutdown immediately without waiting for the builders to finish
``source``
Announce the URL of the Buildbot's home page.
``version``
Announce the version of this Buildbot.
Additionally, the config file may specify default notification options
as shown in the example earlier.
If the ``allowForce=True`` option was used, some additional commands
will be available:
.. index:: Properties; from forced build
:samp:`force build [--branch={BRANCH}] [--revision={REVISION}] [--props=PROP1=VAL1,PROP2=VAL2...] {BUILDER} {REASON}`
Tell the given :class:`Builder` to start a build of the latest code. The user
requesting the build and *REASON* are recorded in the :class:`Build` status. The
buildbot will announce the build's status when it finishes.The
user can specify a branch and/or revision with the optional
parameters :samp:`--branch={BRANCH}` and :samp:`--revision={REVISION}`. The user
can also give a list of properties with :samp:`--props={PROP1=VAL1,PROP2=VAL2..}`.
:samp:`stop build {BUILDER} {REASON}`
Terminate any running build in the given :class:`Builder`. *REASON* will be added
to the build status to explain why it was stopped. You might use this
if you committed a bug, corrected it right away, and don't want to
wait for the first build (which is destined to fail) to complete
before starting the second (hopefully fixed) build.
If the `categories` is set to a category of builders (see the categories
option in :ref:`Builder-Configuration`) changes related to only that
category of builders will be sent to the channel.
If the `useRevisions` option is set to `True`, the IRC bot will send status messages
that replace the build number with a list of revisions that are contained in that
build. So instead of seeing `build #253 of ...`, you would see something like
`build containing revisions [a87b2c4]`. Revisions that are stored as hashes are
shortened to 7 characters in length, as multiple revisions can be contained in one
build and may exceed the IRC message length limit.
Two additional arguments can be set to control how fast the IRC bot tries to
reconnect when it encounters connection issues. ``lostDelay`` is the number of
of seconds the bot will wait to reconnect when the connection is lost, where as
``failedDelay`` is the number of seconds until the bot tries to reconnect when
the connection failed. ``lostDelay`` defaults to a random number between 1 and 5,
while ``failedDelay`` defaults to a random one between 45 and 60. Setting random
defaults like this means multiple IRC bots are less likely to deny each other
by flooding the server.
.. bb:status:: PBListener
PBListener
~~~~~~~~~~
.. @cindex PBListener
.. py:class:: buildbot.status.client.PBListener
::
import buildbot.status.client
pbl = buildbot.status.client.PBListener(port=int, user=str,
passwd=str)
c['status'].append(pbl)
This sets up a PB listener on the given TCP port, to which a PB-based
status client can connect and retrieve status information.
:command:`buildbot statusgui` (:bb:cmdline:`statusgui`) is an example of such a
status client. The ``port`` argument can also be a strports
specification string.
.. bb:status:: StatusPush
StatusPush
~~~~~~~~~~
.. @cindex StatusPush
.. py:class:: buildbot.status.status_push.StatusPush
::
def Process(self):
print str(self.queue.popChunk())
self.queueNextServerPush()
import buildbot.status.status_push
sp = buildbot.status.status_push.StatusPush(serverPushCb=Process,
bufferDelay=0.5,
retryDelay=5)
c['status'].append(sp)
:class:`StatusPush` batches events normally processed and sends it to the
:func:`serverPushCb` callback every ``bufferDelay`` seconds. The callback
should pop items from the queue and then queue the next callback.
If no items were popped from ``self.queue``, ``retryDelay`` seconds will be
waited instead.
.. bb:status:: HttpStatusPush
HttpStatusPush
~~~~~~~~~~~~~~
.. @cindex HttpStatusPush
.. @stindex buildbot.status.status_push.HttpStatusPush
::
import buildbot.status.status_push
sp = buildbot.status.status_push.HttpStatusPush(
serverUrl="http://example.com/submit")
c['status'].append(sp)
:class:`HttpStatusPush` builds on :class:`StatusPush` and sends HTTP requests to
``serverUrl``, with all the items json-encoded. It is useful to create a
status front end outside of buildbot for better scalability.
.. bb:status:: GerritStatusPush
GerritStatusPush
~~~~~~~~~~~~~~~~
.. py:class:: buildbot.status.status_gerrit.GerritStatusPush
:class:`GerritStatusPush` sends review of the :class:`Change` back to the Gerrit server, optionally also sending a message when a build is started.
GerritStatusPush can send a separate review for each build that completes, or a single review summarizing the results for all of the builds.
An example usage::
from buildbot.status.status_gerrit import GerritStatusPush
from buildbot.status.builder import Results, SUCCESS, RETRY
def gerritReviewCB(builderName, build, result, status, arg):
if result == RETRY:
return None, 0, 0
message = "Buildbot finished compiling your patchset\n"
message += "on configuration: %s\n" % builderName
message += "The result is: %s\n" % Results[result].upper()
if arg:
message += "\nFor more details visit:\n"
message += status.getURLForThing(build) + "\n"
# message, verified, reviewed
return message, (result == SUCCESS or -1), 0
def gerritStartCB(builderName, build, arg):
message = "Buildbot started compiling your patchset\n"
message += "on configuration: %s\n" % builderName
return message
def gerritSummaryCB(buildInfoList, results, status, arg):
success = False
failure = False
msgs = []
for buildInfo in buildInfoList:
msg = "Builder %(name)s %(resultText)s (%(text)s)" % buildInfo
link = buildInfo.get('url', None)
if link:
msg += " - " + link
else:
msg += "."
msgs.append(msg)
if buildInfo['result'] == SUCCESS:
success = True
else:
failure = True
msg = '\n\n'.join(msgs)
if success and not failure:
verified = 1
else:
verified = -1
reviewed = 0
return (msg, verified, reviewed)
c['buildbotURL'] = 'http://buildbot.example.com/'
c['status'].append(GerritStatusPush('127.0.0.1', 'buildbot',
reviewCB=gerritReviewCB,
reviewArg=c['buildbotURL'],
startCB=gerritStartCB,
startArg=c['buildbotURL'],
summaryCB=gerritSummaryCB,
summaryArg=c['buildbotURL']))
Parameters:
``server`` (string)
Gerrit SSH server's address to use for push event notifications.
``username`` (string)
Gerrit SSH server's username.
``identity_file`` (string, optional)
Gerrit SSH identity file.
``port`` (int, optional)
Gerrit SSH server's port (default: 29418)
``reviewCB``
If specified, determines the message and score to give when sending a review for each separate build.
It should return a tuple of :samp:`({message}, {verified}, {reviewed})`.
``startCB``
If specified, it should return a message.
This message will be sent to the Gerrit server when each build is started.
``summaryCB``
If specified, determines the message and score to give when sending a single review summarizing all of the builds.
It should return a tuple of :samp:`({message}, {verified}, {reviewed})`.
.. note::
By default, a single summary review is sent; that is, a default :py:func:`summaryCB` is provided, but no :py:func:`reviewCB` or :py:func:`startCB`.
.. seealso::
:file:`master/docs/examples/git_gerrit.cfg` and :file:`master/docs/examples/repo_gerrit.cfg` in the Buildbot distribution provide a full example setup of Git+Gerrit or Repo+Gerrit of :bb:status:`GerritStatusPush`.
.. bb:status:: GitHubStatus
GitHubStatus
~~~~~~~~~~~~
.. @cindex GitHubStatus
.. py:class:: buildbot.status.github.GitHubStatus
::
from buildbot.status.github import GitHubStatus
repoOwner = Interpolate("%(prop:github_repo_owner)s")
repoName = Interpolate("%(prop:github_repo_name)s")
sha = Interpolate("%(src::revision)s")
gs = GitHubStatus(token='githubAPIToken',
repoOwner=repoOwner,
repoName=repoName,
sha=sha,
startDescription='Build started.',
endDescription='Build done.',
)
buildbot_bbtools = BuilderConfig(
name='builder-name',
slavenames=['slave1'],
factory=BuilderFactory(),
properties={
"github_repo_owner": "buildbot",
"github_repo_name": "bbtools",
},
)
c['builders'].append(buildbot_bbtools)
c['status'].append(gs)
:class:`GitHubStatus` publishes a build status using
`GitHub Status API `_.
It requires `txgithub ` package to
allow interaction with GitHub API.
It is configured with at least a GitHub API token, repoOwner and repoName
arguments.
You can create a token from you own
`GitHub - Profile - Applications - Register new application
`_ or use an external tool to
generate one.
`repoOwner`, `repoName` are used to inform the plugin where
to send status for build. This allow using a single :class:`GitHubStatus` for
multiple projects.
`repoOwner`, `repoName` can be passes as a static `string` (for single
project) or :class:`Interpolate` for dynamic substitution in multiple
project.
`sha` argument is use to define the commit SHA for which to send the status.
By default `sha` is defined as: `%(src::revision)s`.
In case any of `repoOwner`, `repoName` or `sha` returns `None`, `False` or
empty string, the plugin will skip sending the status.
You can define custom start and end build messages using the
`startDescription` and `endDescription` optional interpolation arguments.
.. [#] Apparently this is the same way http://buildd.debian.org displays build status
.. [#] It may even be possible to provide SSL access by using a
specification like ``"ssl:12345:privateKey=mykey.pen:certKey=cert.pem"``,
but this is completely untested
.. _PyOpenSSL: http://pyopenssl.sourceforge.net/