CruiseControl.NET post-build actions - cruisecontrol.net

We have CC.NET setup on our ASP.NET app. When we build the project, the ASP.NET app is pre-compiled and copied to a network share, from which a server runs the application.
The server is a bit different from development box'es, and the next server in our staging environment differs even more. The difference is specific config files and so on - so I want to exclude some files - or delete them before the pre-compiled app is copied to a network share.
My config file looks like this:
<project name="Assembly.Web.project">
<triggers>
<intervalTrigger seconds="3600" />
</triggers>
<sourcecontrol type="svn">
<trunkUrl>svn://svn-server/MyApp/Web/Trunk</trunkUrl>
<workingDirectory>C:\build-server\Assembly\Web\TEST-HL</workingDirectory>
<executable>C:\Program Files (x86)\SVN 1.5 bin\svn.exe</executable>
<username>uid</username>
<password>pwd</password>
</sourcecontrol>
<tasks>
<msbuild>
<executable>C:\Windows\Microsoft.NET\Framework64\v3.5\MSBuild.exe</executable>
<workingDirectory>C:\build-server\Assembly\Web\TEST-HL</workingDirectory>
<projectFile>C:\build-server\Assembly\Web\TEST-HL\Web\Web.sln</projectFile>
<buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
<targets>Build</targets>
<timeout>900</timeout>
<logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
</tasks>
<publishers>
<buildpublisher>
<sourceDir>C:\build-server\Assembly\Web\PrecompiledWeb</sourceDir>
<publishDir>\\test-web01\Web</publishDir>
<useLabelSubDirectory>false</useLabelSubDirectory>
<alwaysPublish>false</alwaysPublish>
</buildpublisher>
</publishers>
</project>
As you can see, I use a buildPublisher to copy the pre-compiled files to the network share. What I want to do here, is either 1) delete certain files before they are copied or 2) replace those files after they have been copied.
I DO NOT want to have some app running watching specific files for change, and then after that replace the files with other ones. I want something to be either done by CC.NET, or triggered by CC.NET.
Can you launch a .bat file with CC.NET?

I use a NAnt task for all publishing, deploying, cleaning and so on.

Take a look at MSDEPLOY or Web Deployment Projects. There is a question that will provide more detail here

You have to use NAnt for those kind of stuff.
Here is the Task Reference of Nant..

Of course CruiseControl.NET can run a batch file, simply use the exec task. However, an easier answer might just be to have MSBuild do the task for you. It should be simple to add a few steps in the postcompile target.

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

Transform external config in a web role

Can slowcheetah transform an external config file in an azure web role? e.g. I have logging info in log4net.config. But the transformed version does not get created when packaged.
I did not manage to get slowCheetah working in my Azure solution.
One alternative you can use is to create complete config files for each environment - e.g. :
log4net.debug.config
log4net.release.config
and copy the contents of these into the log4net.config at buildtime depending on the build configuration chosen.
This is done by adding a build target to your csproj file like so:
<Target Name="BeforeBuild">
<Delete Files="$(ProjectDir)log4net.config" />
<Copy SourceFiles="$(ProjectDir)log4net.$(Configuration).config"
DestinationFiles="$(ProjectDir)log4net.config" />
</Target>
(you may have to modify the paths in the script depending on where in the solution your config files are)
You can find more information on MSBuild and manipulating your .csproj file here and here

VS 2012 Publishing Profiles and Copy Files Using MSBuilld Commands

I've set up asp.net website on Azure with TFS online for source control using VS 2012. I'm trying to copy files using VS 2012 new publishings profiles and MSBuild. Reading this article Visual Studio 2012 Web Deployment Projects are Dead – Long Live Publishing Profiles, in which Doug says you can use build scripts in your publishing profile.
So I setup a test that works in my .csproj on my local build. I'm just simply copying the robots.txt file from the root directory to the css directory. Here is my test. I set my pubxml in the TFS Build Process template under process > 6. Publishing -- Azure Website, Web Deploy Pubish Profile.
<Target Name="AfterBuild">
<Copy SourceFiles="$(ProjectDir)robots.txt" DestinationFolder="$(ProjectDir)css\" />
</Target>
I dropped this Code into my my pubxml file and I get a big nothing. What am I doing wrong?
Is it possible to copy files afterbuild on Azure?
Additional Information
The log file contains these lines so I'm sure the publishing profile is running.
AfterBuild:
Creating directory "C:\a\src\...\css".
Copying file from "C:\a\src\...\robots.txt" to "C:\a\src\...\css\robots.txt".
Here are the build steps that Azure's default build template uses:
ValidateSolutionConfiguration:
PrepareForBuild:
CoreCompile:
_CopyFilesMarkedCopyLocal:
CopyFilesToOutputDirectory:
GenerateTargetFrameworkMonikerAttribute:
CoreCompile:
_CopyFilesMarkedCopyLocal:
CopyFilesToOutputDirectory:
_CopyWebApplicationLegacy:
ValidateGlobalPackageSetting:
CollectFilesFromIntermediateAssembly:
CollectFilesFromContent:
CollectFilesFromIntermediateSatelliteAssembliesWithTargetPath:
CollectFilesFromReference:
CollectFilesFromAllExtraReferenceFiles:
CollectFilesFrom_binDeployableAssemblies:
PipelineCollectFilesPhase:
ExcludeGeneratedDebugSymbol:
PreTransformWebConfig:
TransformWebConfigCore:
PostTransformWebConfig:
PreProfileTransformWebConfig:
PipelineTransformPhase:
ProcessPublishDatabaseSettings:
PreAutoParameterizationWebConfigConnectionStrings:
AutoParameterizationWebConfigConnectionStringsCore:
PostAutoParameterizationWebConfigConnectionStrings:
PipelineMsdeploySpecificTransformPhase:
ValidatePublishProfileSettings:
CopyAllFilesToSingleFolderForMsdeploy:
PipelineCopyAllFilesToOneFolderForMsdeploy:
Package:
GenerateMsdeployManifestFiles:
PackageUsingManifest:
GenerateSampleDeployScript:
PipelineDeployPhase:
AfterBuild:
So it looks like Azure packages all the files up during the "31. CopyAllFilesToSingleFolderForMsdeploy" step. It would appear that running copy during the AfterBuild step is to late. I moved the Copy command to the target "BeforeBuild" but the files are still not ending up in the CopyAllFilesToOneFolderForMsdeploy step.
Thanks to Sayed Ibrahim Hashimi for his article How to compress CSS/JavaScript before publish/package for helping me solve this.
It's possible to copy directly Package Temp Directory. I ended up adding this target to my publishing profile (pubxml) file. After the "CopyAllFilesTOSingleFolderForMsdeploy" step finishes this step will run which will copy a file from one part of the solution into the destinationfolder you specify.
<Target Name="AdditionalFilesForPackage" AfterTargets="CopyAllFilesToSingleFolderForMsdeploy">
<Copy SourceFiles="$(ProjectDir)robots.txt" DestinationFolder="$(_PackageTempDir)\css\" />
</Target>

Get the CCNetBuildDate in NAnt parallel tasks

In a cruise control configuration file, I use a set of parallel tasks to call some NAnt targets. I noticed that the CC system parameters (like CCNetBuildDate) are not pushed to the NAnt scripts, while they are pushed when I remove the parallel flag. How can I push the CCNetBuildDate information to my parallel tasks?
When I tested this (1.5) I got 0001-01-01 for CCNetBuildDate.
Until this bug is fixed you could save the correct settings before executing the parallel tasks. As you can not override properties passed on the command line you would have to change their names or use <exec> to call nant directly:
<nant>
<buildFile>SaveCCNetParameters.build</buildFile>
</nant>
<parallel>
<tasks>
<exec>
<executable>$(NAntExePath)</executable>
<buildArgs>-buildfile:Build1.build #CCNetBuildParameters</buildArgs>
</exec>
<exec>
<executable>$(NAntExePath)</executable>
<buildArgs>-buildfile:Build2.build #CCNetBuildParameters</buildArgs>
</exec>
</tasks>
</parallel>
where CCNetBuildParameters is a file looking similar to:
-DCCNetBuildDate=2012-11-10
-DCCNetBuildTime=12:12:12
-DCCNetLabel=123
[...]

Create folder inside debug or release con console application

i have a console application in vs2010 (C#) and in the project, i have a Folder added by me (right click on project.. add->folder) and i want that when i compile the application (debug or release), then the folder will be created (if not exists) in the debug or release directory.
Is that possible?
The console application is a daemon that access to a database and send emails with templates allocated in that folder.
I hope you can help me. Thanks!
There's no "automatic" way to get VS to create folders (other than the specified output folder) during a build, but there's two pretty easys ways to accomplish it.
Use a post-build event, which you set up in the Build Events tab of your project's properties. This is basically a batch file that you run after the build completes, something like this:
IF NOT EXIST $(OutDir)MySubFolder MKDIR $(OutDir)MySubFolder
XCOPY /D $(ProjectDir)MySubFolder\*.tmpl $(OutDir)MySubFolder
Use MSBuild's AfterBuild event. This is my preferred method, mostly because it integrates better with our automated build process, but it's a little more involved:
Right-click on your project node and Unload it
Right-click on the unloaded project node and Edit the file
Near the bottom is a commented-out pair of XML nodes. Uncomment the AfterBuild target and replace it with something like this:
<Target Name="AfterBuild">
<MakeDir Directory="$(OutDir)MySubFolder" Condition="!Exists('$(OutDir)MySubFolder')" />
<CreateItem Include="$(ProjectDir)MySubFolder\*.tmpl">
<Output TaskParameter="Include" ItemName="Templates" />
</CreateItem>
<Copy SourceFiles="#Templates" DestinationFolder="$(OutDir)MySubFolder" ContinueOnError="True" />
</Target>
Save the changes, close the .csproj file, then right-click and Reload the project.
I solve it, like this:
in the csproj:
<Target Name="AfterBuild">
<MakeDir Directories="$(OutDir)EmailTemplates" Condition="!Exists('$(OutDir)EmailTemplates')" />
<ItemGroup>
<Templates Include="$(ProjectDir)EmailTemplates\*.*" />
</ItemGroup>
<Copy SourceFiles="#(Templates)" DestinationFolder="$(OutDir)EmailTemplates" />
</Target>
Thank you for your help!

Resources