def send_change(branch, old_revno, old_revid, new_revno, new_revid, hook): config = branch.get_config() server = config.get_user_option(SERVER_KEY) if not server: bzrlib.trace.warning( 'bzr_buildbot: ERROR. If %s is set, %s must be set', HOOK_KEY, SERVER_KEY) return change = generate_change( branch, old_revno, old_revid, new_revno, new_revid, blame_merge_author=_is_true(config, PQM_KEY)) if _is_true(config, SEND_BRANCHNAME_KEY): change['branch'] = branch.nick # as of this writing (in Buildbot 0.7.9), 9989 is the default port when # you make a buildbot master. port = int(config.get_user_option(PORT_KEY) or 9989) # if dry run, stop. if _is_true(config, DRYRUN_KEY): bzrlib.trace.note("bzr_buildbot DRY RUN " "(*not* sending changes to %s:%d on %s)", server, port, hook) keys = change.keys() keys.sort() for k in keys: bzrlib.trace.note("[%10s]: %s", k, change[k]) return # We instantiate our own reactor so that this can run within a server. reactor = twisted.internet.selectreactor.SelectReactor() # See other reference to http://twistedmatrix.com/trac/ticket/3591 # above. This line can go away with a release of Twisted that addresses # this issue. reactor.resolver = ThreadedResolver(reactor) pbcf = twisted.spread.pb.PBClientFactory() reactor.connectTCP(server, port, pbcf) deferred = pbcf.login( twisted.cred.credentials.UsernamePassword('change', 'changepw')) def sendChanges(remote): """Send changes to buildbot.""" bzrlib.trace.mutter("bzrbuildout sending changes: %s", change) change['src'] = 'bzr' return remote.callRemote('addChange', change) deferred.addCallback(sendChanges) def quit(ignore, msg): bzrlib.trace.note("bzrbuildout: %s", msg) reactor.stop() def failed(failure): bzrlib.trace.warning("bzrbuildout: FAILURE\n %s", failure) reactor.stop() deferred.addCallback(quit, "SUCCESS") deferred.addErrback(failed) reactor.callLater(60, quit, None, "TIMEOUT") bzrlib.trace.note( "bzr_buildbot: SENDING CHANGES to buildbot master %s:%d on %s", server, port, hook) reactor.run(installSignalHandlers=False) # run in a thread when in server
def _installed_hook(branch): value = branch.get_config().get_user_option(HOOK_KEY) if value is not None: value = value.strip().lower() if value not in (PUSH_VALUE, COMMIT_VALUE, CHANGE_VALUE): raise bzrlib.errors.BzrError( '%s, if set, must be one of %s, %s, or %s' % (HOOK_KEY, PUSH_VALUE, COMMIT_VALUE, CHANGE_VALUE)) return value
def _installed_hook(branch): value = branch.get_config().get_user_option(HOOK_KEY) if value is not None: value = value.strip().lower() if value not in (PUSH_VALUE, COMMIT_VALUE, CHANGE_VALUE): raise bzrlib.errors.BzrError( '%s, if set, must be one of %s, %s, or %s' % ( HOOK_KEY, PUSH_VALUE, COMMIT_VALUE, CHANGE_VALUE)) return value
def send_change(branch, old_revno, old_revid, new_revno, new_revid, hook): config = branch.get_config() server = config.get_user_option(SERVER_KEY) if not server: bzrlib.trace.warning( 'bzr_buildbot: ERROR. If %s is set, %s must be set', HOOK_KEY, SERVER_KEY) return change = generate_change(branch, old_revno, old_revid, new_revno, new_revid, blame_merge_author=_is_true(config, PQM_KEY)) if _is_true(config, SEND_BRANCHNAME_KEY): change['branch'] = branch.nick # as of this writing (in Buildbot 0.7.9), 9989 is the default port when # you make a buildbot master. port = int(config.get_user_option(PORT_KEY) or 9989) # if dry run, stop. if _is_true(config, DRYRUN_KEY): bzrlib.trace.note( "bzr_buildbot DRY RUN " "(*not* sending changes to %s:%d on %s)", server, port, hook) keys = sorted(change.keys()) for k in keys: bzrlib.trace.note("[%10s]: %s", k, change[k]) return # We instantiate our own reactor so that this can run within a server. reactor = twisted.internet.selectreactor.SelectReactor() # See other reference to http://twistedmatrix.com/trac/ticket/3591 # above. This line can go away with a release of Twisted that addresses # this issue. reactor.resolver = ThreadedResolver(reactor) pbcf = twisted.spread.pb.PBClientFactory() reactor.connectTCP(server, port, pbcf) auth = config.get_user_option(AUTH_KEY) if auth: user, passwd = [s.strip() for s in auth.split(':', 1)] else: user, passwd = ('change', 'changepw') deferred = pbcf.login( twisted.cred.credentials.UsernamePassword(user, passwd)) def sendChanges(remote): """Send changes to buildbot.""" bzrlib.trace.mutter("bzrbuildout sending changes: %s", change) change['src'] = 'bzr' return remote.callRemote('addChange', change) deferred.addCallback(sendChanges) def quit(ignore, msg): bzrlib.trace.note("bzrbuildout: %s", msg) reactor.stop() def failed(failure): bzrlib.trace.warning("bzrbuildout: FAILURE\n %s", failure) reactor.stop() deferred.addCallback(quit, "SUCCESS") deferred.addErrback(failed) reactor.callLater(60, quit, None, "TIMEOUT") bzrlib.trace.note( "bzr_buildbot: SENDING CHANGES to buildbot master %s:%d on %s", server, port, hook) reactor.run(installSignalHandlers=False) # run in a thread when in server
def post_commit_hook( local, master, old_revno, old_revid, new_revno, new_revid, # bzrlib args fixes=None # this one get curried using functools.partial ): """This hook marks fixed bugzilla bugs specified by --fixes arguments.""" branch = local or master config = branch.get_config() revision = branch.repository.get_revision(new_revid) status_by_url = dict(revision.iter_bugs()) # store bugzilla tasks bugs = [] # since we made it to post-commit, all the bugtracker handles are valid for tag, bug in map(lambda x: x.split(':'), fixes or []): enabled = config.get_user_option('bugzilla_%s_bugzillatools_enable' % tag) if not enabled: continue # bugzillatools not enabled for this tracker tracker = bzrlib.bugtracker.tracker_registry.get_tracker(tag, branch) UPIBT = bzrlib.bugtracker.URLParametrizedIntegerBugTracker if not isinstance(tracker, UPIBT) or tracker.type_name != 'bugzilla': continue # tracker is not a bugzilla tracker if status_by_url[tracker.get_bug_url(bug)] != bzrlib.bugtracker.FIXED: # bzrlib only groks fixed for now, but if other statuses come # along this will filter them out continue # see if bzlib knows about this server url, user, password = None, None, None try: server = dict(conf.items('server.' + tag)) url, user, password = \ [server.get(k) for k in 'url', 'user', 'password'] except bzlib.config.NoSectionError: pass # server not defined # url falls back to bzr config (tracker url) # # ugly hack: API doesn't expose the tracker URL, but _base_url property # is defined for URLParametrizedBugTracker, which bugzilla trackers are url = url or tracker._base_url # user falls back to bzr config, then committer user = user \ or config.get_user_option('bugzilla_%s_user' % tag) \ or bzrlib.config.extract_email_address(revision.committer) # password falls back to bzr config password = password \ or config.get_user_option('bugzilla_%s_password' % tag) if not password: bzrlib.trace.warning( "Password not defined for bugtracker '{}'.".format(tag)) continue # get status and resolution status = config.get_user_option('bugzilla_%s_status' % tag) resolution = config.get_user_option('bugzilla_%s_resolution' % tag) if not (status and resolution): bzrlib.trace.warning( "Status or resolution not defined for bugtracker '{}'.".format( tag)) continue bugs.append([bug, url, user, password, status, resolution]) if not bugs: return # nothing to do # assemble the comment outf = StringIO.StringIO() # show master branch (i.e. bound location if a bound branch) outf.write('Fixed in commit at:\n %s\n\n' % master.base) lf = bzrlib.log.log_formatter('long', show_ids=True, to_file=outf) bzrlib.log.show_log(branch, lf, start_revision=new_revno, end_revision=new_revno, verbose=True) msg = outf.getvalue() print 'message:\n', msg for bug, url, user, password, status, resolution in bugs: print 'Setting status of bug {} on {} to {} {}'.format( bug, url, status, resolution) bz = bzlib.bugzilla.Bugzilla(url, user, password) try: bz.bug(bug).set_status(status, resolution, msg) except Exception as e: bzrlib.trace.show_error('Bugtracker error: ' + str(e))
def _set_branch_option(branch, option, value): branch.get_config().set_user_option(option, value)
def _get_branch_option(branch, option): return branch.get_config().get_user_option(option)
def post_commit_hook( local, master, old_revno, old_revid, new_revno, new_revid, # bzrlib args fixes=None # this one get curried using functools.partial ): """This hook marks fixed bugzilla bugs specified by --fixes arguments.""" branch = local or master config = branch.get_config() revision = branch.repository.get_revision(new_revid) status_by_url = dict(revision.iter_bugs()) # store bugzilla tasks bugs = [] # since we made it to post-commit, all the bugtracker handles are valid for tag, bug in map(lambda x: x.split(':'), fixes or []): enabled = config.get_user_option( 'bugzilla_%s_bugzillatools_enable' % tag ) if not enabled: continue # bugzillatools not enabled for this tracker tracker = bzrlib.bugtracker.tracker_registry.get_tracker(tag, branch) UPIBT = bzrlib.bugtracker.URLParametrizedIntegerBugTracker if not isinstance(tracker, UPIBT) or tracker.type_name != 'bugzilla': continue # tracker is not a bugzilla tracker if status_by_url[tracker.get_bug_url(bug)] != bzrlib.bugtracker.FIXED: # bzrlib only groks fixed for now, but if other statuses come # along this will filter them out continue # see if bzlib knows about this server url, user, password = None, None, None try: server = dict(conf.items('server.' + tag)) url, user, password = \ [server.get(k) for k in 'url', 'user', 'password'] except bzlib.config.NoSectionError: pass # server not defined # url falls back to bzr config (tracker url) # # ugly hack: API doesn't expose the tracker URL, but _base_url property # is defined for URLParametrizedBugTracker, which bugzilla trackers are url = url or tracker._base_url # user falls back to bzr config, then committer user = user \ or config.get_user_option('bugzilla_%s_user' % tag) \ or bzrlib.config.extract_email_address(revision.committer) # password falls back to bzr config password = password \ or config.get_user_option('bugzilla_%s_password' % tag) if not password: bzrlib.trace.warning( "Password not defined for bugtracker '{}'.".format(tag) ) continue # get status and resolution status = config.get_user_option('bugzilla_%s_status' % tag) resolution = config.get_user_option('bugzilla_%s_resolution' % tag) if not (status and resolution): bzrlib.trace.warning( "Status or resolution not defined for bugtracker '{}'.".format( tag ) ) continue bugs.append([bug, url, user, password, status, resolution]) if not bugs: return # nothing to do # assemble the comment outf = StringIO.StringIO() # show master branch (i.e. bound location if a bound branch) outf.write('Fixed in commit at:\n %s\n\n' % master.base) lf = bzrlib.log.log_formatter('long', show_ids=True, to_file=outf) bzrlib.log.show_log( branch, lf, start_revision=new_revno, end_revision=new_revno, verbose=True ) msg = outf.getvalue() print 'message:\n', msg for bug, url, user, password, status, resolution in bugs: print 'Setting status of bug {} on {} to {} {}'.format( bug, url, status, resolution ) bz = bzlib.bugzilla.Bugzilla(url, user, password) try: bz.bug(bug).set_status(status, resolution, msg) except Exception as e: bzrlib.trace.show_error('Bugtracker error: ' + str(e))