在CruiseControl.NET中构建具有项目依赖性的顺序

时间:2009-06-12 19:21:29

标签: .net continuous-integration cruisecontrol.net

在我们的.NET软件开发商店中,我们设置了CruiseControl.NET来构建28个项目,其中一些是相互依赖的。每个项目大致代表一个Visual Studio项目或Flex库与单元测试配对。我很恼火的是,我没有找到一个好的方法来确保项目按照表示依赖关系的顺序构建。

这就是我在做的事情:

  1. 所有内容都在同一个构建队列中。我这样做是为了按顺序完成构建,因此我可以避免需要多个工作目录。
  2. 我在项目上设置队列优先级,我认为这会影响他们的构建顺序。但是在仔细阅读文档之后,我发现它只是在队列中有多个构建请求时控制优先级。
  3. 除了使用区间触发器启动构建之外,我还使用项目触发器,以便在依赖项成功构建时,它们的依赖项也会构建。
  4. 在某种程度上,此设置有效。主要问题是如果某人对项目A和项目B中的代码进行了更改,其中项目B依赖于项目A.有时,项目B将在项目A之前构建。因为项目A尚未构建,所以可以有时导致项目B破裂。这是暂时的,因为间隔触发器导致项目A稍后构建,并且其成功构建触发项目B重建并得到修复。我想要避免的是在项目A之前建造项目B,以便不会发生中间破坏。

    您使用哪些实践来正确管理CruiseControl.NET服务器上的相互依赖性?此时,我不愿意改为像TeamCity这样的非自由持续集成包。

3 个答案:

答案 0 :(得分:8)

不要将依赖项放在CC.NET项目设置中。您需要通过NAnt脚本控制项目构建顺序。您不必构建在解决方案级别上,您可以在单个项目级别上构建。

<target name="Project1" depends="Projects2" description="Builds project 1">
     <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\dev\ccnet</workingDirectory>
        <projectFile>CCNet.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
        <targets>Build;Test</targets>
        <timeout>900</timeout>
        <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
     </msbuild>
</target>

<target name="Project2" depends="Projects3" description="Builds project 2">
     <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\dev\ccnet</workingDirectory>
        <projectFile>CCNet.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
        <targets>Build;Test</targets>
        <timeout>900</timeout>
        <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
     </msbuild>
</target>

<target name="Project3" description="Builds Project 3">
     <msbuild>
            <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
            <workingDirectory>C:\dev\ccnet</workingDirectory>
            <projectFile>CCNet.sln</projectFile>
            <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
            <targets>Build;Test</targets>
            <timeout>900</timeout>
            <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
     </msbuild>
</target>

您可以在单个项目级别上运行单元测试,因此您不需要在多个项目上进行重复运行。

答案 1 :(得分:2)

我建议您不要使用visual studio项目来交叉CruiseControl项目的概念!我通常建立一个包含大量工作的CC项目。对我来说,这意味着CC项目将运行一个NAnt脚本。 NAnt脚本对我的工作和时间进行了非常精细的控制。这意味着我可以构建我的解决方案(它知道首先要构建哪个项目!),运行我的单元测试,重置数据库,部署一些代码,发送一些电子邮件,进行一些代码分析(NDepend和NCover很棒!),这意味着我有一个项目出现在CCTray中,这使事情更加真实。然后,我可以在CC中创建一个新项目,以控制从DEV推送到STAGING以及从STAGING到PROD的时间,以便我们可以“按下”此任务。但是,这仅产生了3个巡航控制项目,并且更加用户友好。

答案 2 :(得分:2)

虽然你已经接受了答案,但我会建议别的:你不应该在两个项目之间有直接的依赖关系。通过“直接”我的意思是每当项目A中的二进制文件发生变化时,这并不意味着你会自动使用它们来构建项目B.

更新这些引用的过程应由(由您)控制,否则您将不可避免地最终为项目B打破大量的构建。

我倾向于将所有外部二进制文件保存在源代码管理下的 lib 目录(和子目录)下,并且只有在我决定这样做时才更新它们。而“外部”我指的是第三方图书馆和我公司其他项目的图书馆(例如:http://code.google.com/p/projectpilot/source/browse/#svn/trunk/lib