Example #1
0
 def _create_default_generators(self):
     return [
         BuildStartEndStatusGenerator(
             start_formatter=MessageFormatter(subject=""),
             end_formatter=MessageFormatter(subject="")
         )
     ]
Example #2
0
    def setUp(self):
        self.setup_test_reactor()

        self.setup_reporter_test()
        self.reporter_test_repo = 'https://example.org/user/repo'

        self.master = fakemaster.make_master(self,
                                             wantData=True,
                                             wantDb=True,
                                             wantMq=True)

        self._http = yield fakehttpclientservice.HTTPClientService.getService(
            self.master, self, _BASE_URL, debug=None, verify=None)
        self.oauthhttp = yield fakehttpclientservice.HTTPClientService.getService(
            self.master,
            self,
            _OAUTH_URL,
            auth=('key', 'secret'),
            debug=None,
            verify=None)
        self.bsp = BitbucketStatusPush(
            Interpolate('key'),
            Interpolate('secret'),
            status_key=Interpolate(
                "%(prop:buildername)s/%(prop:buildnumber)s"),
            status_name=Interpolate(
                "%(prop:buildername)s-%(prop:buildnumber)s"),
            generators=[
                BuildStartEndStatusGenerator(
                    start_formatter=MessageFormatter(
                        subject="{{ status_detected }}"),
                    end_formatter=MessageFormatter(subject="{{ summary }}"))
            ])
        yield self.bsp.setServiceParent(self.master)
        yield self.bsp.startService()
Example #3
0
def masterConfig():
    c = {}
    from buildbot.config import BuilderConfig
    from buildbot.process.factory import BuildFactory
    from buildbot.plugins import steps, schedulers, reporters
    c['schedulers'] = [
        schedulers.AnyBranchScheduler(name="sched", builderNames=["testy"])
    ]
    f = BuildFactory()
    f.addStep(steps.ShellCommand(command='echo hello'))
    c['builders'] = [
        BuilderConfig(name="testy", workernames=["local1"], factory=f)
    ]
    notifier = reporters.PushoverNotifier(
        '1234',
        'abcd',
        mode="all",
        watchedWorkers=['local1'],
        messageFormatter=MessageFormatter(template='This is a message.'),
        messageFormatterMissingWorker=MessageFormatterMissingWorker(
            template='No worker.'))
    c['services'] = [
        reporters.MailNotifier("*****@*****.**", mode="all"), notifier
    ]
    return c
Example #4
0
 def test_notifiy_for_buildset(self):
     self.master.config.services = [
         MailNotifier("*****@*****.**", mode="all", buildSetSummary=True),
         PushoverNotifier('1234', 'abcd', mode="all", buildSetSummary=True,
             messageFormatter=MessageFormatter(template='This is a message.'))]
     yield self.master.reconfigServiceWithBuildbotConfig(self.master.config)
     yield self.doTest('whole buildset')
Example #5
0
    def __init__(self,
                 mode=("failing", "passing", "warnings"),
                 tags=None,
                 builders=None,
                 schedulers=None,
                 branches=None,
                 subject="Buildbot %(result)s in %(title)s on %(builder)s",
                 add_logs=False,
                 add_patch=False,
                 report_new=False,
                 message_formatter=None,
                 _want_previous_build=None):
        super().__init__(mode, tags, builders, schedulers, branches, subject,
                         add_logs, add_patch)
        self.formatter = message_formatter
        if self.formatter is None:
            self.formatter = MessageFormatter()

        # TODO: private and deprecated, included only to support HttpStatusPushBase
        self._want_previous_build_override = _want_previous_build

        if report_new:
            self.wanted_event_keys = [
                ('builds', None, 'finished'),
                ('builds', None, 'new'),
            ]
Example #6
0
 def _create_default_generators(self):
     return [
         BuildStatusGenerator(
             add_patch=True,
             message_formatter=MessageFormatter(template_type='html')),
         WorkerMissingGenerator(
             workers='all',
             message_formatter=MessageFormatterMissingWorker(template_type='html')),
     ]
Example #7
0
    def __init__(self, mode=("failing", "passing", "warnings"),
                 tags=None, builders=None, schedulers=None, branches=None,
                 subject=None, add_logs=False, add_patch=False, message_formatter=None):
        if subject is not None:
            warn_deprecated('3.5.0', 'BuildSetStatusGenerator subject parameter has been ' +
                            'deprecated: please configure subject in the message formatter')
        else:
            subject = "Buildbot %(result)s in %(title)s on %(builder)s"

        super().__init__(mode, tags, builders, schedulers, branches, subject, add_logs, add_patch)
        self.formatter = message_formatter
        if self.formatter is None:
            self.formatter = MessageFormatter()
Example #8
0
    def __init__(self, mode, tags, builders, schedulers, branches, subject,
                 add_logs, add_patch, message_formatter):
        self.mode = self._compute_shortcut_modes(mode)

        self.tags = tags
        self.builders = builders
        self.schedulers = schedulers
        self.branches = branches
        self.subject = subject
        self.add_logs = add_logs
        self.add_patch = add_patch
        self.formatter = message_formatter
        if self.formatter is None:
            self.formatter = DefaultMessageFormatter()
Example #9
0
 def __init__(self,
              mode=("failing", "passing", "warnings"),
              tags=None,
              builders=None,
              schedulers=None,
              branches=None,
              subject="Buildbot %(result)s in %(title)s on %(builder)s",
              add_logs=False,
              add_patch=False,
              message_formatter=None):
     super().__init__(mode, tags, builders, schedulers, branches, subject,
                      add_logs, add_patch)
     self.formatter = message_formatter
     if self.formatter is None:
         self.formatter = MessageFormatter()
Example #10
0
def masterConfig(build_set_summary):
    c = {}
    from buildbot.config import BuilderConfig
    from buildbot.process.factory import BuildFactory
    from buildbot.plugins import steps, schedulers, reporters
    c['schedulers'] = [
        schedulers.AnyBranchScheduler(
            name="sched",
            builderNames=["testy"])
    ]
    f = BuildFactory()
    f.addStep(steps.ShellCommand(command='echo hello'))
    c['builders'] = [
        BuilderConfig(name="testy",
                      workernames=["local1"],
                      factory=f)
    ]

    formatter = MessageFormatter(template='This is a message.')
    formatter_worker = MessageFormatterMissingWorker(template='No worker.')

    if build_set_summary:
        generators_mail = [
            BuildSetStatusGenerator(mode='all'),
            WorkerMissingGenerator(workers='all'),
        ]
        generators_pushover = [
            BuildSetStatusGenerator(mode='all', message_formatter=formatter),
            WorkerMissingGenerator(workers=['local1'], message_formatter=formatter_worker),
        ]
    else:
        generators_mail = [
            BuildStatusGenerator(mode='all'),
            WorkerMissingGenerator(workers='all'),
        ]
        generators_pushover = [
            BuildStatusGenerator(mode='all', message_formatter=formatter),
            WorkerMissingGenerator(workers=['local1'], message_formatter=formatter_worker),
        ]

    c['services'] = [
        reporters.MailNotifier("*****@*****.**", generators=generators_mail),
        reporters.PushoverNotifier('1234', 'abcd', generators=generators_pushover)
    ]
    return c
Example #11
0
    def __init__(self,
                 mode=("failing", "passing", "warnings"),
                 tags=None,
                 builders=None,
                 schedulers=None,
                 branches=None,
                 subject="Buildbot %(result)s in %(title)s on %(builder)s",
                 add_logs=False,
                 add_patch=False,
                 report_new=False,
                 message_formatter=None):
        super().__init__(mode, tags, builders, schedulers, branches, subject,
                         add_logs, add_patch)
        self.formatter = message_formatter
        if self.formatter is None:
            self.formatter = MessageFormatter()

        if report_new:
            self.wanted_event_keys = [
                ('builds', None, 'finished'),
                ('builds', None, 'new'),
            ]
Example #12
0
class BuildStatusGeneratorMixin:

    possible_modes = ("change", "failing", "passing", "problem", "warnings",
                      "exception", "cancelled")

    def __init__(self, mode, tags, builders, schedulers, branches, subject,
                 add_logs, add_patch, message_formatter):
        self.mode = self._compute_shortcut_modes(mode)

        self.tags = tags
        self.builders = builders
        self.schedulers = schedulers
        self.branches = branches
        self.subject = subject
        self.add_logs = add_logs
        self.add_patch = add_patch
        self.formatter = message_formatter
        if self.formatter is None:
            self.formatter = DefaultMessageFormatter()

    def check(self):
        self._verify_build_generator_mode(self.mode)

        if '\n' in self.subject:
            config.error('Newlines are not allowed in message subjects')

        # you should either limit on builders or tags, not both
        if self.builders is not None and self.tags is not None:
            config.error(
                "Please specify only builders or tags to include - not both.")

    def generate_name(self):
        name = self.__class__.__name__
        if self.tags is not None:
            name += "_tags_" + "+".join(self.tags)
        if self.builders is not None:
            name += "_builders_" + "+".join(self.builders)
        if self.schedulers is not None:
            name += "_schedulers_" + "+".join(self.schedulers)
        if self.branches is not None:
            name += "_branches_" + "+".join(self.branches)
        name += "_".join(self.mode)
        return name

    def _should_attach_log(self, log):
        if isinstance(self.add_logs, bool):
            return self.add_logs

        if log['name'] in self.add_logs:
            return True

        long_name = "{}.{}".format(log['stepname'], log['name'])
        if long_name in self.add_logs:
            return True

        return False

    def is_message_needed(self, build):
        # here is where we actually do something.
        builder = build['builder']
        scheduler = build['properties'].get('scheduler', [None])[0]
        branch = build['properties'].get('branch', [None])[0]
        results = build['results']

        if self.builders is not None and builder['name'] not in self.builders:
            return False  # ignore this build
        if self.schedulers is not None and scheduler not in self.schedulers:
            return False  # ignore this build
        if self.branches is not None and branch not in self.branches:
            return False  # ignore this build
        if self.tags is not None and not self._matches_any_tag(
                builder['tags']):
            return False  # ignore this build

        if "change" in self.mode:
            prev = build['prev_build']
            if prev and prev['results'] != results:
                return True
        if "failing" in self.mode and results == FAILURE:
            return True
        if "passing" in self.mode and results == SUCCESS:
            return True
        if "problem" in self.mode and results == FAILURE:
            prev = build['prev_build']
            if prev and prev['results'] != FAILURE:
                return True
        if "warnings" in self.mode and results == WARNINGS:
            return True
        if "exception" in self.mode and results == EXCEPTION:
            return True
        if "cancelled" in self.mode and results == CANCELLED:
            return True

        return False

    @defer.inlineCallbacks
    def build_message(self, master, reporter, name, builds, results):
        patches = []
        logs = []
        body = ""
        subject = None
        msgtype = None
        users = set()
        for build in builds:
            if self.add_patch:
                ss_list = build['buildset']['sourcestamps']

                for ss in ss_list:
                    if 'patch' in ss and ss['patch'] is not None:
                        patches.append(ss['patch'])

            if self.add_logs:
                build_logs = yield self._get_logs_for_build(master, build)
                if isinstance(self.add_logs, list):
                    build_logs = [
                        log for log in build_logs
                        if self._should_attach_log(log)
                    ]
                logs.extend(build_logs)

            if 'prev_build' in build and build['prev_build'] is not None:
                previous_results = build['prev_build']['results']
            else:
                previous_results = None
            blamelist = yield reporter.getResponsibleUsersForBuild(
                master, build['buildid'])
            buildmsg = yield self.formatter.formatMessageForBuildResults(
                self.mode, name, build['buildset'], build, master,
                previous_results, blamelist)
            users.update(set(blamelist))
            msgtype = buildmsg['type']
            body += buildmsg['body']
            if 'subject' in buildmsg:
                subject = buildmsg['subject']

        if subject is None:
            subject = self.subject % {
                'result': Results[results],
                'projectName': master.config.title,
                'title': master.config.title,
                'builder': name
            }

        return {
            'body': body,
            'subject': subject,
            'type': msgtype,
            'builder_name': name,
            'results': results,
            'builds': builds,
            'users': list(users),
            'patches': patches,
            'logs': logs
        }

    @defer.inlineCallbacks
    def _get_logs_for_build(self, master, build):
        all_logs = []
        steps = yield master.data.get(('builds', build['buildid'], "steps"))
        for step in steps:
            logs = yield master.data.get(("steps", step['stepid'], 'logs'))
            for l in logs:
                l['stepname'] = step['name']
                l['content'] = yield master.data.get(
                    ("logs", l['logid'], 'contents'))
                all_logs.append(l)
        return all_logs

    def _verify_build_generator_mode(self, mode):
        for m in self._compute_shortcut_modes(mode):
            if m not in self.possible_modes:
                if m == "all":
                    config.error(
                        "mode 'all' is not valid in an iterator and must be "
                        "passed in as a separate string")
                else:
                    config.error("mode {} is not a valid mode".format(m))

    def _compute_shortcut_modes(self, mode):
        if isinstance(mode, str):
            if mode == "all":
                mode = ("failing", "passing", "warnings", "exception",
                        "cancelled")
            elif mode == "warnings":
                mode = ("failing", "warnings")
            else:
                mode = (mode, )
        return mode
Example #13
0
 def _generators(self) -> list[BuildStatusGenerator]:
     formatter = MessageFormatter(template_type="plain",
                                  subject=subject_template)
     return [BuildStatusGenerator(message_formatter=formatter)]
Example #14
0
 def _create_default_generators(self):
     formatter = MessageFormatter(template_type='html', template=DEFAULT_MSG_TEMPLATE)
     return [BuildStatusGenerator(message_formatter=formatter)]