cruise control.NET perforce all commits ever are modifications - perforce

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!

Related

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

Doing a build when changes happen in either of two repositories AND a file system

I have a ccnet project which watches two SVN repositories for changes. Using a source control block of type multi worked fine for that. Now the project needs to watch the two repositories and a file. It needs to only build if one of the two repositories changed and the file changed.
I tried nesting a multi source control block in a multi source control block as follows(you may ignore all the variables):
<sourcecontrol type="multi">
<requireChangesFromAll>True</requireChangesFromAll>
<sourceControls>
<sourcecontrol type="multi">
<requireChangesFromAll>False</requireChangesFromAll>
<sourceControls>
<filtered>
<sourceControlProvider type="svn" autoGetSource="false">
<executable>$(svn-exe)</executable>
<timeout units="minutes">60</timeout>
<trunkUrl>$(svn-srcmwo)</trunkUrl>
<workingDirectory>$(mwo-localfull)</workingDirectory>
</sourceControlProvider>
<inclusionFilters>
<cb:mwo-include-filters/>
</inclusionFilters>
</filtered>
<filtered>
<sourceControlProvider type="svn" autoGetSource="false">
<executable>$(svn-exe)</executable>
<timeout units="minutes">10</timeout>
<trunkUrl>$(svn-orion)</trunkUrl>
<workingDirectory>$(orion-localfull)</workingDirectory>
<webUrlBuilder type="websvn">
<url>$(viewvc-orion){0}$(viewvc-config)</url>
</webUrlBuilder>
</sourceControlProvider>
<inclusionFilters>
<pathFilter>
<pattern>$(svn-orion-trunk)</pattern>
</pathFilter>
</inclusionFilters>
<exclusionFilters>
<pathFilter>
<pattern>$(svn-grsim-makfiles)</pattern>
</pathFilter>
</exclusionFilters>
</filtered>
</sourceControls>
</sourcecontrol>
<sourcecontrol type="filesystem">
<repositoryRoot>e:\build_listen</repositoryRoot>
</sourcecontrol>
</sourceControls>
</sourcecontrol>
but CCValidator gave the error:
Unused node detected: <sourcecontrol type="filesystem"><repositoryRoot>e:\build_listen&lt/repositoryRoot></sourcecontrol>
Does anyone see how this can be done - doing and AND on a file system and two repositories?
This nested source control thing is quite complicated indeed. First of all you missed the <sourceControls> tag in the outer multi sourcecontrol block. Secondly there is an important note in the CCNET documentation on multi sourcecontrol blocks:
Note that, due to the way the configuration gets parsed, if you are using a "multi" block, then the items within the element should not be elements (as you may expect). Instead, the name of the element should be the same as you would put in the "type" attribute when using a element.
That is just the way the source control blocks work in your existing configuration: <filtered> instead of <sourcecontrol type="filtered">.
So this should fix your problem:
<sourcecontrol type="multi">
<requireChangesFromAll>True</requireChangesFromAll>
<sourceControls>
<multi>
<requireChangesFromAll>False</requireChangesFromAll>
<sourceControls>
<filtered>
<sourceControlProvider type="svn" autoGetSource="false">
<executable>$(svn-exe)</executable>
<timeout units="minutes">60</timeout>
<trunkUrl>$(svn-srcmwo)</trunkUrl>
<workingDirectory>$(mwo-localfull)</workingDirectory>
</sourceControlProvider>
<inclusionFilters>
<cb:mwo-include-filters/>
</inclusionFilters>
</filtered>
<filtered>
<sourceControlProvider type="svn" autoGetSource="false">
<executable>$(svn-exe)</executable>
<timeout units="minutes">10</timeout>
<trunkUrl>$(svn-orion)</trunkUrl>
<workingDirectory>$(orion-localfull)</workingDirectory>
<webUrlBuilder type="websvn">
<url>$(viewvc-orion){0}$(viewvc-config)</url>
</webUrlBuilder>
</sourceControlProvider>
<inclusionFilters>
<pathFilter>
<pattern>$(svn-orion-trunk)</pattern>
</pathFilter>
</inclusionFilters>
<exclusionFilters>
<pathFilter>
<pattern>$(svn-grsim-makfiles)</pattern>
</pathFilter>
</exclusionFilters>
</filtered>
</sourceControls>
</multi>
<filesystem>
<repositoryRoot>e:\build_listen</repositoryRoot>
</filesystem>
</sourceControls>
</sourcecontrol>
I think you can't have two following sourcecontrol blocks.
You should refactor your projects as follow:
One project with only the filesystem trigger.
This will be the trigger for the next job
Another project linked to the previous one AND with your multi sourcecontrol triggers.
Have a look to CruiseServer Control Task to synchronize two jobs:

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 run a task before updating source files?

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.

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