Better Ways to Maintain Continuous Integration?
I find that I am always tuning and tweaking our CI setup as we add new projects. While there is NO question that the benefits are awesome for existing code that seldom changes, new projects or volitile ones seem to require more work as I have to configure each project to be "intergrated" as well as maintain an ever-growing CCNET.config file. Is there a better strategy short of building an utility to manage adding and modifying a CI setup?
I do a few things to try keep it under control:
1) Split the config file into two. I have one file that mostly stays the same and contains a set of constants e.g.
<?xml version="1.0" encoding="utf-8"?> <cruisecontrol xmlns:cb="urn:ccnet.config.builder"> <!-- Constant definition used by the projecct config to prevent changes being required for each iteration --> <cb:define branch="branch name for source control"/> <cb:define ciserver="Server name in here"/> <cb:define devenv="Path to DEVENV"/> <cb:define nunit="Path to NUNIT"/> <cb:define cruisecontrol="Cruisecontrol Path"/> <!-- Include file to the standard CI project definitions. This file is kept under source control --> <cb:include href="config\CCProjects.config"/> </cruisecontrol>
The use of constants allows you to make a single change and have it propagate through each task in the config file.
2) Keep the file with the projects in under source control. The project file gets updated as part of the SVN checkout. This helps track changes that get made and let you rollback without too much hassle.
Maybe it has got to the point where CC.Net is working against you rather than for you. I've heard good things about the ease of configuration of other CI servers, like Hudson, but it may not be a good fit with your build environment.
1/ Split your config file as you want
For example, I have a constants section, and each project is an include, so I can update each project quite independently and use constants across projects.
<cruisecontrol xmlns:cb="urn:ccnet.config.builder"> <!-- Shared constants --> <cb:define WorkingFolderBase="D:\dev\ContinuousIntegration\WC" /> <cb:define ArtifactFolderBase="D:\dev\ContinuousIntegration\Artifact" /> <cb:define ConfigFolder="projects" /> <cb:define SvnBasePath="http://myserver.com/svn" /> <cb:define SvnUsername="Myusername" /> <cb:define SvnPassword="MyPassword" /> <!-- MyProject1 --> <cb:include href="projects/MyProject1.config"/> <!-- MyProject2 --> <cb:include href="projects/MyProject2.config"/> </cruisecontrol>
<project name="MyProject1" queue="Q1" queuePriority="1"> <artifactDirectory>$(ArtifactFolderBase)\MyProject1</artifactDirectory> <workingDirectory>$(WorkingFolderBase)\MyProject1</workingDirectory> <!-- SVN implementation --> <sourcecontrol type="svn" username="$(SvnUsername)" password="$(SvnPassword)"> <trunkUrl>$(SvnBasePath)/MyProject1/trunk/</trunkUrl> <workingDirectory>$(WorkingFolderBase)\MyProject1</workingDirectory> </sourcecontrol> [...] </project>
2/ Use version control on CC.NET (I recommand on the whole installation) or on config files.
3/ Keep it simple! have all actions executed by a batch file (Compile applciation, compile tests, run tests, get coverage, static analyser, generate reports ...).