从 《【Hello CC.NET】CC.NET 实现自动化集成》 到 《【Hello CC.NET】自动化发布时 Web.config 文件维护》 ,大神在评论里提到的方案还没有一一去研究对比,调研的 deadline 已经逼近,CC.NET 的落地提上日程。

  经过两周的努力,终于成功部署了两个项目,由于两个项目的人员配置/开发流程/项目架构不一样,部署的方案也有些差异。过程中碰到这样那样的坑,都是用最快想到的笨方法填坑,然后继续往下走。落地的姿势并不完美,但总算有了一些看得到的成果。   

  落地面临的第一个问题是,ccnet.config 配置比较繁复:太多的 hardcode;相同的 xml 节点内容比较多,尤其在配置多个项目的时候,策略变更时,需要改动的地方比较多。本文将讲述 ccnet.config 模板化的思路。

  

  目标

  • 提取全局性的配置,避免到处 Hardcode
  • 简化各个节点的配置,便于维护

  1.全局变量

    <cc:define CIWebSite="http://vm-caihaihua/CCNET/"/><cc:define CIDirectory="C:\CI\"/><cc:define MsBuildPath="C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"/><cc:define MsTestPath="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe"/><cc:define SVNPath="C:\Program Files (x86)\VisualSVN Server\bin\svn.exe"/><cc:define FCReplacerPath="C:\CI\Tools\FCReplacer.exe"/><cc:define DFCopierPath="C:\CI\Tools\DFCopier.exe"/><cc:define name="MsBuildXmlLogger"><logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger></cc:define>

  

变量名称 描述
CIWebSite CC.NET配套网站的地址 http://vm-caihaihua/CCNET/
CIDirectory 工作目录 C:\CI\
MsBuildPath MsBuild 程序的地址 C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
MsTestPath MsTest 程序的地址 C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe
SVNPath Svn 程序的地址 C:\Program Files (x86)\VisualSVN Server\bin\svn.exe
FCReplacerPath FCReplacer 程序的地址 C:\CI\Tools\FCReplacer.exe
DFCopierPath DFCopier 程序的地址 C:\CI\Tools\DFCopier.exe
MsBuildXmlLogger 日志 Logger 的配置 <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>

 

  2.默认值

    <!-- 默认配置 --><cc:define QueuePriority="1"/><cc:define KeepLastXBuilds="300"/><!-- Email 相关 --><cc:define EmailDomain="company.com"/><cc:define EmailSendHost="smtp.live.com"/><cc:define EmailSendPort="25"/><cc:define EmailUseSSL="FALSE"/><cc:define EmailSendUser="ci"/><cc:define EmailSendPassword="********"/><cc:define CIEmailUser="ci"/><cc:define PMEmailUser="pm_1"/><cc:define name="EmailTesterList"><user group="tester" name="tester_1" address="tester_1@$(EmailDomain)"/><user group="tester" name="tester_2" address="tester_2@$(EmailDomain)"/></cc:define><!-- Trigger 相关 --><cc:define ModificationTriggerIntervalSeconds="300"/><cc:define ModificationDelaySeconds="60"/><cc:define ProjectTriggerIntervalSeconds="30"/><cc:define ProjectTriggerStatus="Success"/><cc:define DailyBuildTriggerTime="18:00"/><!-- SVN 相关 -->    <cc:define SVNUsername="ci"/><cc:define SVNPassword="********"/><cc:define SvnCleanCopy="FALSE"/><cc:define name="SourceControl">        </cc:define><!-- Task 相关 --><cc:define TestTimeout="1800"/><cc:define CopyTimeout="60"/><cc:define ReplaceTimeout="60"/><cc:define BuildConfiguration="DEBUG"/><cc:define PublishConfiguration="RELEASE"/>

    

变量名称 描述
QueuePriority  项目在队列中的优先级  1
KeepLastXBuilds  保留最后的 X 个构建结果  300
EmailDomain  公司邮箱域名  company.com
EmailSendHost  邮箱服务器地址  smtp.live.com
EmailSendPort  邮箱服务器端口  25
EmailUseSSL  是否启用 SSL  TRUE
EmailSendUser  发送邮箱的帐号  ci
EmailSendPassword  发送邮箱账户的密码  ******
 CIEmailUser  CI 维护人员的邮箱账户  ci
 PMEmailUser  部门经理的邮箱账户  pm_1
 EmailTesterList  测试人员邮箱列表

<user group="tester" name="tester_1" address="tester_1@$(EmailDomain)"/>

<user group="tester" name="tester_2" address="tester_2@$(EmailDomain)"/>

 ModificationTriggerIntervalSeconds  源代码监测的频率(秒)  300
 ModificationDelaySeconds  源代码变更触发构建任务的延迟时间(秒)  60
 ProjectTriggerIntervalSeconds  依赖项目的状态监测频率(秒)  30
 ProjectTriggerStatus  依赖项目的设定状态  SUCCESS
 DailyBuildTriggerTime  每日构建的时间点  18:00
 SVNUsername  SVN 帐号  ci
 SVNPassword  SVN 帐号的密码  ******
 SvnCleanCopy  下载源代码前是否先删除本地源代码  FALSE
 SourceControl  源代码管理的配置  
 TestTimeout  运行测试的超时时间(秒)  1800
 CopyTimeout  拷贝文件的超时时间(秒)  60
 ReplaceTimeout  替换文件内容的超时时间(秒)  60
 BuildConfiguration  编译的配置  DEBUG
 PublishConfiguration  发布网站的配置  RELEASE

  

  

  3.通知模板

    <cc:define name="EmailPublisher"><email mailhost="$(EmailSendHost)" mailport="$(EmailSendPort)"mailhostUsername="$(EmailSendUser)@$(EmailDomain)" mailhostPassword="$(EmailSendPassword)"from="$(EmailSendUser)@$(EmailDomain)"useSSL="$(EmailUseSSL)" includeDetails="true"><!--邮件标题配置--><subjectPrefix>$(EmailSubject)</subjectPrefix><subjectSettings><!-- Success/Broken/StillBroken/Fixed/Exception--><subject buildResult="Success" value="${CCNetProject} Build result"/><subject buildResult="Fixed" value="${CCNetProject} Build result"/><subject buildResult="Broken" value="${CCNetProject} Build result"/><subject buildResult="StillBroken" value="${CCNetProject} Build result" /><subject buildResult="Exception" value="${CCNetProject} Build result" /></subjectSettings><!--收件人配置--><converters><rcgexConverter find="$" replace="@$(EmailDomain)"/></converters><modifierNotificationTypes><notificationType>Failed</notificationType><notificationType>Fixed</notificationType></modifierNotificationTypes><users><user group="pm" name="$(PMEmailUser)" address="$(PMEmailUser)@$(EmailDomain)"/><user group="ci" name="$(CIEmailUser)" address="$(CIEmailUser)@$(EmailDomain)"/><user group="tl" name="$(TeamLeader)" address="$(TeamLeader)@$(EmailDomain)"/><cc:EmailTesterList/></users><groups><group name="pm"><notifications><!--Always/Success/Change/Fixed/Failed/Exception --><notificationType>Change</notificationType></notifications></group><group name="ci"><notifications><notificationType>Exception</notificationType></notifications></group><group name="tl"><notifications><notificationType>Success</notificationType><notificationType>Fixed</notificationType><notificationType>Failed</notificationType></notifications></group><group name="developer"><notifications><notificationType>Success</notificationType><notificationType>Fixed</notificationType><notificationType>Failed</notificationType></notifications></group><group name="tester"><notifications><notificationType>Fixed</notificationType></notifications></group></groups></email></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
EmailDomain 公司邮箱域名  company.com  N
EmailSendHost 邮件服务器的地址  smtp.live.com  N
EmailSendPort 邮件服务器的端口  25  N
EmailUseSSL 是否使用 SSL(取决于邮件服务器的配置)  TRUE  N
EmailSendUser 邮件通知的发送帐号  CI  N
EmailSendPassword 邮件通知的发送帐号的密码  ******  N
PMEmailUser 部门经理的邮箱帐号  pm_1  N
CIEmailUser CI 环境维护人员的邮箱帐号  ci  N
TeamLeader 项目组负责人的邮箱帐号,各个项目组配置不同    Y
EmailSubject 邮件通知的前缀    Y

  

  例子:  

            <publishers><!--邮件通知--><cc:EmailPublisher/></publishers>

  4.触发器模板

  (1)源代码检测:每隔一段时间检查源代码,如果有变更,则触发构建过程

    <!-- Triggers:ModificationTrigger/DailyBuildTrigger/ProjectTrigger--><cc:define name="ModificationTrigger"><!--源码修改触发--><intervalTrigger seconds="$(ModificationTriggerIntervalSeconds)" buildCondition="IfModificationExists" /></cc:define> 

  模板变量:

变量名称 描述 默认值 是否必填
ModificationTriggerIntervalSeconds 源码监测频率(秒) 600 N

  

  例子:

        <triggers><cc:ModificationTrigger/></triggers>

  (2)每日构建:每天到设定的时间点触发构建过程

    <cc:define name="DailyBuildTrigger"><!--每日构建--><scheduleTrigger time="$(DailyBuildTriggerTime)" buildCondition="ForceBuild"><weekDays><!--<weekDay>Sunday</weekDay>--><weekDay>Monday</weekDay><weekDay>Tuesday</weekDay><weekDay>Wednesday</weekDay><weekDay>Thursday</weekDay><weekDay>Friday</weekDay><!--<weekDay>Saturday</weekDay>--></weekDays></scheduleTrigger></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
DailyBuildTriggerTime 每日构建的时间点 18:00 N

  

  例子:

        <triggers><cc:DailyBuildTrigger/></triggers>

  (3)项目依赖:每隔一段时间检查指定项目的构建结果,如果等于指定值,则触发构建过程

    <cc:define name="ProjectTrigger"><projectTrigger serverUri="tcp://vm-caihaihua:21234/CruiseManager.rem" project="$(ListenToProject)"><triggerStatus>$(ProjectTriggerStatus)</triggerStatus><innerTrigger type="intervalTrigger" seconds="$(ProjectTriggerIntervalSeconds)" buildCondition="ForceBuild" /><!--<triggerFirstTime>True</triggerFirstTime>--></projectTrigger></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
ProjectTriggerIntervalSeconds 监测依赖项目的频率(秒) 30 N
ProjectTriggerStatus 设定的构建结果 SUCCESS N
ListenToProject 依赖的项目名称   Y

  

  例子:

        <triggers><cc:ProjectTrigger ListenToProject="TestProject-Servcies"/></triggers>

  5.源代码管理模板

    <!-- SourceControl: SVNSourceControl --><cc:define name="SVNSourceControl"><sourcecontrol type="svn"><trunkUrl>$(SVNTrunkURL)</trunkUrl><executable>$(SVNPath)</executable><workingDirectory>$(CIDirectory)$(WorkingDirectory)</workingDirectory><username>$(SVNUsername)</username><password>$(SVNPassword)</password><revert>True</revert><cleanCopy>$(SvnCleanCopy)</cleanCopy><cleanUp>True</cleanUp><deleteObstructions>True</deleteObstructions></sourcecontrol></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
SVNUsername Svn 账户,需要项目的 checkout 权限 ci N
SVNPassword Svn 账户的密码 ****** N
SvnCleanCopy 下载源代码前是否先删除本地源代码 FALSE N
SVNTrunkURL 项目的 Svn 路径
  Y

  例子:

        <project><cc:SVNSourceControl SVNTrunkURL="https://vm-caihaihua/svn/testproject/services/trunk/"SvnCleanCopy="False"/></project>

  6.任务模板

  (1)文件内容替换

  

    <cc:define name="Replace"><exec><executable>$(FCReplacerPath)</executable><buildArgs><cc:Files/><cc:Rules/></buildArgs><buildTimeoutSeconds>$(ReplaceTimeout)</buildTimeoutSeconds><successExitCodes>0</successExitCodes></exec></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
ReplaceTimeout 替换的超时时间(秒) 60 N
Files 需要替换的文件列表   Y
Rules 替换的规则
  Y

  例子:

       <tasks><!-- Config --><cc:Replace><cc:define name="Files">
/file=$(CIDirectory)$(WorkingDirectory)WcfService\Web.config
/file=$(CIDirectory)$(WorkingDirectory)ManagerTest\App.config
/file=$(CIDirectory)$(WorkingDirectory)WcfServiceTest\App.config</cc:define><cc:define name="Rules">
/from=Catalog=(?![^;\s']*_log[;\s']+)(=?[^;\s']*)/to=Catalog=testproject_trunk
/from=Source=(=?.*?)(=?[;\s']+)/to=Source=vm-caihaihua$2
/from=http://(=?[^\/]+)/(=?\w+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$2.svc
/from=http://(=?.*?)/(?!SSO)(=?[^\/]+)/(=?\w+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$3.svc
/from=http://(=?.*?)/SSO/(=?\w+).svc/to=http://vm-caihaihua/testproject_trunk_ci/SSO/$2.svc</cc:define></cc:Replace></tasks>

  (2)项目编译

    <cc:define name="Build"><msbuild><executable>$(MsBuildPath)</executable><buildArgs>/t:build /p:configuration=$(BuildConfiguration)</buildArgs><cc:MsBuildXmlLogger/><workingDirectory>$(CIDirectory)$(WorkingDirectory)</workingDirectory><projectFile>$(SolutionPath)</projectFile></msbuild></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
BuildConfiguration 编译的配置 DEBUG N
SolutionPath 项目的相对路径   Y

  例子:

       <tasks><!-- Build --><cc:Build SolutionPath="TestProjectService.sln"/></tasks>

  (3)网站发布

  

    <cc:define name="Publish"><msbuild><executable>$(MsBuildPath)</executable><workingDirectory>$(CIDirectory)$(WorkingDirectory)</workingDirectory><projectFile>$(SolutionPath)</projectFile><buildArgs>/t:ResolveReferences;Compile/t:_CopyWebApplication/p:Configuration=$(PublishConfiguration)/p:WebProjectOutputDir=$(CIDirectory)$(To)/p:OutputPath=$(CIDirectory)$(To)\bin</buildArgs></msbuild></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
PublishConfiguration 编译的配置 RELACE N
SolutionPath 项目的相对路径   Y
To 目标文件夹的相对路径   Y

  例子:

       <tasks><!-- Publish --><cc:Publish SolutionPath="WcfService\WcfService.csproj"To="$(PublishDirectory)WcfService" /></tasks>

  (4)文件拷贝

    <cc:define name="Copy"><exec><executable>$(DFCopierPath)</executable><buildArgs>/from=$(CIDirectory)$(From) /to=$(CIDirectory)$(To)</buildArgs><buildTimeoutSeconds>$(CopyTimeout)</buildTimeoutSeconds><successExitCodes>0</successExitCodes></exec></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
CopyTimeout 拷贝的超时时间(秒) 60 N
From 需要拷贝的文件夹的相对路径   Y
To 目标文件夹的相对路径   Y

  例子:

       <tasks><!-- Copy--><cc:Copy From="$(WorkingDirectory)WcfServiceTo="$(PublishDirectory)WcfService"/></tasks>

  (5)自动化测试

    <cc:define name="RunTest"><exec><executable>$(MSTestPath)</executable><baseDirectory>$(CIDirectory)$(WorkingDirectory)</baseDirectory><buildArgs>/testcontainer:$(TestContainerPath)</buildArgs><buildTimeoutSeconds>$(TestTimeout)</buildTimeoutSeconds></exec></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
TestTimeout 测试的超时时间(秒) 1800 N
TestContainerPath 测试列表的相对路径   Y

  例子:

       <tasks><!--Run Test--><cc:RunTest TestContainerPath="ManagerTest\bin\Debug\ManagerTest.dll"/><cc:RunTest TestContainerPath="WcfServiceTest\bin\Debug\WcfServiceTest.dll"/></tasks>

  7.项目模板

    <cc:define name="Project"><project name="$(ProjectName)" queue="$(Queue)" queuePriority="$(QueuePriority)"><webURL>$(CIWebSite)server/local/project/$(ProjectName)/ViewProjectReport.aspx</webURL><!--标签--><labeller type="dateLabeller"/><artifactDirectory>$(CIDirectory)$(ArtifactDirectory)</artifactDirectory><!--项目的目录--><workingDirectory >$(CIDirectory)$(WorkingDirectory)</workingDirectory><!--自动运行时间间隔--><triggers><cc:TriggerList/></triggers><!--对源码修改延迟处理时间间隔--><modificationDelaySeconds>$(ModificationDelaySeconds)</modificationDelaySeconds><maxSourceControlRetries>5</maxSourceControlRetries><!--源代码管理(SVN)--><cc:SourceControl/><state type="state" directory="$(CIDirectory)$(StateDirectory)"/><publishers><modificationHistory onlyLogWhenChangesFound="true"/><statistics/><xmllogger/><artifactcleanup cleanUpMethod="KeepLastXBuilds" cleanUpValue="$(KeepLastXBuilds)" /><!--邮件通知--><cc:EmailPublisher/></publishers><tasks><cc:TaskList/></tasks></project></cc:define>

  模板变量:

变量名称 描述 默认值 是否必填
QueuePriority 项目在队列里的优先级 1 N
KeepLastXBuilds 保存最后的 X 个构建结果 300 N
ModificationDelaySeconds 源代码变更触发构建任务的延迟时间 60 N
SourceControl 源代码配置   N
Queue 项目从属的队列   Y
ProjectName 项目名称   Y
StateDirectory 构建日志的保存目录   Y
WorkingDirectory 项目的工作目录,即源代码的保存路径   Y
ArtifactDirectory 构建结果的存放目录   Y
TriggerList 触发器配置列表   Y
TaskList 任务列表   Y

  

  例子:

  TestProject 包括 Wcf Service 项目和 AdminWeb 项目

  (1)Wcf Service

  a.  自动化部署

  • 自动获取源代码
  • 源代码监测及每日构建
  • 修改配置文件中的数据库连接字符串及服务引用地址
  • Debug 编译整个解决方案
  • Release 发布 Service 到 CI 环境

  b. 自动化测试

  • 与a使用同一个工作目录(即源代码)
  • 监测自动化部署过程,如果成功则触发自动化测试
  • 运行 ManagerTest 和 ServiceTest

  (2) AdminWeb

自动化部署

  • 自动获取源代码
  • 源代码监测及每日构建
  • 修改配置文件中的数据库连接字符串及服务引用地址
  • Debug 编译整个解决方案
  • Release 发布 AdminWeb 到 CI 环境
    <!-- TestProject: Service 项目 --><queue name="TestProject" duplicates="ApplyForceBuildsReAdd" /><cc:Project ProjectName="TestProject-Servcies"Queue="TesProjectt"WorkingDirectory="TestProject\SourceCode\service_trunk\"ArtifactDirectory="TestProject\Artifact\service\"StateDirectory="TestProject\State\"PublishDirectory="TestProject\Publish\"EmailSubject="[CI-TestProjectService]"ModificationDelaySeconds="30"TeamLeader="caihaihua"><cc:define name="SourceControl"><cc:SVNSourceControl SVNTrunkURL="https://vm-caihaihua/svn/testproject/services/trunk/"SvnCleanCopy="False"/></cc:define><cc:define name="TriggerList"><cc:ModificationTrigger/><cc:DailyBuildTrigger/></cc:define><cc:define name="TaskList"><!-- Config --><cc:Replace><cc:define name="Files">/file=$(CIDirectory)$(WorkingDirectory)WcfService\Web.config/file=$(CIDirectory)$(WorkingDirectory)ManagerTest\App.config/file=$(CIDirectory)$(WorkingDirectory)WcfServiceTest\App.config</cc:define><cc:define name="Rules">/from=Catalog=(?![^;\s']*_log[;\s']+)(=?[^;\s']*)/to=Catalog=service_trunk_ci/from=Source=(=?.*?)(=?[;\s']+)/to=Source=localhost$2/from=http://(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$2.svc/from=http://(=?.*?)/(?!SSO)(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$3.svc/from=http://(=?.*?)/SSO/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/SSO/$2.svc</cc:define></cc:Replace><!-- Build --><cc:Build SolutionPath="TestProjectService.sln"/><!-- Publish --><cc:Copy From="$(WorkingDirectory)WcfService"To="$(PublishDirectory)WcfService"/></cc:define></cc:Project><cc:Project ProjectName="TestProjectServcies-Test"Queue="TestProject"QueuePriority="2"WorkingDirectory="TestProject\SourceCode\service_trunk\"ArtifactDirectory="TestProject\Artifact\test\"StateDirectory="TestProject\State\"EmailSubject="[CI-TestProjectServcie-Test]"ModificationDelaySeconds="30"TeamLeader="caihaihua"><cc:define name="TriggerList"><cc:ProjectTrigger ListenToProject="TestProject-Servcies"/></cc:define><cc:define name="TaskList"><!--Run Test--><cc:RunTest TestContainerPath="ManagerTest\bin\Debug\ManagerTest.dll"/><cc:RunTest TestContainerPath="WcfServiceTest\bin\Debug\WcfServiceTest.dll"/></cc:define></cc:Project><!-- TestProject: AdminWeb 项目 --><cc:Project ProjectName="TestProject-AdminWeb"Queue="TestProject"WorkingDirectory="TestProject\SourceCode\admin_trunk\"ArtifactDirectory="TestProject\Artifact\admin\"StateDirectory="TestProject\State\"PublishDirectory="TestProject\Publish\"EmailSubject="[CI-TestProject-AdminWeb]"TeamLeader="caihaihua"><cc:define name="SourceControl"><cc:SVNSourceControl SVNTrunkURL="https://vm-caihaihua/svn/testproject/adminweb/trunk/"/></cc:define><cc:define name="TriggerList"><cc:ModificationTrigger/><cc:DailyBuildTrigger/></cc:define><cc:define name="TaskList"><!-- Config --><cc:Replace><cc:define name="Files">/file=$(CIDirectory)$(WorkingDirectory)AdminWeb\Web.config</cc:define><cc:define name="Rules">/from=http://(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$2.svc/from=http://(=?.*?)/(?!SSO)(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$3.svc/from=http://(=?.*?)/SSO/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/SSO/$2.svc</cc:define></cc:Replace><!-- Build --><cc:Build SolutionPath="AdminWeb.sln"/><!-- Publish --><cc:Publish SolutionPath="AdminWeb\AdminWeb.csproj"To="$(PublishDirectory)AdminWeb" /></cc:define></cc:Project>

完整的 ccnet.config:

<cruisecontrol xmlns:cc="urn:ccnet.config.builder"><!-- 全局配置 --><cc:define CIWebSite="http://vm-caihaihua/CCNET/"/><cc:define CIDirectory="C:\CI\"/><cc:define MsBuildPath="C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"/><cc:define MsTestPath="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe"/><cc:define SVNPath="C:\Program Files (x86)\VisualSVN Server\bin\svn.exe"/><cc:define FCReplacerPath="C:\CI\Tools\FCReplacer.exe"/><cc:define DFCopierPath="C:\CI\Tools\DFCopier.exe"/><cc:define name="MsBuildXmlLogger"><logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger></cc:define><!-- Publishers:EmailPublisher--><cc:define name="EmailPublisher"><email mailhost="$(EmailSendHost)" mailport="$(EmailSendPort)"mailhostUsername="$(EmailSendUser)@$(EmailDomain)" mailhostPassword="$(EmailSendPassword)"from="$(EmailSendUser)@$(EmailDomain)"useSSL="$(EmailUseSSL)" includeDetails="true"><!--邮件标题配置--><subjectPrefix>$(EmailSubject)</subjectPrefix><subjectSettings><!-- Success/Broken/StillBroken/Fixed/Exception--><subject buildResult="Success" value="${CCNetProject} ${CCNetBuildDate} Build result"/><subject buildResult="Fixed" value="${CCNetProject} ${CCNetBuildDate} Build result"/><subject buildResult="Broken" value="${CCNetProject} ${CCNetBuildDate} Build result"/><subject buildResult="StillBroken" value="${CCNetProject} ${CCNetBuildDate} Build result" /><subject buildResult="Exception" value="${CCNetProject} ${CCNetBuildDate} Build result" /></subjectSettings>lo<!--收件人配置--><converters><regexConverter find="$" replace="@$(EmailDomain)"/></converters><modifierNotificationTypes><notificationType>Failed</notificationType><notificationType>Fixed</notificationType></modifierNotificationTypes><users><user group="pm" name="$(PMEmailUser)" address="$(PMEmailUser)@$(EmailDomain)"/><user group="ci" name="$(CIEmailUser)" address="$(CIEmailUser)@$(EmailDomain)"/><user group="tl" name="$(TeamLeader)" address="$(TeamLeader)@$(EmailDomain)"/><cc:EmailTesterList/></users><groups><group name="pm"><notifications><!--Always/Success/Change/Fixed/Failed/Exception --><notificationType>Change</notificationType></notifications></group><group name="ci"><notifications><notificationType>Exception</notificationType></notifications></group><group name="tl"><notifications><notificationType>Success</notificationType><notificationType>Fixed</notificationType><notificationType>Failed</notificationType></notifications></group><group name="developer"><notifications><notificationType>Success</notificationType><notificationType>Fixed</notificationType><notificationType>Failed</notificationType></notifications></group><group name="tester"><notifications><notificationType>Fixed</notificationType></notifications></group></groups></email></cc:define><!-- Triggers:ModificationTrigger/DailyBuildTrigger/ProjectTrigger--><cc:define name="ModificationTrigger"><!--源码修改触发--><intervalTrigger seconds="$(ModificationTriggerIntervalSeconds)" buildCondition="IfModificationExists" /></cc:define><cc:define name="DailyBuildTrigger"><!--每日构建--><scheduleTrigger time="$(DailyBuildTriggerTime)" buildCondition="ForceBuild"><weekDays><!--<weekDay>Sunday</weekDay>--><weekDay>Monday</weekDay><weekDay>Tuesday</weekDay><weekDay>Wednesday</weekDay><weekDay>Thursday</weekDay><weekDay>Friday</weekDay><!--<weekDay>Saturday</weekDay>--></weekDays></scheduleTrigger></cc:define><cc:define name="ProjectTrigger"><projectTrigger serverUri="tcp://Server12:21234/CruiseManager.rem" project="$(ListenToProject)"><triggerStatus>$(ProjectTriggerStatus)</triggerStatus><innerTrigger type="intervalTrigger" seconds="$(ProjectTriggerIntervalSeconds)" buildCondition="ForceBuild" /><!--<triggerFirstTime>True</triggerFirstTime>--></projectTrigger></cc:define><!-- SourceControl: SVNSourceControl --><cc:define name="SVNSourceControl"><sourcecontrol type="svn"><trunkUrl>$(SVNTrunkURL)</trunkUrl><executable>$(SVNPath)</executable><workingDirectory>$(CIDirectory)$(WorkingDirectory)</workingDirectory><username>$(SVNUsername)</username><password>$(SVNPassword)</password><revert>True</revert><cleanCopy>$(SvnCleanCopy)</cleanCopy><cleanUp>True</cleanUp><deleteObstructions>True</deleteObstructions></sourcecontrol></cc:define><!-- Tasks: Replace/Build/Publish/Copy/RunTest --><cc:define name="Replace"><exec><executable>$(FCReplacerPath)</executable><buildArgs><cc:Files/><cc:Rules/></buildArgs><buildTimeoutSeconds>$(ReplaceTimeout)</buildTimeoutSeconds><successExitCodes>0</successExitCodes></exec></cc:define><cc:define name="Build"><msbuild><executable>$(MsBuildPath)</executable><buildArgs>/t:build /p:configuration=$(BuildConfiguration)</buildArgs><cc:MsBuildXmlLogger/><workingDirectory>$(CIDirectory)$(WorkingDirectory)</workingDirectory><projectFile>$(SolutionPath)</projectFile></msbuild></cc:define><cc:define name="Publish"><msbuild><executable>$(MsBuildPath)</executable><workingDirectory>$(CIDirectory)$(WorkingDirectory)</workingDirectory><projectFile>$(SolutionPath)</projectFile><buildArgs>/t:ResolveReferences;Compile/t:_CopyWebApplication/p:Configuration=$(PublishConfiguration)/p:WebProjectOutputDir=$(CIDirectory)$(To)/p:OutputPath=$(CIDirectory)$(To)\bin</buildArgs></msbuild></cc:define><cc:define name="Copy"><exec><executable>$(DFCopierPath)</executable><buildArgs>/from=$(CIDirectory)$(From) /to=$(CIDirectory)$(To)</buildArgs><buildTimeoutSeconds>$(CopyTimeout)</buildTimeoutSeconds><successExitCodes>0</successExitCodes></exec></cc:define><cc:define name="RunTest"><exec><executable>$(MSTestPath)</executable><baseDirectory>$(CIDirectory)$(WorkingDirectory)</baseDirectory><buildArgs>/testcontainer:$(TestContainerPath)</buildArgs><buildTimeoutSeconds>$(TestTimeout)</buildTimeoutSeconds></exec></cc:define><!-- 通用配置(模板) --><cc:define name="Project"><project name="$(ProjectName)" queue="$(Queue)" queuePriority="$(QueuePriority)"><webURL>$(CIWebSite)server/local/project/$(ProjectName)/ViewProjectReport.aspx</webURL><!--标签--><labeller type="dateLabeller"/><artifactDirectory>$(CIDirectory)$(ArtifactDirectory)</artifactDirectory><!--项目的目录--><workingDirectory >$(CIDirectory)$(WorkingDirectory)</workingDirectory><!--自动运行时间间隔--><triggers><cc:TriggerList/></triggers><!--对源码修改延迟处理时间间隔--><modificationDelaySeconds>$(ModificationDelaySeconds)</modificationDelaySeconds><maxSourceControlRetries>5</maxSourceControlRetries><!--源代码管理(SVN)--><cc:SourceControl/><state type="state" directory="$(CIDirectory)$(StateDirectory)"/><publishers><modificationHistory onlyLogWhenChangesFound="true"/><statistics/><xmllogger/><artifactcleanup cleanUpMethod="KeepLastXBuilds" cleanUpValue="$(KeepLastXBuilds)" /><!--邮件通知--><cc:EmailPublisher/></publishers><tasks><cc:TaskList/></tasks></project></cc:define><!-- 默认配置 --><cc:define QueuePriority="1"/><cc:define KeepLastXBuilds="300"/><!-- Email 相关 --><cc:define EmailDomain="company.com"/><cc:define EmailSendHost="smtp.live.com"/><cc:define EmailSendPort="25"/><cc:define EmailUseSSL="TRUE"/><cc:define EmailSendUser="ci"/><cc:define EmailSendPassword="******"/><cc:define CIEmailUser="ci"/><cc:define PMEmailUser="pm_1"/><cc:define name="EmailTesterList"><user group="tester" name="tester_1" address="tester_1@$(EmailDomain)"/><user group="tester" name="tester_2" address="tester_2@$(EmailDomain)"/></cc:define><!-- Trigger 相关 --><cc:define ModificationTriggerIntervalSeconds="300"/><cc:define ModificationDelaySeconds="60"/><cc:define ProjectTriggerIntervalSeconds="30"/><cc:define ProjectTriggerStatus="SUCCESS"/><cc:define DailyBuildTriggerTime="18:00"/><!-- SVN 相关 -->    <cc:define SVNUsername="ci"/><cc:define SVNPassword="******"/><cc:define SvnCleanCopy="FALSE"/><cc:define name="SourceControl">        </cc:define><!-- Task 相关 --><cc:define TestTimeout="1800"/><cc:define CopyTimeout="60"/><cc:define ReplaceTimeout="60"/><cc:define BuildConfiguration="DEGUB"/><cc:define PublishConfiguration="RELEASE"/><!-- TestProject: Service 项目 --><queue name="TestProject" duplicates="ApplyForceBuildsReAdd" /><cc:Project ProjectName="TestProject-Servcies"Queue="TesProjectt"WorkingDirectory="TestProject\SourceCode\service_trunk\"ArtifactDirectory="TestProject\Artifact\service\"StateDirectory="TestProject\State\"PublishDirectory="TestProject\Publish\"EmailSubject="[CI-TestProjectService]"ModificationDelaySeconds="30"TeamLeader="caihaihua"><cc:define name="SourceControl"><cc:SVNSourceControl SVNTrunkURL="https://vm-caihaihua/svn/testproject/services/trunk/"SvnCleanCopy="False"/></cc:define><cc:define name="TriggerList"><cc:ModificationTrigger/><cc:DailyBuildTrigger/></cc:define><cc:define name="TaskList"><!-- Config --><cc:Replace><cc:define name="Files">/file=$(CIDirectory)$(WorkingDirectory)WcfService\Web.config/file=$(CIDirectory)$(WorkingDirectory)ManagerTest\App.config/file=$(CIDirectory)$(WorkingDirectory)WcfServiceTest\App.config</cc:define><cc:define name="Rules">/from=Catalog=(?![^;\s']*_log[;\s']+)(=?[^;\s']*)/to=Catalog=service_trunk_ci/from=Source=(=?.*?)(=?[;\s']+)/to=Source=localhost$2/from=http://(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$2.svc/from=http://(=?.*?)/(?!SSO)(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$3.svc/from=http://(=?.*?)/SSO/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/SSO/$2.svc</cc:define></cc:Replace><!-- Build --><cc:Build SolutionPath="TestProjectService.sln"/><!-- Publish --><cc:Copy From="$(WorkingDirectory)WcfService"To="$(PublishDirectory)WcfService"/></cc:define></cc:Project><cc:Project ProjectName="TestProjectServcies-Test"Queue="TestProject"QueuePriority="2"WorkingDirectory="TestProject\SourceCode\service_trunk\"ArtifactDirectory="TestProject\Artifact\test\"StateDirectory="TestProject\State\"EmailSubject="[CI-TestProjectServcie-Test]"ModificationDelaySeconds="30"TeamLeader="caihaihua"><cc:define name="TriggerList"><cc:ProjectTrigger ListenToProject="TestProject-Servcies"/></cc:define><cc:define name="TaskList"><!--Run Test--><cc:RunTest TestContainerPath="ManagerTest\bin\Debug\ManagerTest.dll"/><cc:RunTest TestContainerPath="WcfServiceTest\bin\Debug\WcfServiceTest.dll"/></cc:define></cc:Project><!-- TestProject: AdminWeb 项目 --><cc:Project ProjectName="TestProject-AdminWeb"Queue="TestProject"WorkingDirectory="TestProject\SourceCode\admin_trunk\"ArtifactDirectory="TestProject\Artifact\admin\"StateDirectory="TestProject\State\"PublishDirectory="TestProject\Publish\"EmailSubject="[CI-TestProject-AdminWeb]"TeamLeader="caihaihua"><cc:define name="SourceControl"><cc:SVNSourceControl SVNTrunkURL="https://vm-caihaihua/svn/testproject/adminweb/trunk/"/></cc:define><cc:define name="TriggerList"><cc:ModificationTrigger/><cc:DailyBuildTrigger/></cc:define><cc:define name="TaskList"><!-- Config --><cc:Replace><cc:define name="Files">/file=$(CIDirectory)$(WorkingDirectory)AdminWeb\Web.config</cc:define><cc:define name="Rules">/from=http://(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$2.svc/from=http://(=?.*?)/(?!SSO)(=?[^\/]+)/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/WcfService/$3.svc/from=http://(=?.*?)/SSO/(=?[^\/]+).svc/to=http://vm-caihaihua/testproject_trunk_ci/SSO/$2.svc</cc:define></cc:Replace><!-- Build --><cc:Build SolutionPath="AdminWeb.sln"/><!-- Publish --><cc:Publish SolutionPath="AdminWeb\AdminWeb.csproj"To="$(PublishDirectory)AdminWeb" /></cc:define></cc:Project>
</cruisecontrol>

View Code

转载于:https://www.cnblogs.com/harveyChoi/p/hello_cc_net_3.html

【Hello CC.NET】巧用模板简化配置相关推荐

  1. Spring事务支持:利用继承简化配置

    因为事务代理的实现类是 TransactionProxyFactoryBean . 事务代理Bean必须注入事务管理器. 大部分情况下,每个事务代理的事务属性大同小异,对于这种情况,Spring提供了 ...

  2. easycode 表配置_idea的easyCode的 MybatisPlus模板的配置详解

    EasyCode 插件 EasyCode 插件 是一款根据表结构生成代码的很方便的Idea插件, 强烈推荐. 并且可以自定义模板来控制生成的类 我在使用的过程中发现一些问题,现在把解决办法记录下来, ...

  3. seci-log 1.11 发布 增加了ftpserver,远程ftp,sftp采集简化配置等功能

    2019独角兽企业重金招聘Python工程师标准>>> 日志分析软件 seci-log 1.11发布,增加了增加了ftpserver,远程ftp,sftp采集简化配置等功能.上篇文章 ...

  4. android 选择ppt模板,微软Office安卓手机版使用攻略:巧用模板可事半功倍

    微软Office安卓手机版使用攻略:巧用模板可事半功倍 2015年06月26日 15:31作者:广州分站文章出处:泡泡网原创 分享 6月25日,微软安卓手机端Office三款核心应用正式通过腾讯应用宝 ...

  5. Spring-注入参数详解-[简化配置方式]

    概述 字面属性值 字面值属性 构造函数参数 集合元素 引用对象属性 字面值属性 构造函数参数 集合元素 使用P命名空间 通过p命名空间引用字面属性值 通过p命名空间引用其他bean 概述 Spring ...

  6. 大数据WEB阶段Spring框架(二)简化配置的操作

    Spring简化配置的操作 零.复习 IOC控制反转, 之前是通过new创建对象 , IOC是由Spring容器创建对象 , 需要用时getBean获取 . 导入约束文件 获取对象两种方式 : 通过I ...

  7. Spring+Mybatis使用MapperScannerConfigurer简化配置__MapperScannerConfigurer的作用

    Spring+Mybatis使用MapperScannerConfigurer简化配置 MyBatis的一大亮点就是可以不用DAO层的实现类,而我们知道service层调dao层 如果没有实现类,Sp ...

  8. php smarty模板配置,Smarty模板简单配置与使用方法示例

    这篇文章主要介绍了Smarty模板简单配置与使用方法,涉及Smarty模板的基本配置与缓存文件的相关使用技巧,需要的朋友可以参考下 本文实例讲述了Smarty模板简单配置与使用方法.分享给大家供大家参 ...

  9. Spring 简化配置(了解/不推荐)

    >p命名空间 作用:对属性(成员变量)配置简化 xmlns:p="http://www.springframework.org/schema/p" >c命名空间 作用: ...

最新文章

  1. 计算机组成原理两数相加指令,计算机组成原理复习题
  2. 小结 frambuffer 原理及流程 (五)
  3. python经典案例-20个Python练手经典案例,能全做对的人确实很少!
  4. 『转载』在vs2008(2005)winform中,打开office文档
  5. DRBD+HeartBeat+NFS 架构
  6. 二分图----最大匹配,最小点覆盖,最大点独立集
  7. java nextgaussian(),java.util.Random.nextGaussian()
  8. 主流物联网平台的架构设计思考
  9. 批处理框架 Spring Batch,数据迁移量过大如何保证内存?
  10. 塔菲尔曲线斜率的大小_中国第一塔,与埃菲尔铁塔齐名,到底有多强悍?
  11. 物流管理系统(SSM+vue+shiro)【前后台】
  12. STM32MP157 Linux系统移植开发篇19:Linux内核Wi-Fi驱动移植
  13. 收藏不迷路 —— Flutter 转场动效大合集
  14. PHP开发阿里云短信服务接口
  15. uniapp实现下拉加载更多 u-loadmore
  16. Matlab 动态输入变量和嵌套函数、匿名函数
  17. workerman GatewayWorker配置wss服务
  18. Centos7安装vsftp服务,配置用户,并使用nginx开启访问
  19. 【笔记】面向数据科学家的实用统计学
  20. 13、《Libevent中文帮助文档》学习笔记13:Linux下集成、运行libevent

热门文章

  1. 我是如何用 Redis 做实时订阅推送的?
  2. 分布式事务科普(终结篇)
  3. 你写的 Java 代码是如何一步步输出结果的
  4. 小米自动化运维平台演进设计思路
  5. 谈谈怎么做【服务隔离】
  6. 区块链及比特币入门指南
  7. 大型分布式网站术语分析 15 条,你知道几条?
  8. jQuery 中jQuery/$的数据类型是什么?
  9. Linux通常把设备对象抽象为,linux 设备模型(1)
  10. 用java写游戏_用java写的扫雷游戏