How to run a task before updating source files? - cruisecontrol.net

I need to run a task in CruiseControl .NET before checking for modification in source control. I mean this task should be the very first thing that CruiseControl will always do. I see
<prebuild> section in cc.config, but it is for running tasks before building a solution, so it is not exactly what I need.

Prebuild DOES fire before the source control get. It comes after the source control block but still fires first. Here's an example I've been using:
<cb:define subversionpath="c:\Program Files\Subversion\bin\svn.exe"
/>
<cb:define name="svn50">
<executable>$(subversionpath)</executable>
<workingDirectory>D:\Projects\B50\Source</workingDirectory>
<trunkUrl>svn://machineName/branches/B_50/Source</trunkUrl>
<autoGetSource>true</autoGetSource>
</cb:define>
<project name="StreamlineCheckBuild" queue="B50">
<triggers>
<intervalTrigger seconds="180" />
</triggers>
<sourcecontrol type="svn">
<cb:svn50/>
<deleteObstructions>true</deleteObstructions>
<forceUpdate>true</forceUpdate>
</sourcecontrol>
<prebuild>
<exec>
<executable>$(subversionpath)</executable>
<buildArgs>cleanup</buildArgs>
<baseDirectory>D:\Projects\B50</baseDirectory>
</exec>
</prebuild>
<tasks>
...
</tasks>
</cruisecontrol>

Use batch file as proxy for the version control utility, eg. svn.bat:
echo do stuff
"c:\program files\Subversion\svn.exe" %*
Use executable atrribute to point to the bach file.

Related

cruise control.NET perforce all commits ever are modifications

I've got a cruise control server running and successfully building my project. However, my interval trigger (set to IfModificationExists) is registering the entire changelist in the history of the database as modifications every time it tries to build, and therefore builds on every interval regardless of whether there's a new commit. Any suggestions? Here are the relevant bits of my config file:
<cruisecontrol>
<project name="MyProj">
<artifactDirectory>C:\CCNet\Artifacts\</artifactDirectory>
<!-- TRIGGER THE CHECK TO BUILD EVERY HOUR -->
<triggers>
<!-- check the source control every X time for changes,
and run the tasks if changes are found -->
<intervalTrigger
name="continuous"
seconds="3600"
buildCondition="IfModificationExists"
initialSeconds="5"/>
</triggers>
<workingDirectory>C:\PerforceFiles\</workingDirectory>
<!-- CHECK FOR CHANGES IN PERFORCE, EXCLUDE .CHM FILES SINCE THEY ARE CHECKED IN AS PART OF THIS BUILD -->
<sourcecontrol type="filtered">
<sourceControlProvider type="p4">
<view>//depot/Folder1/... //cruisecontrol_server/Folder1/..., //depot/Folder2/... //cruisecontrol_server/Folder2/..., //depot/Folder3/... //cruisecontrol_server/Folder3/..., //depot/Folder4/... //cruisecontrol_server/Folder4/...</view>
<executable>C:\Program Files\Perforce\p4.exe</executable>
<workingDirectory>C:\PerforceFiles</workingDirectory>
<client>cruisecontrol_server</client> <!-- this workspace's tree is equivalent to the view listed above -->
<user>cruisecontrol</user>
<port>myPort</port>
<applyLabel>false</applyLabel>
<autoGetSource>true</autoGetSource>
<forceSync>false</forceSync>
</sourceControlProvider>
<exclusionFilters>
<pathFilter>
<pattern>/**/*.chm</pattern>
</pathFilter>
</exclusionFilters>
</sourcecontrol>
The remainder of the file is just my tasks and publishers, which I don't think would be relevant. If there is more information you need, let me know and I'll respond as quickly as I can.
It looks right to me, this is the filtered block I'm using with SVN and is working properly:
<sourcecontrol type="filtered">
<sourceControlProvider type="svn">
<executable>$(svnConsole)</executable>
<username>username</username>
<password>password</password>
<autoGetSource>true</autoGetSource>
<trunkUrl>https://trunkurl</trunkUrl>
<workingDirectory>$(DevelopmentDir)\</workingDirectory>
</sourceControlProvider>
<exclusionFilters>
<pathFilter>
<pattern>**/AssemblyInfo.cs</pattern>
</pathFilter>
</exclusionFilters>
</sourcecontrol>
This excludes every AssemblyInfo.cs file on the trunk.
Hope this helps!

Multi Projects with CCNET

I have GIT repo as below,
\main
\Module A
\Module B
\Shared
When i make a change on Module B, CCNET will make a build from Module A and then Module B,
I dont want CCNET to do this way.It will take a lot of time.
I just want ccnet build only changes on Module B.
Somebody please help me :
My 1 project in CCNET Config:
enter code here
<project name="Dashboard 5.0" queue="Dashboard_01" queuePriority="01" category="01">
<artifactDirectory>&pathToArtifactsDirectory;Dashboard 5.0\</artifactDirectory>
&workingDirectory;
<webURL>http://&buildServerAddress;/ccnet/server/&buildServerName;/project/Dashboard 5.0/ViewLatestBuildReport.aspx</webURL>
&modificationDelaySeconds;
<triggers>
<intervalTrigger seconds='30' buildCondition='IfModificationExists'/>
<scheduleTrigger time='03:00' buildCondition='ForceBuild' name='Scheduled'/>
<scheduleTrigger time='11:00' buildCondition='ForceBuild' name='Scheduled'/>
</triggers>
<state type="state" directory="&pathToStatesDirectory;Dashboard 5.0\" />
<sourcecontrol type="git">
<repository>&gitAddress;</repository>
<branch>master</branch>
<autoGetSource>true</autoGetSource>
<fetchSubmodules>false</fetchSubmodules>
<executable>C:\Program Files (x86)\Git\cmd\git.exe</executable>
<commitBuildModifications>false</commitBuildModifications>
<commitUntrackedFiles>false</commitUntrackedFiles>
<timeout>3000000</timeout>
</sourcecontrol>
<tasks>
<nant>
<executable>&pathToNantFile;</executable>
<baseDirectory>&pathToBuildScriptsDirectory;Dashboard 5.0\</baseDirectory>
<buildArgs>-D:projects_to_build=dashboard_framework</buildArgs>
<buildFile>cruise.build</buildFile>
<targetList>
<target>automate</target>
</targetList>
<buildTimeoutSeconds>3000</buildTimeoutSeconds>
</nant>
</tasks>
<publishers>
<merge>
<files>
<file>&pathDB5MainCheckoutDirectory;framework\build\test-reports\*Test.dll-results.xml</file>
<file>&pathDB5MainCheckoutDirectory;framework\build\test-reports\Test*.dll-results.xml</file>
<file>&pathDB5MainCheckoutDirectory;framework\build\test-reports\simian.xml</file>
</files>
</merge>
<xmllogger />
</publishers>
Any check in for Module A or Module B will cause the project node to start either way. What you are looking for is similar to what subversion update command on a sub folder does and Git is not intended to be this way. An alternative you can create a separate repository for each module. The build script or Nant task would have to be separated as well.
In Git, if you have several directories that are always checked out independently, then these are really two different projects and should live in two different repositories. You can merge them back together at a later point using Git Submodules

How do I configure two different triggers for a project in CruiseControl.Net?

I would like to know if its possible to create two triggers, one on a filesystem and another for an svn checkout in the same config file.
I have tried out the following:
a) have put both the triggers and their respective filesystem, svn definitions along with tasks in the same file,
Results in error: It says unused node deteted
eg:
<trigggers>
<intervalTrigger seconds="100" buildCondition="ForceBuild"/>
<intervalTrigger seconds="300" buildCondition="IfModificationExists"/>
</triggers>
<sourcecontrol type="filesystem">
<repositoryRoot>...</repositoryRoot>
</sourcecontrol>
<sourcecontrol type="svn">
<trunkUrl>....</trunkUrl>
<workingDirectory>...</workingDirectory>
<executable>...\SVN.exe</executable>
<username/>..<password/>
</sourcecontrol>
<tasks>
<!-- To be carried out if either of the two triggers happen -->
</tasks>
b) have created different scopes for each of the trigger bound with respective filesystem/svn and tasks, also ends up with unused node detected error.
<cb:define first_trigger_and source _and_tasks>
<triggers>
<intervalTrigger seconds="300" buildCondition="ForceBuild"/>
</triggers>
<sourcecontrol type="filesystem">
<repositoryRoot>...</repositoryRoot>
</sourcecontrol>
<tasks>
<!--To be carried out when first trigger happens -->
</tasks>
</cb:define>
<!-- And then I call the trigger this way -->
<cb:first_trigger_and source _and_tasks>
Neither of those solution works.
Multiple triggers can be specified inside the <triggers> block, but that is not why CruiseControl.Net is complaining when it's processing your configuration.
It seems to me that you want a single trigger, but two separate source control entries. The <triggers> entries specify when CruiseControl.Net should wake up and check the project state. You can't specify multiple <sourcecontrol> elements in a <project> block. To actually rebuild project on both (remote) svn changes and local filesystem changes, you should use <sourcecontrol type="multi"> with a standard trigger:
<triggers>
<intervalTrigger seconds="30" />
</triggers>
<sourcecontrol type="multi">
<sourceControls>
<filesystem>
<repositoryRoot>...</repositoryRoot>
</filesystem>
<svn>
<trunkUrl>....</trunkUrl>
<workingDirectory>...</workingDirectory>
<executable>...\SVN.exe</executable>
<username/>..<password/>
</svn>
</sourceControls>
</sourcecontrol>
<tasks>
<!-- To be executed if either of the two source control providers report changes -->
</tasks>

How to commit into TortoiseSVN using cruise control config file

hi all,
can any one tell how to commit into
tortoisesvn using cruise control
config file. I am getting an error
"C:*****\Documentation\trunk\dotnet\svn"
is not executable or it may not exist.
here's the config part...
<workingDirectory>C:\*****\Documentation\trunk\dotnet\</workingDirectory>
<category>Individual Solutions</category>
<modificationDelaySeconds>10</modificationDelaySeconds>
<sourcecontrol type="svn">
<trunkUrl>******* svn url *********</trunkUrl>
<username> unname </username>
<password> pwd </password>
<autoGetSource>true</autoGetSource>
</sourcecontrol>
<tasks>
<exec>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
<successExitCodes>0</successExitCodes>
</exec>
<exec>
<executable>iisreset</executable>
<buildArgs>/stop</buildArgs>
</exec>
<exec>
<executable>c:\Program Files\TortoiseSVN\bin\TortoiseProc.exe /command:commit /path:"C:\*****\Documentation\trunk\dotnet\"</executable>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
<successExitCodes>0</successExitCodes>
<description>checkin shared content...</description>
</exec>
<exec>
<executable>iisreset</executable>
<buildArgs>/start</buildArgs>
</exec>
</tasks>
</project>
Thank you all,
There's a few things:
You want to pass the command-line arguments to in the <buildArgs> element, not as part of the <executable> element (like you've done for the "issreset" command, for example).
Why are you checking stuff in after every build? The way you seem to have things set up here, it's just going to go into an infinite loop, building then checking in and building again (because it detected a new check-in). Generally, you don't check build outputs into your repository.

Cruise control merging?

I had successfully extracted the compilation log present in my IDE into some one xml file very well. So in order to merge it I had mentioned in my ccnet.config file inside the publisher task using the <merge>
section.
But when I force my build, I am able to get the output.xml file correctly but an
error is thrown in ccnet.config window that it is unable to merge as this file is currently used by some other process.
Please see below:
[VSAT:ERROR] Publisher threw
exception:
ThoughtWorks.CruiseControl.Core.CruiseC
ontrolException: Unable to read the
contents of the file: C:
\ThreePartition\outp ut.xml --->
System.IO.IOException: The process
cannot access the file 'C:\ThreeP
artition\output.xml' because it is
being used by another process.
Can you suggest any method by which merging can be done successfully?
I have pasted the whole ccnet.config file below.
<project name="VSAT">
<sourcecontrol type="filtered">
<sourceControlProvider type="filesystem">
<repositoryRoot>C:\ThreePartition</repositoryRoot>
<autoGetSource>true</autoGetSource>
<ignoreMissingRoot>false</ignoreMissingRoot>
</sourceControlProvider>
<exclusionFilters>
<pathFilter>
<pattern>C:\ThreePartition\wrSbc750gx_ThreePartition\**</pattern>
</pathFilter>
<pathFilter>
<pattern>C:\ThreePartition\*.txt</pattern>
</pathFilter>
<pathFilter>
<pattern>C:\ThreePartition\*.xml</pattern>
</pathFilter>
</exclusionFilters>
</sourcecontrol>
<triggers>
<intervalTrigger name="continuous" seconds="240"
buildCondition="IfModificationExists" />
</triggers>
<tasks>
<nant>
<executable>C:\Nant-0.85\bin\NAnt.exe</executable>
<buildFile>nant.build</buildFile>
</nant>
</tasks>
<publishers>
<merge>
<files>
<file>C:\ThreePartition\output.xml</file>
</files>
</merge>
<xmllogger logDir="C:\Program Files\CruiseControl.NET\server\DF2.0-CI
\Logfiles" />
<email from="BuildAdmin#server.com"
mailhost="smtp.servermail.com" includeDetails="TRUE">
<users>
user name="Maddy" group="buildmaster"
address="Mymail#server.com"/>
</users>
<groups>
<group name="buildmaster" notification="always"/>
<group name="developers" notification="change"/>
</groups>
</email>
</publishers>
</project>
</cruisecontrol>
I had just placed the publishers section below for the better view
<publishers>
<merge>
<files>
<file>C:\ThreePartition\output.xml</file>
</files>
</merge>
<email from="BuildAdmin#server.com" mailhost="smtp.server.com" includeDetails="TRUE">
<users>
<user name="Maddy" group="buildmaster" address="Maddy.#server.com"/>
</users>
<groups> <group name="buildmaster" notification="always"/>
<group name="developers" notification="change"/>
</groups>
</email>
Some ideas:
Eliminate other obvious applications that would be writing to that file: other CCNet projects, other CCNet instances (e.g. are you maybe running the service and something from the command line?), or perhaps your source control.
If you're not attached to NAnt, try MSBuild and see if you get the same error. If all you're doing is compiling, you can pass the .sln or .csproj as a parameter directly to MSBuild.
Make sure you're on the latest version of CCNet - they regularly publish what I would consider fairly major bug fixes regularly.
What is says: the question is which process has open your xml while CC.net is trying to merge -- perhaps Process Explorer could be useful? Perhaps it works if you copy the xml output to a separate file and merge that.

Resources