从今往后每周都写一篇日志,总结一下自己的经验吧。
PM让我搞团队的CruiseControl.NET。什么是CruiseControl.NET呢?简单的说就是团队代码每日构建。它可以自动编译、自动运行单元测试、自动部署、自动打包。1. 对开发来讲可以保证编译通过,不会因为一个组员的代码编译不通过而影响其他人第二天的工作。2. 对PM和Team Leader来说,可以控制代码的质量。代码质量?!恩,你没看错,利用StyleCop等代码规范分析器还有MS unit test 和NUnit,可以保证整个团队的代码规范和质量达到很高的水平!3. 对QA来说,每天都可以测试最新的版本,把测试的任务分配到每天,从而监控开发人员每天的质量。总之,CruiseControl.NET对团队是个很好的工具。
既然有帮助,那么我就来介绍一下如何配置吧。
首先呢,要下载相关的软件,版本控制软件是必不可少的哦。SVN,VSS都是很流行的版本控制工具。不过VSS要钱的,所以大多数Team都采用SVN。一般CruiseControl.NET都安装在团队的服务器上。这里我推荐一个很好用的SVN集成工具,VisualSVN Server。先安装这个。安装完毕之后,我们需要安装CruiseControl.NET了。从http://sourceforge.net/projects/ccnet/可以下载最新的版本。http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET是它的官方网址,这里有很多最新的信息。安装CruiseControl.NET需要IIS。安装完毕之后,接下来就是要配置CruiseControl了。
我先讲一下文件目录结构:
这个是VisualSVN Server 和 CruiseControl.NET安装后的目录
进入CruiseControl.NET之后:
Server目录下是CruiseControl.NET的核心,里面存有配置文件等。Webdashborad目录主要是IIS网站,同时还包含Help文档。
CruiseControl.NET有2种监控方式:exe执行文件和Windows Service执行。分别对应ccnet.exe和CuriseControl.NET服务。
接下来就是本文的核心了,介绍一下CruiseControl.NET的配置文件。
CruiseControl.NET总有4个配置文件:Server目录下的ccnet.config、ccnet.exe.config、ccservice.exe.config和Webdashborad目录下的dashboard.config。
ccnet.config是配置项目,SVN路径,Email地址等等的核心配置文件。我们大多数时间是跟它打交道。
ccnet.exe.config是ccnet.exe可执行文件的配置文件,当我们选择手动运行ccnet.exe时候,它才起作用。
ccservice.exe.config是CruiseControl.NET Service的配置文件。它和ccnet.exe.config主要作用是控制发送Email模板的内容,比如要不要单元测试内容啊,要不要最近更新的内容啊等等。
dashboard.config是配置CruiseControl.NET网站的配置文件,主要是网站显示的内容,也是要不要单元测试啊等等。
写了这么多,我们来看例子吧,一看例子同学们就懂了。
ccnet.config配置文件如下:
![](/Images/OutliningIndicators/ContractedBlock.gif)
ccnet.config
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project name ="MyProject"><!--这个是工程名称-->
<labeller type="dateLabeller" /><!--这个控制Labeller的类型,这里用日期,当然也可以用数字-->
<workingDirectory>E:\Program Files\CruiseControl.NET\server\MyProject</workingDirectory><!--这个目录保存源代码-->
<artifactDirectory>E:\Program Files\CruiseControl.NET\server\Artifacts\MyProject</artifactDirectory><!--这个目录保存每次编译的结果-->
<triggers>
<scheduleTrigger time="00:00" name="Scheduled"><!--我现在用时间触发器,每天00:00编译程序-->
<weekDays><!--星期天休息,就不编译了,唉,每周六要加班啊!-->
<weekDay>Monday</weekDay>
<weekDay>Tuesday</weekDay>
<weekDay>Wednesday</weekDay>
<weekDay>Thursday</weekDay>
<weekDay>Friday</weekDay>
<weekDay>Saturday</weekDay>
</weekDays>
</scheduleTrigger>
</triggers>
<sourcecontrol type="svn"><!--一般都用SVN了,当然VSS也可以-->
<trunkUrl>http://10.50.0.20:8001/svn/projects/MyProject/</trunkUrl><!--SVN Code Address-->
<executable>E:/Program Files/VisualSVN Server/bin/svn.exe</executable><!--这个Visual SVN Server的程序,用它来Download code-->
<username>username</username>
<password>password</password>
</sourcecontrol>
<tasks>
<msbuild>
<executable>D:\WIN2003\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable><!--这个MSBuild的路径-->
<projectFile>MyProject.sln</projectFile><!--这个Solution Name-->
<buildArgs>/t:Build /p:Configuration=Release</buildArgs>
</msbuild>
<!--<exec>
<executable>E:\Program Files\CruiseControl.NET\server\MyProject\DelTestResults.bat</executable>
</exec>
<exec>
<executable>E:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\mstest.exe</executable>
<buildArgs>/resultsfile:.\TestResults\TestResult.trx /runconfig:LocalTestRun.testrunconfig /testmetadata:MyProject.vsmdi /testlist:TestList</buildArgs>
</exec>-->
</tasks>
<publishers>
<!--to get the test results in the dashboard we have to merge the results XML file
the project working directory is used as the base path here-->
<merge>
<files>
<file>E:\Program Files\CruiseControl.NET\server\MyProject\TestResults\TestResult.trx</file><!--这个文件是用于合并UnitTest result-->
</files>
</merge>
<!--this is the line I missed for ages, without it you get strange missing publisher log errors-->
<xmllogger />
<email from="lifeizhuhai@163.com" mailhost="pop3.163.com" mailport="25" includeDetails="TRUE"
mailhostUsername="username" mailhostPassword="password" useSSL="FALSE">
<users>
<!--<user name="Prime Li" group="developers" address="lifeizhuhai@163.com"/>-->
<user name="Group" group="developers" address="group@163.com"/>
</users>
<groups>
<group name="developers" notification="Always"/>
<group name="manager" notification="Success"/>
</groups>
<modifierNotificationTypes>
<NotificationType>Failed</NotificationType>
<NotificationType>Fixed</NotificationType>
</modifierNotificationTypes>
</email>
<rss/>
<modificationHistory />
</publishers>
<externalLinks>
<externalLink name="AMO700" url="http://amo-server/AMO700/" />
</externalLinks>
</project>
主要的配置我都加注释了。如果要控制多个Project,可以并行加多个<Project .../>节点。
下面是ccservice.exe.config,ccnet.exe.config跟它类似的,我们一般修改它的Email模板的配置节,其他都是原封不动。
![](/Images/OutliningIndicators/ContractedBlock.gif)
CCService.exe.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="xslFiles" type="ThoughtWorks.CruiseControl.Core.Config.XslFilesSectionHandler,ThoughtWorks.CruiseControl.Core"/>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<!-- Specifies the stylesheets that are used to transform the build results when using the EmailPublisher -->
<xslFiles><!--这个重要,是控制Email发送模板内容的,name后面是对应目录下的excel配置文件-->
<file name="xsl\header.xsl"/>
<file name="xsl\compile.xsl"/>
<!--<file name="xsl\unittests.xsl"/>-->
<file name="xsl\fit.xsl"/>
<file name="xsl\compile-msbuild.xsl"/>
<file name="xsl\MsTestReport2008.xsl"/>
<file name="xsl\modifications.xsl"/>
<!--<file name="xsl\fxcop-summary.xsl"/>-->
</xslFiles>
<!-- Defines the port and protocol that the ccnet server will use to service remote requests -->
<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" port="21234">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full"/>
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
<log4net>
<root>
<!--
Change the value in the next line to alter the amount of logging generated by CruiseControl.NET.
The following values are supported: DEBUG, INFO, WARN, ERROR, OFF.
For more detailed information on how to configure log4net, see http://logging.apache.org/log4net/
-->
<level value="DEBUG"/>
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileAppender"/>
</root>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%thread:%level] %message%newline"/>
</layout>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="ccnet.log"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<!-- Note: Core.Logging.ServerLogFileReader depends on having "[%thread" present in the pattern -->
<conversionPattern value="%date [%thread:%level] %message%newline"/>
</layout>
</appender>
</log4net>
<appSettings>
<!-- Without this appSetting ccservice will look for ccnet.config in its own directory. -->
<!-- <add key="ccnet.config" value="c:\some\path\to\ccnet.config"/> -->
<add key="service.name" value="CCService"/>
<add key="remoting" value="on"/>
<add key="ServerLogFilePath" value="ccnet.log"/>
<!-- Used by the WebDashboard ServerLog plugin to locate the log file produced by the LogFileTraceListener (above) -->
<add key="ServerLogFileLines" value="100"/>
<!-- Used by the WebDashboard ServerLog plugin to determine how many lines from the log file should be read -->
<add key="WatchConfigFile" value="true"/>
<!-- Turns on or off the file watcher used to monitor the ccnet.config file -->
</appSettings>
<startup>
<supportedRuntime version="v2.0.50727" />
</startup>
</configuration>
最后是dashborad.config,用于配置IIS网站的内容的,这个是插件式网站,网站的内容是可以配出来的,也是我们以后开发的方向哦。多学学吧,插件式网站开发!
![](/Images/OutliningIndicators/ContractedBlock.gif)
DashBoard.config
<?xml version="1.0" encoding="utf-8" ?>
<dashboard>
<remoteServices>
<servers>
<!-- Update this list to include all the servers you want to connect to. NB - each server name must be unique -->
<server name="local" url="tcp://localhost:21234/CruiseManager.rem" allowForceBuild="true" allowStartStopBuild="true" />
</servers>
</remoteServices>
<plugins>
<farmPlugins>
<farmReportFarmPlugin />
<cctrayDownloadPlugin />
</farmPlugins>
<serverPlugins>
<serverReportServerPlugin />
<serverLogServerPlugin />
<serverInformationServerPlugin />
<queueStatusServerPlugin />
<projectConfigurationServerPlugin />
</serverPlugins>
<projectPlugins>
<projectReportProjectPlugin />
<latestBuildReportProjectPlugin />
<viewAllBuildsProjectPlugin />
<projectStatisticsPlugin xslFileName="xsl\StatisticsGraphs.xsl" />
<serverLogProjectPlugin />
<viewConfigurationProjectPlugin />
<modificationHistoryProjectPlugin />
</projectPlugins>
<buildPlugins>
<buildReportBuildPlugin>
<xslFileNames><!--修改这里,是控制显示哪些详细的编译内容-->
<xslFile>xsl\header.xsl</xslFile>
<xslFile>xsl\compile.xsl</xslFile>
<xslFile>xsl\compile-msbuild.xsl</xslFile>
<!--<xslFile>xsl\unittests.xsl</xslFile>-->
<xslFile>xsl\fxcop-summary.xsl</xslFile>
<xslFile>xsl\NCoverSummary.xsl</xslFile>
<xslFile>xsl\SimianSummary.xsl</xslFile>
<xslFile>xsl\MsTestReport2008.xsl</xslFile>
<xslFile>xsl\modifications.xsl</xslFile>
<!--<xslFile>xsl\MsTestReport2008.xsl</xslFile>
<xslFile>xsl\MsTestReport.xsl</xslFile>-->
<!--<xslFile>xsl\MsTestSummary.xsl</xslFile>-->
<xslFile>xsl\fitnesse.xsl</xslFile>
</xslFileNames>
</buildReportBuildPlugin>
<buildLogBuildPlugin />
<xslReportBuildPlugin description="NUnit Details" actionName="NUnitDetailsBuildReport" xslFileName="xsl\tests.xsl" /><!--这里是CruiseControl.NET提供的插件-->
<xslReportBuildPlugin description="NUnit Timings" actionName="NUnitTimingsBuildReport" xslFileName="xsl\timing.xsl" />
<xslReportBuildPlugin description="NAnt Output" actionName="NAntOutputBuildReport" xslFileName="xsl\NAnt.xsl" />
<xslReportBuildPlugin description="NAnt Timings" actionName="NAntTimingsBuildReport" xslFileName="xsl\NAntTiming.xsl" />
<xslReportBuildPlugin description="FxCop Report" actionName="FxCopBuildReport" xslFileName="xsl\FxCopReport.xsl" />
<xslReportBuildPlugin description="NCover Report" actionName="NCoverBuildReport" xslFileName="xsl\NCover.xsl" />
<xslReportBuildPlugin description="Simian Report" actionName="SimianBuildReport" xslFileName="xsl\SimianReport.xsl"/>
<xslReportBuildPlugin description="Fitnesse Report" actionName="FitnesseBuildReport" xslFileName="xsl\FitnesseReport.xsl"/>
<xslReportBuildPlugin description="MSBuild Report" actionName="MSBuildBuildReport" xslFileName="xsl\msbuild.xsl"/>
<xslReportBuildPlugin description="MSTest Report" actionName="MSTESTReport" xslFileName="xsl\MsTestReport2008.xsl"/>
<!-- This is an example of using Project-specific build plugins
<xslReportBuildPlugin description="My Report" actionName="MyReport" xslFileName="xsl\MyReport.xsl">
<includedProjects>
<projectName>My Project</projectName>
</includedProjects>
</xslReportBuildPlugin>
<xslReportBuildPlugin description="My Other Report" actionName="MyOtherReport" xslFileName="xsl\MyOtherReport.xsl">
<excludedProjects>
<projectName>My Project</projectName>
</excludedProjects>
</xslReportBuildPlugin>
-->
</buildPlugins>
</plugins>
</dashboard>
好了,大功告成了,最后呢,我再教大家一招,用变量来控制节点。我们可以把这些变量统一放在文件头来管理,这样很方便维护。
![](/Images/OutliningIndicators/ContractedBlock.gif)
用变量来维护配置文件
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define MyProjectName="ILoveYou"/>
<project name =$(MyProjectName)>
<
>
</project
</cruisecontrol>
OK,同学们,下课!
PS: 好累哇~~~以后我会给大家带来《如何控制团队代码规范》的课程,希望大家喜欢~~~