I am working in CCNet version 1.4, and I am having difficulty getting the parameters I want defined in a clean manner. In my example, I want 6 total projects as (3 solutions in 2 branches). I defined a generic project that could incorporate all 6 possibilities based on choice of 8 variables. When it's a trunk project, 4 of the variables should be one thing. When it's a branch project, the 4 variables should be another thing. The other 4 variables are dependent on which solution I want to build.
In my attempt below, I put the 4 trunk variables in one define block and the 4 release variables in another block. I also have a define block for each of the solutions.
<cb:define name="ProductBuildProject">
<project name="$(ProjectName)" queue="Common">
<category>Main Builds</category>
<sourcecontrol type="multi">
<sourceControls>
<cb:svn-sourcebuild-checkout BranchPath="$(BranchPath)" MainSourcePath="$(MainSourcePath)" />
</sourceControls>
</sourcecontrol>
<modificationDelaySeconds>10</modificationDelaySeconds>
<labeller type="defaultlabeller">
<prefix><cb:LabelPrefix/></prefix>
<incrementOnFailure>true</incrementOnFailure>
</labeller>
<triggers>
<intervalTrigger name="continuous" seconds="900" buildCondition="IfModificationExists"/>
</triggers>
<tasks>
<nant>
<executable>&nant-path;</executable>
<baseDirectory><cb:LocalKeywordLabPath/>\<cb:MainSourcePath/></baseDirectory>
<buildArgs>-v -D:deployServer=<cb:DeployServer/></buildArgs>
<buildFile><cb:BuildFileName/></buildFile>
<targetList>
<target><cb:BuildTargetName/></target>
</targetList>
<buildTimeoutSeconds>600</buildTimeoutSeconds>
</nant>
</tasks>
<publishers>
<merge>
<files>
<file><cb:LocalKeywordLabPath/>\<cb:MainSourcePath/>\<cb:UnitTestOutputPath/></file>
</files>
</merge>
&publishers-common-block;
</publishers>
<externalLinks/>
</project>
</cb:define>
<cb:define name="TrunkBuildParameters">
<cb:define name="LocalKeywordLabPath"><cb:keywordlab-trunk-local/></cb:define>
<cb:define name="BranchPath"><cb:trunk-path/></cb:define>
<cb:define name="LabelPrefix">1.1.0.</cb:define>
<cb:define name="DeployServer">smwtlkwlab01n</cb:define>
</cb:define>
<cb:define name="ReleaseBranchBuildParameters">
<cb:define name="LocalKeywordLabPath"><cb:keywordlab-release-local/></cb:define>
<cb:define name="BranchPath"><cb:releaseBranch-path/></cb:define>
<cb:define name="LabelPrefix">1.1.100.</cb:define>
<cb:define name="DeployServer">smwdvkwlab03n</cb:define>
</cb:define>
<cb:define name="KeywordLabWebParameters">
<cb:define name="MainSourcePath">Source\Presentation</cb:define>
<cb:define name="BuildFileName">KeywordLab.Web.build</cb:define>
<cb:define name="BuildTargetName">automated-with-webdeploy</cb:define>
<cb:define name="UnitTestOutputPath">KeywordLab.Web.UnitTest\bin\Release\KeywordLab.Web.UnitTest.trx</cb:define>
</cb:define>
<cb:define name="KeywordLabWebMvcParameters">
<cb:define name="MainSourcePath">Source\UI</cb:define>
<cb:define name="BuildFileName">KeywordLab.Web.Mvc.build</cb:define>
<cb:define name="BuildTargetName">automated-with-webdeploy</cb:define>
<cb:define name="UnitTestOutputPath">KeywordLab.Web.Mvc.Tests\bin\Release\KeywordLab.Web.Mvc.Tests.trx</cb:define>
</cb:define>
<cb:define name="KeywordLabServiceParameters">
<cb:define name="MainSourcePath">Source\Service</cb:define>
<cb:define name="BuildFileName">KeywordLab.build</cb:define>
<cb:define name="BuildTargetName">automated</cb:define>
<cb:define name="UnitTestOutputPath">KeywordLab.UnitTest\bin\Release\KeywordLab.UnitTest.trx</cb:define>
</cb:define>
Finally, I try to define the 6 projects each by referencing the define block for the trunk or release build and the correct define block for the solution.
<!--KeywordLab Web-->
<cb:ProductBuildProject>
<cb:define name="ProjectName">KeywordLab Web (1N)</cb:define>
<cb:TrunkBuildParameters/>
<cb:KeywordLabWebParameters/>
</cb:ProductBuildProject>
<!--KeywordLab Web Mvc-->
<cb:ProductBuildProject>
<cb:define name="ProjectName">KeywordLab Web Mvc (1N)</cb:define>
<cb:TrunkBuildParameters/>
<cb:KeywordLabWebMvcParameters/>
</cb:ProductBuildProject>
<!--KeywordLab Service-->
<cb:ProductBuildProject>
<cb:define name="ProjectName">KeywordLab Service (1N)</cb:define>
<cb:TrunkBuildParameters/>
<cb:KeywordLabServiceParameters/>
</cb:ProductBuildProject>
<!--KeywordLab Web-->
<cb:ProductBuildProject>
<cb:define name="ProjectName">Release Branch (3N) - KeywordLab Web</cb:define>
<cb:ReleaseBranchBuildParameters/>
<cb:KeywordLabWebParameters/>
</cb:ProductBuildProject>
<!--KeywordLab Web Mvc-->
<cb:ProductBuildProject>
<cb:define name="ProjectName">Release Branch (3N) - KeywordLab Web Mvc</cb:define>
<cb:ReleaseBranchBuildParameters/>
<cb:KeywordLabWebMvcParameters/>
</cb:ProductBuildProject>
<!--KeywordLab Service-->
<cb:ProductBuildProject>
<cb:define name="ProjectName">Release Branch (3N) - KeywordLab Service</cb:define>
<cb:ReleaseBranchBuildParameters/>
<cb:KeywordLabServiceParameters/>
</cb:ProductBuildProject>
This isn't working and I'm hoping that someone can point out what I'm doing wrong. When I try to load this config, the error I receive is:
[CCNet Server:ERROR] INTERNAL ERROR: Reference to unknown symbol LabelPrefix
As you can see in TrunkBuildParameters and ReleaseBranchBuildParameters, I define LabelPrefix in both, and all 6 projects reference one or the other of these define blocks. I then try to reference this in the block of the project. This is apparently not a valid way of defining a variable for use by projects. Could someone please tell me what I'm doing wrong or perhaps a better way to do this at all?
I'd suggest using the Validator supplied with cruisecontrol to see what the final parsed config file is, to check if you've missed anything.
Having said that, what I usually do is the other way around. I define commonly used config blocks and then write out the project config with only a few lines. Perhaps you'll consider that clean enough?
Related
I want to calculate a value in my ccnet.config file. So I tried this:
<cb:eval prio="$(BasePriority)+$(Priority)" />
<project name="test" queue="test" queuePriority="$(prio)">
...
But this gave me an error that eval needs to have the "expr" attribute. How do I name the output of the eval so I can reference it?
I found an example in another question on stack overflow. Here is how its done:
<cb:define name="prio">
<cb:eval expr="$(BasePriority)+$(Priority)" />
</cb:define>
<project name="test" queue="test" queuePriority="$(prio)">
Is there any way to use the project name in the project config in CruiseControl.NET ?
I tried ${project.name} based on other posts which doesn't work.
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define BuildArtifactsMainDir="D:\CCNet\BuildArtifacts\"/>
<project name="MyProject">
<artifactDirectory>$(BuildArtifactsMainDir)${project.name}</artifactDirectory>
<tasks>
<exec>
<executable>C:\Windows\System32\robocopy.exe</executable>
<buildArgs>D:\${project.name} F:\${project.name}</buildArgs>
<buildTimeoutSeconds>600</buildTimeoutSeconds>
<successExitCodes>0,1,3,4,8,16</successExitCodes>
</exec>
</tasks>
I don't think there's a parameter for project name. You can use scopes instead.
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define BuildArtifactsMainDir="D:\CCNet\BuildArtifacts\"/>
<cb:scope ProjectName="MyProject">
<project name="$(ProjectName)">
<artifactDirectory>$(BuildArtifactsMainDir)$(ProjectName)</artifactDirectory>
...
</project>
</cb:scope>
I am setting up a nightly build using ccnet 1.6 to run projects sequentially and exclusively, but however I set up the queues when the build is triggered the projects do not start in the expected order as defined by the queue priority. The config below randomly starts queues 1, 2, 3 or 4 first then completes the remaining projects in the defined sequence order (ie 2, 1, 3, 4 or 3, 1, 2, 4 etc). I've tried xlmns 1.6 and 1.5 with same results. I can't see why this is not working, am I missing something?
Thanks
<cb:define name="Common">
<webURL>http://hostname/ccnet/server/local/project\$(CCProjectName)\ViewLatestBuildReport.aspx</webURL>
<workingDirectory>D:\source\$(ProjectName)</workingDirectory>
<sourcecontrol type="svn"/>
<modificationDelaySeconds>60</modificationDelaySeconds>
<triggers>
<scheduleTrigger time="11:05" buildCondition="ForceBuild "/>
</triggers>
<state type="state" directory="C:\Program Files\CruiseControl.NET\server" />
</cb:define>
<cb:define name="BuildProject">
<project name="$(CCProjectName)" queue="SequentialQueue" queuePriority="$(QueuePriority)">
<cb:Common />
<tasks>
<exec>
<executable>$(ANT_HOME)\bin\ant.bat</executable>
<buildArgs>-logger org.apache.tools.ant.XmlLogger -logfile build_log.xml -f build\$(ProjectName).xml</buildArgs>
</exec>
</tasks>
<publishers>
<merge>
<files>
<file>D:\source\$(ProjectName)\build\*.xml</file>
</files>
</merge>
<xmllogger />
</publishers>
</project>
</cb:define>
<cb:BuildProject CCProjectName="API" ProjectName="api" QueuePriority="1" />
<cb:BuildProject CCProjectName="Ack" ProjectName="acknowledgement" QueuePriority="2" />
<cb:BuildProject CCProjectName="Error" ProjectName="error" QueuePriority="3" />
<cb:BuildProject CCProjectName="Monitoring" ProjectName="monitoring" QueuePriority="4" />
I'm guessing this is a bug in CruiseControl.Net, your scenario (variable priority projects in one queue triggered by the same schedule trigger) is not a common one. You should file a bug on cruisecontrolnet.org.
A more usual solution for this kind of setup is having the projects trigger each other using <projectTrigger/>, which also results in a sequential build. You'll probably want to change the triggerStatus parameter so that a failed build does not stop the chain.
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>
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.