若是你有足够的主机资源和人力资源,那为每一个项目单独搭建一套CI环境是再好不过的了,每一个项目都有专人维护CI环境,各个项目的配置互不干扰。不过对于一些公司来讲,这显然有些浪费,BuildBot Master的资源消耗是不大的,咱们彻底能够使用一套BuildBot Master来服务于多个项目,至少BuildBot是能够支持这样作的。html
CI环境中,咱们首要关注的就是源码库。多个项目可能各自使用单独的源码库,也可能共享一个源码库并经过目录隔离和识别。不管怎样,咱们均可以经过BuildBot Master的配置来知足咱们的要求。app
若是说多个项目共享一个源码库或是一个项目下的多个子系统放在一个源码库中,这时咱们在配置change_source时指定一个变动监测器便可,这个监测器的监测范围从源码库的根路径开始。以Subversion源码库为例,咱们能够这样来配置:svn
c['change_source'] = [SVNPoller("svn://10.0.0.1:3000",
svnuser='tony',
svnpasswd='tony',
pollinterval=60,
split_file=change_path_split)]post
咱们经过change_path_split来拆分变动文件的路径,假设SVN库结构是这样的:
svn://10.0.0.1:3000
- foo_proj
- trunk
- main/main.c
- branches
- tags
- bar_proj
- trunk
- main/main.c
- branches
- tags性能
咱们能够这样来实现change_path_split:测试
def change_path_split(path):
pieces = path.split('/')
if pieces[0] == 'foo_proj' and pieces[1] == 'trunk':
return ('foo_proj/trunk', '/'.join(pieces[2:]))
elif pieces[0] == 'bar_proj' and pieces[1] == 'trunk':
return ('bar_proj/trunk', '/'.join(pieces[2:]))
else:
return Noneui
不一样项目下的文件变动,会致使change_path_split返回不一样的值,而change_path_split返回值会被用于匹配不一样的Scheduler:spa
c['schedulers'].append(Scheduler(name="foo-ci-plan",
branch='foo_proj/trunk',
treeStableTimer=5,
builderNames=["foo-redhat-builder", "foo-x86-solaris-builder"]).net
c['schedulers'].append(Scheduler(name="bar-ci-plan",
branch='bar_proj/trunk',
treeStableTimer=5,
builderNames=["bar-redhat-builder", "bar-x86-solaris-builder"])rest
上面各个Scheduler的branch属性会与change_path_split返回值元组中的第一个元素匹配,这样foo-ci-plan即是foo_proj的scheduler,而bar-ci-plan则是bar_proj的scheduler。这样某个项目路径下的文件变动只会触发对应的scheduler开始工做,不会出现误触发。
若是多个项目或一个项目的多个模块使用不一样的源码库,同理,咱们能够为c['change_source']赋予多个SVNPoller,例如:
c['change_source'] = [SVNPoller("svn://10.0.0.1:3000",
svnuser='tony',
svnpasswd='tony',
pollinterval=60,
split_file=change_path_split),
SVNPoller("svn://10.0.0.1:4000",
svnuser='tony',
svnpasswd='tony',
pollinterval=60,
split_file=another_change_path_split)]
与Scheduler的匹配方式也与上述描述一致,这里就不重复说明了。
不一样项目的干系人多不相同,那么集成的结果是如何准确地反馈给项目各自对应的干系人呢?以Mail反馈通知为例,我在BuildBot手册中找到了两种方式,一种方式是经过设置Scheduler的owner属性,而后指定MailNotifier的sendToInterestedUsers=True,意图让BuildBot将Mail通知发到owner list中的每一个邮件地址,但经测试后发现,这种方式彷佛很差用,不知道是不是BuildBot对该功能的实现上存在问题。
另一种方式则是配置多个MailNotifier。每一个MailNotifier中指定对应builder的名称列表,并经过extraRecipients指定这些Builder对应的项目的干系人Mail地址列表,例如:
c['status'].append(mail.MailNotifier(fromaddr="foo-buildbot@buildbot.net",
extraRecipients=["foo1@buildbot.net", "foo2@buildbot.net"],
builders=['foo-x86-solaris-builder', 'foo-redhat-builder'],
useTls=False,
sendToInterestedUsers=False,
relayhost="smtp.buildbot.net",
smtpUser='tony',
smtpPassword='tony',
smtpPort=25))
c['status'].append(mail.MailNotifier(fromaddr="bar-buildbot@buildbot.net",
extraRecipients=["bar1@buildbot.net", "bar2@buildbot.net"],
builders=['bar-x86-solaris-builder', 'bar-redhat-builder'],
useTls=False,
sendToInterestedUsers=False,
relayhost="smtp.buildbot.net",
smtpUser='tony',
smtpPassword='tony',
smtpPort=25))
这样foo的builders构建的结果将发到foo1和foo2;而bar的builders构建结果将反馈到bar1和bar2。
多个项目共享一套BuildBot Master有利有弊,其不足之处可能有以下几点:
一、项目过多时,可能存在潜在的性能问题
二、Master的配置被多个项目共享,存在潜在的Conflict问题;
三、另外master.cfg可能size过大,也不利于阅读和维护。