Can Cruise Control attempt to start a build before fully downloading an svn commit
I have an app and shared library with separate CC build triggers (a successful library build will also trigger a build of the app), with a queue set up to make sure that CC doesn't attempt to build the app until the library is finished.
Something weird happened this morning. I'm working over a slowish VPN and committed a bunch of changes to my app and a shared library (this was all done as a single commit). CC did a build of my app first which failed because it couldn't find two new classes in the shared library. After this the shared library built successfully, followed by my app building successfully.
It looks like CC attempted to build after the changes to my app had been downloaded to the build server, but before the changes to the library had arrived. Is this possible, or do I need to look elsewhere to find out what was the cause?
This is the error I got in the build log for the application:
<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>
An excerpt from my CCnet.config file is below:
<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.CruiseC开发者_C百科ontrol.MsBuild.dll</logger>
<timeout>1000000</timeout>
</msbuild>
</tasks>
</project>
Subversion commits are atomic, so this should not be possible. Cruise control should not see any new files until the checkin is complete. You'll have to put the blame elsewhere.
Unless you're actually using two separate subversion repositories (perhaps using svn:external?)
I've had a similar issue with CC.Net, but not on SVN. I'm not familiar with how their commits work. But on my SCM, CC.Net polled the server for changes in the middle of a check-in and launched a build, even though there were other files getting checked in.
Personally, I didn't worry about it, because it was a perfect storm where the CC.Net trigger happened to get fired in the middle of a check-in. In my almost 3 years of using CC.Net, I'd say that's happened twice.
SVN commits are atomic. Nothing can fetch your commit until it is all posted to the server. What I think you are seeing is the default non-queuing behavior in CC.NET.
To prevent this, you need to set the queue attribute on the project element:
<project name="build_shared_library" queue="my-lock-value">...
<project name="build_app" queue="my-lock-value">...
Both the library and the app should have the same value in the queue attribute.
I think you said it all in your question:
CC did a build of my app first which failed because it couldn't find two new classes in the shared library. After this the shared library built successfully, followed by my app building successfully.
There was no way for CC.NET to know that the changes to your app depended on changes to your library. Your configuration doesn't say that the "sharedLib" project must be built before the "App1" project is built, it just says that if they're both in the queue at the same time, "sharedLib" goes first.
You may want to consider having the "sharedLib" project trigger builds of the "App1" project.
精彩评论