[CruiseControl]Build Loop
一 Build Loop
Build Loop是CruiseControl的核心组件,它用来运行一个守护(后台)进程定期检查你的Source control tool上的修改,根据你的设置和检查的结果来决定是否build,在build后将结果通知所有的listeners。
二 Build Loop如何工作
CruiseControl定义一个build cycle,包含决定是否一个build是需要的,进行build,创建log,然后发送通知。后台进程按照用户定义的时间间隔尝试开始一个build cycle。配置文件每次被重新加载以至于CruiseControl不需要重新启动就可以使配置的改动起作用,但是对于新添加的project,仍然需要重新启动CruiseControl来使新project的修改起作用。在build的最后,log会被生成且被用于build result jsp的显示。
三Build Loop的配置
当启动CruiseControl时可以指定命令行参数(也成为系统参数)来对build loop进行配置,可以使用的参数-jmxport/-rmiport/-configfile/-xslpath/-user/-password/-agentutil/-debug/-log4jconfig/-port/-dashboardurl/-postinterval/-postenabled/-lib。
四 Plugins
1)Plugin概括
我们很难想象CruiseControl被使用的所有的方法,不同team的使用不同工具和其他的一些微妙的差别导致了我们不可能开发一种适合所有情况的解决方案。 CruiseControl被设计为实现Continous integration的high-level的核心和实现所有细节的plugins两部分。通过这种方法我们很容易创建新的功能,修改已有的功能和删除不需要的功能。plugins机制也使得对CruiseControl的codebase的学习更加容易,因为所有的功能都是按模块组织,例如你可以假设所有的CVS的功能在一个地方。plugin机制也使得测试工作更容易。
plugin class通过registration程序被映射到相应的configuration xml的element,随CruiseControl发布的plugins默认地都被registrated。
2)plugin执行过程
projectxmlhelper class初始化configuration,处理plugin的映射,将plugins初始化到对应的pluginxmlhelper。一旦完成初始化配置,plugins将会被validated,然后在build cycle的适当的时候运行。plugin的执行时机取决于plugin的类型。
plugin 初始化:
在正常的初始化情况下,pluginxmlhelper调用config文件中tag对应的属性的set方法,例如与<ant/>元素的target属性对应的AntBuilder的setTarget方法。解析器是区分大小写的,必须保持属性的和方法的大小写完全一致。
在config文件中允许plugin中嵌套申明其他元素,在这种情况下,CruiseControl将需要你的plugin为每个嵌套元素实现add或create方法:
*如果嵌套的元素本身就是plugin,pluginxmlhelper不知道哪种类型的元素应该映射,所以需要projectxmlhelper中配置此元素;
*如果是简单的嵌套元素(非plugin),plugin自己知道需要映射的元素名字。返回实例AntBuilder,我们可以看到createJVMArg()方法和嵌套的JVMArg类型。createJVMArg()方法负责创建JVMArg的实例且保持此实例的引用能在AntBuilder中的其他地方继续使用。createJVMArg()返回了新创建的JVMArg对象,以至于pluginxmlhelper能使用与父元素同样的方法配置嵌套元素。理论上,元素的嵌套层数是没有限制的,只要有合适的create方法。
plugin 验证:
在解析器配置好plugin后,我们立即使用plugin的validate()方法来对plugin进行验证。通过validate()的验证,我们能够尽早地发现plugin的配置问题。
plugin 执行:
在plugins配置和验证后,我们将开始按照他们的类型来执行他们。每一个plugin都有一个“action” 方法被cruisecontrol调用来执行plugin。例如bootstrappers类型的plugin是在build cycle开始前执行,在他们被配置和验证配置正确后,我们便可以依次调用他们的“action” 方法bootstrap()。
3)plugin的配置
plugin 注册:
plugin的注册是简单且直接的,直接在<cruisecontrol>元素下或<project>元素下增加<plugin name="" classname=""/>,在<plugin/>元素中的name属性表示在config文件中使用此plugin时需要使用的名字,classname属性表示次plugin实际对应的Java class。
如果plugins直接被指定在root元素下,表示plugins对所有的projects都可用。如果plugins只包含在project中,则plugins只能在此project中被使用。同时也可以在project中覆盖全局的plugins定义,例如单独地对某个project使用labelincrementer plugin。
为了保持config文件尽量的小,所有的随cruisecontrol发布的plugins都默认地被自动注册。如果你希望某些默认注册的plugins名字指向你希望的其他的plugins,你只需要显示地使用这些名字重新注册到新的plugins,此后默认被注册的plugins将被覆盖。
plugin的预配置/默认值:
在plugins注册的同时,你能够为plugin的某些属性或嵌套的plugin指定默认值。简单地使用属性或子元素来定义默认值。plugin的默认值还可以在project中真正使用时覆盖。Note: when nested elements have a multiple cardinality, overriding an already pre-configured child element might accumulate them.
例如为htmlemail publisher plugin定义一些默认属性值:
mailhost="smtp.example.com"
returnaddress="buildmaster@example.com"
subjectprefix="[CC]"
xsldir="C:\java\cruisecontrol-2.2.1\report\jsp\webcontent\xsl"
css="C:\java\cruisecontrol-2.2.1\report\jsp\webcontent\css\cruisecontrol.css">
<always address="project-dev@domain.com"/>
<plugin/>
为了保持config文件尽可能小,你能创建一个template project,避免重复设置通用的属性,例如如下project只需要设置project name:
<plugin name="project">
<bootstrappers>
<cvsbootstrapper localworkingcopy="projects/${project.name}"/>
</bootstrappers>
...
</plugin>
<project name="foo" />
<project name="bar" />
...
</cruisecontrol>
4) Plugin类型
目前CruiseControl支持6中不同的plugin类型,每一种都有不同的角色,但他们的设计都很相似。6中类型如下:
*Bootstrapper : 在build前运行;
*SourceControl: 检测code repository决定是否有code改动;
*Builder:真正执行building和testing;
*LabelIncrementer:处理label的增加,label可以被用来tag code;
*Publisher: 发布build的结果,例如通过email;
*Listener: 处理project的events;
5)默认的plugins
bootstrapper
source control
builder
label incrementer
Plugin Name | Class Name |
---|---|
labelincrementer | net.sourceforge.cruisecontrol.labelincrementers.DefaultLabelIncrementer |
publisher
listener
完!