zoukankan      html  css  js  c++  java
  • 【Hello CC.NET】巧用模板简化配置

      从 《【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:WindowsMicrosoft.NETFrameworkv4.0.30319MSBuild.exe"/>
        <cc:define MsTestPath="C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEMSTest.exe"/>
        <cc:define SVNPath="C:Program Files (x86)VisualSVN Serverinsvn.exe"/>
        <cc:define FCReplacerPath="C:CIToolsFCReplacer.exe"/>
        <cc:define DFCopierPath="C:CIToolsDFCopier.exe"/>
        <cc:define name="MsBuildXmlLogger">
            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:Program Files (x86)CruiseControl.NETserverThoughtWorks.CruiseControl.MsBuild.dll</logger>
        </cc:define>

      

    变量名称 描述
    CIWebSite CC.NET配套网站的地址 http://vm-caihaihua/CCNET/
    CIDirectory 工作目录 C:CI
    MsBuildPath MsBuild 程序的地址 C:WindowsMicrosoft.NETFrameworkv4.0.30319MSBuild.exe
    MsTestPath MsTest 程序的地址 C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEMSTest.exe
    SVNPath Svn 程序的地址 C:Program Files (x86)VisualSVN Serverinsvn.exe
    FCReplacerPath FCReplacer 程序的地址 C:CIToolsFCReplacer.exe
    DFCopierPath DFCopier 程序的地址 C:CIToolsDFCopier.exe
    MsBuildXmlLogger 日志 Logger 的配置 <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:Program Files (x86)CruiseControl.NETserverThoughtWorks.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)WcfServiceWeb.config
    /file=$(CIDirectory)$(WorkingDirectory)ManagerTestApp.config
    /file=$(CIDirectory)$(WorkingDirectory)WcfServiceTestApp.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)in
                    </buildArgs>
            </msbuild>
        </cc:define>

      模板变量:

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

       例子:

           <tasks>
                <!-- Publish -->
                <cc:Publish SolutionPath="WcfServiceWcfService.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)WcfService
                         To="$(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="ManagerTestinDebugManagerTest.dll"/>
                <cc:RunTest TestContainerPath="WcfServiceTestinDebugWcfServiceTest.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="TestProjectSourceCodeservice_trunk"
                    ArtifactDirectory="TestProjectArtifactservice"
                    StateDirectory="TestProjectState"
                    PublishDirectory="TestProjectPublish"
                    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)WcfServiceWeb.config
                        /file=$(CIDirectory)$(WorkingDirectory)ManagerTestApp.config
                        /file=$(CIDirectory)$(WorkingDirectory)WcfServiceTestApp.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="TestProjectSourceCodeservice_trunk"
                    ArtifactDirectory="TestProjectArtifact	est"
                    StateDirectory="TestProjectState"
                    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="ManagerTestinDebugManagerTest.dll"/>
                <cc:RunTest TestContainerPath="WcfServiceTestinDebugWcfServiceTest.dll"/>
            </cc:define>
        </cc:Project>
        
        <!-- TestProject: AdminWeb 项目 -->
        <cc:Project ProjectName="TestProject-AdminWeb"
                    Queue="TestProject"
                    WorkingDirectory="TestProjectSourceCodeadmin_trunk"
                    ArtifactDirectory="TestProjectArtifactadmin"
                    StateDirectory="TestProjectState"
                    PublishDirectory="TestProjectPublish"
                    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)AdminWebWeb.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="AdminWebAdminWeb.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:WindowsMicrosoft.NETFrameworkv4.0.30319MSBuild.exe"/>
        <cc:define MsTestPath="C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEMSTest.exe"/>
        <cc:define SVNPath="C:Program Files (x86)VisualSVN Serverinsvn.exe"/>
        <cc:define FCReplacerPath="C:CIToolsFCReplacer.exe"/>
        <cc:define DFCopierPath="C:CIToolsDFCopier.exe"/>
        <cc:define name="MsBuildXmlLogger">
            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:Program Files (x86)CruiseControl.NETserverThoughtWorks.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)in
                </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="TestProjectSourceCodeservice_trunk"
                    ArtifactDirectory="TestProjectArtifactservice"
                    StateDirectory="TestProjectState"
                    PublishDirectory="TestProjectPublish"
                    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)WcfServiceWeb.config
                        /file=$(CIDirectory)$(WorkingDirectory)ManagerTestApp.config
                        /file=$(CIDirectory)$(WorkingDirectory)WcfServiceTestApp.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="TestProjectSourceCodeservice_trunk"
                    ArtifactDirectory="TestProjectArtifact	est"
                    StateDirectory="TestProjectState"
                    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="ManagerTestinDebugManagerTest.dll"/>
                <cc:RunTest TestContainerPath="WcfServiceTestinDebugWcfServiceTest.dll"/>
            </cc:define>
        </cc:Project>
        
        <!-- TestProject: AdminWeb 项目 -->
        <cc:Project ProjectName="TestProject-AdminWeb"
                    Queue="TestProject"
                    WorkingDirectory="TestProjectSourceCodeadmin_trunk"
                    ArtifactDirectory="TestProjectArtifactadmin"
                    StateDirectory="TestProjectState"
                    PublishDirectory="TestProjectPublish"
                    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)AdminWebWeb.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="AdminWebAdminWeb.csproj"
                            To="$(PublishDirectory)AdminWeb" />
            </cc:define>
        </cc:Project>
    </cruisecontrol>
    View Code
  • 相关阅读:
    [ELK] Elasticsearch 安装/配置、启动/停止、加节点/重启
    [ELK] Elastic Stack 的安全性预览
    [Gin] gin.H{} 与 map[string]interface{}
    [Go] 浅谈 Golang struct 与 PHP class 的相似
    [FAQ] Git 修改最后一次的提交人和提交时间 ?
    [Blockchain] 开发完真实的 DApp 后才能得出的结论与看法
    Android 5.0 Phone初始化分析
    推荐一个Android开发懒人库 -- ButterKnife
    ffmpeg 移植到 android 并使用
    为app录制展示gif
  • 原文地址:https://www.cnblogs.com/harveyChoi/p/hello_cc_net_3.html
Copyright © 2011-2022 走看看