def _create_default_generators(self): return [ BuildStartEndStatusGenerator( start_formatter=MessageFormatter(subject=""), end_formatter=MessageFormatter(subject="") ) ]
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()
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
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')
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'), ]
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')), ]
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()
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 __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()
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
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'), ]
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
def _generators(self) -> list[BuildStatusGenerator]: formatter = MessageFormatter(template_type="plain", subject=subject_template) return [BuildStatusGenerator(message_formatter=formatter)]
def _create_default_generators(self): formatter = MessageFormatter(template_type='html', template=DEFAULT_MSG_TEMPLATE) return [BuildStatusGenerator(message_formatter=formatter)]