Beispiel #1
0
    def watchedBuildFinished(self, build):
        builder = yield self.getBuilder(builderid=build['builderid'])

        # only notify about builders we are interested in
        if (self.bot.tags is not None
                and not self.builderMatchesAnyTag(builder.get('tags', []))):
            log.msg('Not notifying for a build that does not match any tags')
            return

        builder_name = builder['name']
        buildnum = build['number']

        if not self.shouldReportBuild(builder_name, buildnum):
            return

        results = self.getResultsDescriptionAndColor(build['results'])
        if self.useRevisions:
            revisions = yield self.getRevisionsForBuild(build)
            r = "Build %s containing revision(s) [%s] is complete: %s" % \
                (builder_name, ','.join(revisions), results[0])
        else:
            r = "Build %s #%d is complete: %s" % \
                (builder_name, buildnum, results[0])

        r += ' [%s]' % maybeColorize(build['state_string'], results[1],
                                     self.useColors)

        r += " - %s" % utils.getURLForBuild(self.master, builder['builderid'],
                                            buildnum)

        self.send(r)
Beispiel #2
0
    def __call__(self, mode, buildername, buildset, build, master, previous_results, blamelist):
        """Generate a buildbot mail message and return a tuple of message text
            and type."""
        ss_list = buildset['sourcestamps']
        results = build['results']

        tpl = self.env.get_template(self.template_name)
        cxt = dict(results=build['results'],
                   mode=mode,
                   buildername=buildername,
                   workername=build['properties'].get(
                       'workername', ["<unknown>"])[0],
                   buildset=buildset,
                   build=build,
                   projects=self.getProjects(ss_list, master),
                   previous_results=previous_results,
                   status_detected=self.getDetectedStatus(
                       mode, results, previous_results),
                   build_url=utils.getURLForBuild(
                       master, build['builder']['builderid'], build['number']),
                   buildbot_url=master.config.buildbotURL,
                   blamelist=blamelist,
                   summary=self.messageSummary(build, results),
                   sourcestamps=self.messageSourceStamps(ss_list)
                   )
        contents = tpl.render(cxt)
        return {'body': contents, 'type': self.template_type}
Beispiel #3
0
    def command_STOP(self, args, **kwargs):
        """stop a running build"""
        args = self.splitArgs(args)
        if len(args) < 3 or args[0] != 'build':
            raise UsageError("Try '" + self.bot.commandPrefix +
                             "stop build _which_ _reason_'.")
        which = args[1]
        reason = ' '.join(args[2:])

        r = f"stopped: by {self.describeUser()}: {reason}"

        # find an in-progress build
        builder = yield self.bot.getBuilder(buildername=which)
        builderid = builder['builderid']
        builds = yield self.bot.getRunningBuilds(builderid)

        if not builds:
            self.send("Sorry, no build is currently running.")
            return

        for bdict in builds:
            num = bdict['number']

            yield self.master.data.control(
                'stop', {'reason': r}, ('builders', builderid, 'builds', num))
            if self.bot.useRevisions:
                revisions = yield self.bot.getRevisionsForBuild(bdict)
                response = f"Build containing revision(s) {','.join(revisions)} interrupted"
            else:
                url = utils.getURLForBuild(self.master, builderid, num)
                response = f"Build [#{num}]({url}) of `{which}` interrupted."
            self.send(response)
Beispiel #4
0
    def watchedBuildFinished(self, build):
        builder = yield self.getBuilder(builderid=build['builderid'])

        # only notify about builders we are interested in
        if (self.bot.tags is not None and
                not self.builderMatchesAnyTag(builder.get('tags', []))):
            log.msg('Not notifying for a build that does not match any tags')
            return

        builder_name = builder['name']
        buildnum = build['number']

        if not self.shouldReportBuild(builder_name, buildnum):
            return

        results = self.getResultsDescriptionAndColor(build['results'])
        if self.useRevisions:
            revisions = yield self.getRevisionsForBuild(build)
            r = "Build %s containing revision(s) [%s] is complete: %s" % \
                (builder_name, ','.join(revisions), results[0])
        else:
            r = "Build %s #%d is complete: %s" % \
                (builder_name, buildnum, results[0])

        r += ' [%s]' % maybeColorize(build['state_string'],
                                     results[1], self.useColors)

        r += " - %s" % utils.getURLForBuild(
                self.master, builder['builderid'], buildnum)

        self.send(r)
Beispiel #5
0
    def formatMessageForBuildResults(self, mode, buildername, buildset, build,
                                     master, previous_results, blamelist):
        """Generate a buildbot mail message and return a dictionary
           containing the message body, type and subject."""
        ss_list = buildset['sourcestamps']
        results = build['results']

        ctx = dict(
            results=build['results'],
            mode=mode,
            buildername=buildername,
            workername=build['properties'].get('workername', ["<unknown>"])[0],
            buildset=buildset,
            build=build,
            projects=self.getProjects(ss_list, master),
            previous_results=previous_results,
            status_detected=self.getDetectedStatus(mode, results,
                                                   previous_results),
            build_url=utils.getURLForBuild(master,
                                           build['builder']['builderid'],
                                           build['number']),
            buildbot_url=master.config.buildbotURL,
            blamelist=blamelist,
            summary=self.messageSummary(build, results),
            sourcestamps=self.messageSourceStamps(ss_list))
        yield self.buildAdditionalContext(master, ctx)
        msgdict = self.renderMessage(ctx)
        defer.returnValue(msgdict)
Beispiel #6
0
    def __call__(self, mode, buildername, buildset, build, master, previous_results, blamelist):
        """Generate a buildbot mail message and return a dictionary
           containing the message body, type and subject."""
        ss_list = buildset['sourcestamps']
        results = build['results']

        ctx = dict(results=build['results'],
                   mode=mode,
                   buildername=buildername,
                   workername=build['properties'].get(
                       'workername', ["<unknown>"])[0],
                   buildset=buildset,
                   build=build,
                   projects=self.getProjects(ss_list, master),
                   previous_results=previous_results,
                   status_detected=self.getDetectedStatus(
                       mode, results, previous_results),
                   build_url=utils.getURLForBuild(
                       master, build['builder']['builderid'], build['number']),
                   buildbot_url=master.config.buildbotURL,
                   blamelist=blamelist,
                   summary=self.messageSummary(build, results),
                   sourcestamps=self.messageSourceStamps(ss_list)
                   )
        ctx.update(self.ctx)
        body = self.body_template.render(ctx)
        email = {'body': body, 'type': self.template_type}
        if self.subject_template is not None:
            email['subject'] = self.subject_template.render(ctx)
        return email
Beispiel #7
0
            def getBuildInfo(build):
                result = build['results']
                resultText = {
                    SUCCESS: "succeeded",
                    FAILURE: "failed",
                    WARNINGS: "completed with warnings",
                    EXCEPTION: "encountered an exception",
                }.get(result, "completed with unknown result %d" % result)

                return {
                    'name':
                    build['builder']['name'],
                    'result':
                    result,
                    'resultText':
                    resultText,
                    'text':
                    build['state_string'],
                    'url':
                    utils.getURLForBuild(self.master,
                                         build['builder']['builderid'],
                                         build['number']),
                    'build':
                    build
                }
Beispiel #8
0
def create_context_for_build(mode, buildername, build, master, blamelist):
    buildset = build['buildset']
    ss_list = buildset['sourcestamps']
    results = build['results']

    if 'prev_build' in build and build['prev_build'] is not None:
        previous_results = build['prev_build']['results']
    else:
        previous_results = None

    return {
        'results': build['results'],
        'mode': mode,
        'buildername': buildername,
        'workername': build['properties'].get('workername', ["<unknown>"])[0],
        'buildset': buildset,
        'build': build,
        'projects': get_projects_text(ss_list, master),
        'previous_results': previous_results,
        'status_detected': get_detected_status_text(mode, results, previous_results),
        'build_url': utils.getURLForBuild(master, build['builder']['builderid'], build['number']),
        'buildbot_url': master.config.buildbotURL,
        'blamelist': blamelist,
        'summary': get_message_summary_text(build, results),
        'sourcestamps': get_message_source_stamp_text(ss_list)
    }
Beispiel #9
0
    def formatMessageForBuildResults(self, mode, buildername, buildset, build, master, previous_results, blamelist):
        """Generate a buildbot mail message and return a dictionary
           containing the message body, type and subject."""
        ss_list = buildset['sourcestamps']
        results = build['results']

        ctx = dict(results=build['results'],
                   mode=mode,
                   buildername=buildername,
                   workername=build['properties'].get(
                       'workername', ["<unknown>"])[0],
                   buildset=buildset,
                   build=build,
                   projects=self.getProjects(ss_list, master),
                   previous_results=previous_results,
                   status_detected=self.getDetectedStatus(
                       mode, results, previous_results),
                   build_url=utils.getURLForBuild(
                       master, build['builder']['builderid'], build['number']),
                   buildbot_url=master.config.buildbotURL,
                   blamelist=blamelist,
                   summary=self.messageSummary(build, results),
                   sourcestamps=self.messageSourceStamps(ss_list)
                   )
        yield self.buildAdditionalContext(master, ctx)
        msgdict = self.renderMessage(ctx)
        defer.returnValue(msgdict)
Beispiel #10
0
    def buildStarted(self, build):
        builder = yield self.bot.getBuilder(builderid=build['builderid'])
        builderName = builder['name']
        buildNumber = build['number']
        log.msg(f"[Contact] Builder {builder['name']} started")

        # only notify about builders we are interested in
        if (self.bot.tags is not None
                and not self.builderMatchesAnyTag(builder.get('tags', []))):
            log.msg('Not notifying for a build that does not match any tags')
            return

        if not self.notify_for('started'):
            return

        if self.useRevisions:
            revisions = yield self.getRevisionsForBuild(build)
            r = f"Build containing revision(s) {','.join(revisions)} on {builderName} started"
        else:
            # Abbreviate long lists of changes to simply two
            # revisions, and the number of additional changes.
            # TODO: We can't get the list of the changes related to a build in
            # nine
            changes_str = ""

            url = utils.getURLForBuild(self.master, builder['builderid'],
                                       build['number'])
            r = f"Build [#{buildNumber}]({url}) of `{builderName}` started"
            if changes_str:
                r += f" ({changes_str})"

        self.send(r + ".")
Beispiel #11
0
    def __call__(self, mode, buildername, buildset, build, master,
                 previous_results, blamelist):
        """Generate a buildbot mail message and return a tuple of message text
            and type."""
        ss_list = buildset['sourcestamps']
        results = build['results']

        tpl = self.env.get_template(self.template_name)
        cxt = dict(
            results=build['results'],
            mode=mode,
            buildername=buildername,
            slavename=build['properties'].get('slavename', ["<unknown>"])[0],
            buildset=buildset,
            build=build,
            projects=self.getProjects(ss_list, master),
            previous_results=previous_results,
            status_detected=self.getDetectedStatus(mode, results,
                                                   previous_results),
            build_url=utils.getURLForBuild(master,
                                           build['builder']['builderid'],
                                           build['number']),
            buildbot_url=master.config.buildbotURL,
            blamelist=blamelist,
            summary=self.messageSummary(build, results),
            sourcestamps=self.messageSourceStamps(ss_list))
        contents = tpl.render(cxt)
        return {'body': contents, 'type': 'plain'}
Beispiel #12
0
 def buildComplete(self, key, build):
     if self.reviewCB is None:
         return
     br = yield self.master.data.get(("buildrequests", build['buildrequestid']))
     buildset = yield self.master.data.get(("buildsets", br['buildsetid']))
     yield utils.getDetailsForBuilds(self.master, buildset, [build])
     build['url'] = utils.getURLForBuild(self.master, build['builder']['builderid'], build['number'])
     self.buildFinished(build['builder']['name'], build, build['results'])
Beispiel #13
0
 def buildComplete(self, key, build):
     if self.reviewCB is None:
         return
     br = yield self.master.data.get(("buildrequests", build["buildrequestid"]))
     buildset = yield self.master.data.get(("buildsets", br["buildsetid"]))
     yield utils.getDetailsForBuilds(self.master, buildset, [build])
     build["url"] = utils.getURLForBuild(self.master, build["builder"]["builderid"], build["number"])
     if self.isBuildReported(build):
         self.buildFinished(build["builder"]["name"], build, build["results"])
Beispiel #14
0
 def default_context(self, build, master=None):
     props = build['properties']
     context = {
         'build': build,
         'revision': props.get('revision', ['unknown'])[0],
         'worker_name': props.get('workername', ['unknown'])[0],
         'builder_name': props.get('buildername', ['unknown'])[0],
         'buildbot_url': master.config.buildbotURL,
         'build_id': build['buildid'],
         'build_url': utils.getURLForBuild(
             master, build['builder']['builderid'], build['number']
         )
     }
     return toolz.merge(context, self.context)
Beispiel #15
0
            def getBuildInfo(build):
                result = build['results']
                resultText = {
                    SUCCESS: "succeeded",
                    FAILURE: "failed",
                    WARNINGS: "completed with warnings",
                    EXCEPTION: "encountered an exception",
                }.get(result, "completed with unknown result %d" % result)

                return {'name': build['builder']['name'],
                        'result': result,
                        'resultText': resultText,
                        'text': build['state_string'],
                        'url': utils.getURLForBuild(self.master, build['builder']['builderid'], build['number'])
                        }
Beispiel #16
0
    def getBuildStatus(self, which, short=False):
        response = f'`{which}`: '

        builder = yield self.getBuilder(buildername=which)
        builderid = builder['builderid']
        runningBuilds = yield self.getRunningBuilds(builderid)

        # pylint: disable=too-many-nested-blocks
        if not runningBuilds:
            onlineBuilders = yield self.getOnlineBuilders()
            if builderid in onlineBuilders:
                response += self.idle_string
                lastBuild = yield self.getLastCompletedBuild(builderid)
                if lastBuild:
                    complete_at = lastBuild['complete_at']
                    if complete_at:
                        complete_at = util.datetime2epoch(complete_at)
                        ago = util.fuzzyInterval(
                            int(reactor.seconds() - complete_at))
                    else:
                        ago = "??"
                    status = self.format_build_status(lastBuild, short=short)
                    if not short:
                        status = ", " + status
                        if lastBuild['results'] != SUCCESS:
                            status_string = lastBuild.get('status_string')
                            if status_string:
                                status += ": " + status_string
                    response += f'  last build {ago} ago{status}'
            else:
                response += self.offline_string
        else:
            response += self.running_string
            buildInfo = []
            for build in runningBuilds:
                step = yield self.getCurrentBuildstep(build)
                if step:
                    s = f"({step[-1]['state_string']})"
                else:
                    s = "(no current step)"
                bnum = build['number']
                url = utils.getURLForBuild(self.master, builderid, bnum)
                buildInfo.append(f"build [#{bnum}]({url}) {s}")

            response += ' ' + ', '.join(buildInfo)

        return response
Beispiel #17
0
            def getBuildInfo(build):
                result = build["results"]
                resultText = {
                    SUCCESS: "succeeded",
                    FAILURE: "failed",
                    WARNINGS: "completed with warnings",
                    EXCEPTION: "encountered an exception",
                }.get(result, "completed with unknown result %d" % result)

                return {
                    "name": build["builder"]["name"],
                    "result": result,
                    "resultText": resultText,
                    "text": build["state_string"],
                    "url": utils.getURLForBuild(self.master, build["builder"]["builderid"], build["number"]),
                    "build": build,
                }
Beispiel #18
0
 def getBuildInfo(build):
     if build:
         buildId = build[0]['buildid']
         return master.data.get(
             ("builds", buildId, 'properties')).addCallback(
                 lambda properties: {
                     'buildId':
                     buildId,
                     'name': (properties.get('virtual_builder_name') or
                              properties.get('buildername'))[0],
                     'build_url':
                     utils.getURLForBuild(master, build[0]['builderid'],
                                          build[0]['number']),
                     'results':
                     build[0]['results'],
                     'properties':
                     properties
                 })
    def formatMessageForBuildResults(self, mode, buildername, buildset, build,
                                     master, previous_build, blamelist):
        ctx = dict(
            mode=mode,
            buildername=buildername,
            workername=build["properties"].get("workername", ["<unknown>"])[0],
            buildset=buildset,
            build=build,
            previous_build=previous_build,
            build_url=utils.getURLForBuild(master,
                                           build["builder"]["builderid"],
                                           build["number"]),
            buildbot_url=master.config.buildbotURL,
            blamelist=blamelist,
        )

        yield self.buildAdditionalContext(master, ctx)
        msgdict = self.renderMessage(ctx)
        return msgdict
Beispiel #20
0
    def command_WATCH(self, args, **kwargs):
        """announce the completion of an active build"""
        args = self.splitArgs(args)
        if len(args) != 1:
            raise UsageError("Try '" + self.bot.commandPrefix +
                             "watch _builder_'.")

        which = args[0]
        builder = yield self.bot.getBuilder(buildername=which)

        # Get current builds on this builder.
        builds = yield self.bot.getRunningBuilds(builder['builderid'])
        if not builds:
            self.send("There are no currently running builds.")
            return

        def watchForCompleteEvent(key, msg):
            if key[-1] in ('finished', 'complete'):
                return self.channel.buildFinished(msg, watched=True)
            return None

        for build in builds:
            startConsuming = self.master.mq.startConsuming
            handle = yield startConsuming(
                watchForCompleteEvent, ('builds', str(build['buildid']), None))
            self.channel.build_subscriptions.append((build['buildid'], handle))

            url = utils.getURLForBuild(self.master, builder['builderid'],
                                       build['number'])

            if self.bot.useRevisions:
                revisions = yield self.bot.getRevisionsForBuild(build)
                r = (f"Watching build on `{which}` containing revision(s) "
                     f"{','.join(revisions)} until it finishes...")
            else:
                r = f"Watching build [#{build['number']}]({url}) of `{which}` until it finishes..."

            self.send(r)
Beispiel #21
0
    def buildFinished(self, build, watched=False):
        builder = yield self.bot.getBuilder(builderid=build['builderid'])
        builderName = builder['name']
        buildNumber = build['number']

        # only notify about builders we are interested in
        if (self.bot.tags is not None and
                not self.bot.builderMatchesAnyTag(builder.get('tags', []))):
            log.msg('Not notifying for a build that does not match any tags')
            return

        if not (watched or (yield self.notify_for_finished(build))):
            return

        if not self.shouldReportBuild(builderName, buildNumber):
            return

        url = utils.getURLForBuild(self.master, builder['builderid'],
                                   buildNumber)

        if self.useRevisions:
            revisions = yield self.getRevisionsForBuild(build)
            r = (
                f"Build on `{builderName}` containing revision(s) {','.join(revisions)} "
                f"{self.bot.format_build_status(build)}")
        else:
            r = (f"Build [#{buildNumber}]({url}) of `{builderName}` "
                 f"{self.bot.format_build_status(build)}")
        s = build.get('status_string')
        if build['results'] != SUCCESS and s is not None:
            r += ": " + s
        else:
            r += "."

        # FIXME: where do we get the list of changes for a build ?
        # if self.bot.showBlameList and buildResult != SUCCESS and len(build.changes) != 0:
        #    r += '  blamelist: ' + ', '.join(list(set([c.who for c in build.changes])))
        self.send(r)
Beispiel #22
0
 def addBuildUrls(self, rclist):
     brids = {}
     for was_cb, results in rclist:
         if isinstance(results, tuple):
             results, brids = results
         builderNames = {}
         if was_cb:  # errors were already logged in worstStatus
             for builderid, br in brids.items():
                 builds = yield self.master.db.builds.getBuilds(
                     buildrequestid=br)
                 for build in builds:
                     builderid = build['builderid']
                     # When virtual builders are used, the builderid used for triggering
                     # is not the same as the one that the build actually got
                     if builderid not in builderNames:
                         builderDict = yield self.master.data.get(
                             ("builders", builderid))
                         builderNames[builderid] = builderDict["name"]
                     num = build['number']
                     url = getURLForBuild(self.master, builderid, num)
                     yield self.addURL(
                         f'{statusToString(build["results"])}: '
                         f'{builderNames[builderid]} #{num}', url)
Beispiel #23
0
    def buildFinished(self, build):
        builder = yield self.getBuilder(builderid=build['builderid'])
        builderName = builder['name']
        buildNumber = build['number']
        buildResult = build['results']

        # only notify about builders we are interested in
        if (self.bot.tags is not None
                and not self.builderMatchesAnyTag(builder.get('tags', []))):
            log.msg('Not notifying for a build that does not match any tags')
            return

        if not (yield self.notify_for_finished(build)):
            return

        if not self.shouldReportBuild(builderName, buildNumber):
            return

        results = self.getResultsDescriptionAndColor(buildResult)

        if self.useRevisions:
            revisions = yield self.getRevisionsForBuild(build)
            r = "Build %s containing revision(s) [%s] is complete: %s" % \
                (builderName, ','.join(revisions), results[0])
        else:
            r = "Build %s #%d is complete: %s" % \
                (builderName, buildNumber, results[0])

        r += ' [%s]' % maybeColorize(build['state_string'], results[1],
                                     self.useColors)

        # FIXME: where do we get the list of changes for a build ?
        # if self.bot.showBlameList and buildResult != SUCCESS and len(build.changes) != 0:
        #    r += '  blamelist: ' + ', '.join(list(set([c.who for c in build.changes])))
        r += " - %s" % utils.getURLForBuild(self.master, builder['builderid'],
                                            buildNumber)
        self.send(r)
Beispiel #24
0
    def buildFinished(self, build):
        builder = yield self.getBuilder(builderid=build['builderid'])
        builderName = builder['name']
        buildNumber = build['number']
        buildResult = build['results']

        # only notify about builders we are interested in
        if (self.bot.tags is not None and
                not self.builderMatchesAnyTag(builder.get('tags', []))):
            log.msg('Not notifying for a build that does not match any tags')
            return

        if not (yield self.notify_for_finished(build)):
            return

        if not self.shouldReportBuild(builderName, buildNumber):
            return

        results = self.getResultsDescriptionAndColor(buildResult)

        if self.useRevisions:
            revisions = yield self.getRevisionsForBuild(build)
            r = "Build %s containing revision(s) [%s] is complete: %s" % \
                (builderName, ','.join(revisions), results[0])
        else:
            r = "Build %s #%d is complete: %s" % \
                (builderName, buildNumber, results[0])

        r += ' [%s]' % maybeColorize(build['state_string'],
                                     results[1], self.useColors)

        # FIXME: where do we get the list of changes for a build ?
        # if self.bot.showBlameList and buildResult != SUCCESS and len(build.changes) != 0:
        #    r += '  blamelist: ' + ', '.join(list(set([c.who for c in build.changes])))
        r += " - %s" % utils.getURLForBuild(
                        self.master, builder['builderid'], buildNumber)
        self.send(r)
 def test_UrlForBuild(self):
     self.assertEqual(utils.getURLForBuild(self.master, 1, 3),
                      'http://localhost:8080/#builders/1/builds/3')
Beispiel #26
0
 def getUrl(self):
     builder_id = yield self.getBuilderId()
     return getURLForBuild(self.master, builder_id, self.number)
Beispiel #27
0
 def test_UrlForBuild(self):
     self.assertEqual(utils.getURLForBuild(self.master, 1, 3),
                      'http://localhost:8080/#builders/1/builds/3')
Beispiel #28
0
 def getUrl(self):
     builder_id = yield self.builder.getBuilderId()
     defer.returnValue(getURLForBuild(self.master, builder_id, self.number))
Beispiel #29
0
 def getUrl(self):
     builder_id = yield self.getBuilderId()
     return getURLForBuild(self.master, builder_id, self.number)