【问题标题】:Can Cruise Control attempt to start a build before fully downloading an svn commitCruise Control 可以在完全下载 svn 提交之前尝试启动构建吗
【发布时间】:2010-02-01 23:36:49
【问题描述】:

我有一个应用程序和共享库,其中包含单独的 CC 构建触发器(成功的库构建也将触发应用程序的构建),并设置了一个队列以确保 CC 不会尝试构建应用程序,直到图书馆完成了。

今天早上发生了一件奇怪的事情。我正在使用速度较慢的 VPN,并对我的应用程序和共享库进行了一系列更改(这一切都是作为一次提交完成的)。 CC 首先构建了我的应用程序,但失败了,因为它在共享库中找不到两个新类。在此之后共享库构建成功,随后我的应用构建成功。

看起来 CC 在我的应用程序的更改下载到构建服务器之后,但在库的更改到达之前尝试构建。这可能吗,还是我需要在其他地方寻找原因?

这是我在应用程序的构建日志中得到的错误:

<error code="CS0246" file="SomeClass.cs" line="###" column="###"><![CDATA[The type or namespace name 'ClassAddedToSharedLibraryInThisCommit' could not be found (are you missing a using directive or an assembly reference?)]]></error>

我的 CCnet.config 文件摘录如下:

 <project name="App1" queue="hourly" queuePriority="2">
    <triggers>
      <multiTrigger operator="Or">
        <triggers>
          <projectTrigger project="sharedLib">
            <triggerStatus>Success</triggerStatus>
            <innerTrigger type="intervalTrigger" seconds="30" buildCondition="ForceBuild"/>
          </projectTrigger>
          <filterTrigger startTime="16:00" endTime="7:00">
            <trigger type="intervalTrigger" seconds ="625" />
          </filterTrigger>
        </triggers>
      </multiTrigger>
    </triggers>
   <sourcecontrol type="svn">
      <tagOnSuccess>false</tagOnSuccess>
      <tagBaseUrl>https://servername/...</tagBaseUrl>
      <autoGetSource>true</autoGetSource>
      <executable>c:\program files\subversion\bin\svn.exe</executable>
      <trunkUrl>https://servername/.../App1/...</trunkUrl>
      <workingDirectory>C:\svn\...\App1\...</workingDirectory>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe</executable>
        <workingDirectory>C:\svn\...\App1\...</workingDirectory>
        <projectFile>App1.sln</projectFile>
        <buildArgs>/p:Configuration=Debug /v:m /m</buildArgs>
        <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        <timeout>1000000</timeout>
      </msbuild>
    </tasks>
  </project>
 <project name="sharedLib" queue="hourly" queuePriority="1">
    <triggers>
      <filterTrigger startTime="16:00" endTime="7:00">
        <trigger type="intervalTrigger" seconds ="350" />
      </filterTrigger>
    </triggers>
    <sourcecontrol type="svn">
      <tagOnSuccess>false</tagOnSuccess>
      <tagBaseUrl>https://servername/...</tagBaseUrl>
      <autoGetSource>true</autoGetSource>
      <executable>c:\program files\subversion\bin\svn.exe</executable>
      <trunkUrl>https://https://servername/.../SharedLib/...</trunkUrl>
      <workingDirectory>C:\svn\...\sharedLib\...</workingDirectory>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe</executable>
        <workingDirectory>C:\svn\...\sharedLib\...</workingDirectory>
        <projectFile>sharedLib.csproj</projectFile>
        <buildArgs>/p:Configuration=Debug /v:m /m</buildArgs>
        <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        <timeout>1000000</timeout>
      </msbuild>
    </tasks>
  </project>

【问题讨论】:

    标签: svn cruisecontrol.net


    【解决方案1】:

    Subversion 提交是atomic,所以这应该是不可能的。在签入完成之前,巡航控制不应看到任何新文件。你必须把责任推到别处。

    除非您实际上使用两个独立的颠覆存储库(可能使用 svn:external?)

    【讨论】:

    • 只有一个存储库,但请参阅我的 cmets 以咨询utah。
    【解决方案2】:

    我在 CC.Net 上遇到过类似的问题,但在 SVN 上没有。我不熟悉他们的提交是如何工作的。但是在我的 SCM 上,CC.Net 在签入过程中轮询服务器以获取更改并启动构建,即使还有其他文件正在签入。

    就我个人而言,我并不担心,因为这是一场完美风暴,CC.Net 触发器恰好在签到过程中被触发。在我使用 CC.Net 近 3 年的时间里,我会说这种情况发生过两次。

    【讨论】:

    • 这听起来像是发生在我身上的事。我想我认为 CC 与源代码控制系统有更紧密的集成。
    • 是的,但是从其他 cmets 看来,这在 SVN 上似乎是不可能的。我的 SCM 允许原子或非原子签入。我使用的是非原子(因为它是默认的)
    【解决方案3】:

    SVN 提交是原子的。在将其全部发布到服务器之前,没有任何东西可以获取您的提交。我认为您看到的是 CC.NET 中的默认非排队行为。

    为防止这种情况,您需要在项目元素上设置队列属性:

    <project name="build_shared_library" queue="my-lock-value">...
    <project name="build_app" queue="my-lock-value">...
    

    库和应用程序在队列属性中应该具有相同的值。

    【讨论】:

    • 我们设置了一个队列,但我看到的似乎与队列问题不一致。共享库作为完整项目包含在解决方案中,而不仅仅是作为二进制 dll 链接。因此,如果我的应用首先构建,它也应该编译库中的代码,同时尝试构建库由于文件锁定而失败。
    • 巡航控制是否真的检查 SVN 服务器以查看是否有新的提交,并等待所有文件复制到构建服务器(SVN 服务器及其数据存储在单独的系统);还是只是在观看 SVN 客户端的本地副本将文件移动到的文件夹? AFAIK NTFS 不支持对多个文件的原子操作,这意味着即使 SVN 将文件 1-10 的更改视为单个事件,也会有一段时间只有文件 1-8 在构建服务器上,而 9 和 10仍在下载中。
    • CC.NET 只是针对服务器运行一个 SVN 日志以查看是否有新的更改,因此在您开始构建之前它们应该都在那里。
    • 我将记录的错误消息添加到我的问题中。除了在所有文件从 svn 服务器复制到构建机器之前触发触发之外,我看不到任何解释它的方法。为返回新类型的两种方法都记录了错误。
    • Dan,你能把你的 ccnet.config 文件的相关部分贴出来吗? IT 不需要太详细,但获取项目、任务和 svn 配置(当然要减去任何用户名/密码)可能会有所帮助。
    【解决方案4】:

    我想你在你的问题中都说完了:

    CC 首先构建了我的应用程序,但失败了,因为它在共享库中找不到两个新类。在此之后共享库构建成功,随后我的应用构建成功。

    CC.NET 无法知道对应用程序的更改取决于对库的更改。您的配置并没有说必须在构建“App1”项目之前构建“sharedLib”项目,它只是说如果它们同时在队列中,则“sharedLib”先行。

    您可能需要考虑让“sharedLib”项目触发“App1”项目的构建。

    【讨论】:

    • 这是执行此操作的触发器(app1 的两个触发器中的第一个)。 App1 需要能够在仅对其进行更改时自行构建。由于 sharedLib 是 app1 解决方案的一部分,App1 应在必要时构建它,无需任何额外干预。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多