![]() ![]() ![]() ![]() ![]() ![]()
|
CruiseControl Installation Guide Standard Usage:
1. Use Ant to build your project. Optional/Advanced Usage:
8. Build Label Customization
Standard Usage 1. Set up your project to build using Ant There's extensive documentation on the Ant project website. Before any thought should be given to using CruiseControl, your project should have a fully functional ant build process which can be run by hand. This should include standard targets for compiling all the source, cleaning out directories created by the build process, and JARing up compiled files to create your project's distributables. Your targets should also include tasks to label elements of the source control repository and optionally checkin the newly created distributables. This is a matter of personal preference. Some believe that a source control management tool should only contain source, while others believe that checking in distributables allows easier access to previous application versions. Regardless, you should be able to build your project with Ant. 2. Add the modificationset target The modificationset element looks something like this: <modificationset ...> <vsselement ssdir="lib" .../> <vsselement ssdir="src" .../> <vsselement ssdir="tests" .../> <vsselement ssdir="jsp" .../> </modificationset>The modificationset element handles general duties, such as logging and enforcing the quiet period between checkins. Any nested elements will handle any repository specific details. If your repository isn't currently supported, it's pretty easy to extend our code to add a new repository; implementing a simple interface is all that's necessary. Most recently, we wrote and tested a <cvselement> in a day. The whole functionality of the modificationset element is to poll a repository for changes. This will be the first task run from Ant during each build, so it's pretty straightforward: if there are any changes since the last successful build, then we'll log the modifications and carry on. If there were no changes, the build ends there and we'll wait and try again in ten minutes. When dealing with any automated process, logging becomes a more important issue. The <modificationset> task will write out an xml file detailing all the modifications that have occurred within the repository since the last successful build. This log will be merged into the xml log that Ant produces when the build is complete. At this point, you should have an Ant file that will perform one full build cycle: checking whether a build is necessary, logging the modifications since the last good build, getting the latest source to your build machine, compiling, packaging your distributable, running unit tests, and labeling your source. 3. Configure cruisecontrol.properties Set the properties to match your project's needs. The properties file is heavily commented to provide the necessary instructions. Tomcat is a freely available application server available from Apache. However, you're free to use the servlet engine of your choice. Follow the directions specific to your app server to install buildservlet.war. You'll need to configure the WEB-INF/web.xml to meet your project's needs. Again, this file is commented with further directions. Again, follow the directions to start your server. Until we've started to build, there are no log files for the servlet to process, so we'll have to wait until we have at least built once before viewing the servlet. Your classpath will need to include all the jars required by CruiseControl. All the required jar files have been included in the lib directory, but you should occasionally check with the original jar vendors for updated versions. A batch script named setclasspath.bat has also been included. This script should add all the required jars to your existing classpath. After setting the classpath appropriately run the MasterBuild process by executing: java CruiseControlThere are some command line arguments that you'll need to specify: the last good build time, the label, and the path to the properties file. Specify no arguments, and you'll get a usage message that will explain the exact arguments that you need. If, for some reason, you need to stop the build process, when restarting you need only specify the path to the properties file. The last good build time and label will be persisted for you.
Advanced/Optional Usage CruiseControl provides the ability to customize the incrementation of the build labels. Each successful build is given a unique build label. The beginning build label can be specified on the command line when starting the MasterBuild process. MasterBuild will then increment the label for each successful build. CruiseControl provides a default label incrementer which will conform to many developent efforts needs. The default label incrementer expects a label in the form "x.y", where x is any String and y is an integer. For example, a label like 1.51, 1.51.4, or MyProjectX.2.5 can all be handled by the default label incrementer. The first successful build will be assigned the original label value provided, then the label will be incremented for the next successful build. The examples would be incremented as follows, 1.52, 1.51.5, and MyProjectX.2.6 respectively. However, this label incrementation scheme may not be suitable for all development efforts. For example, if your development effort wants to use a label like builddate.buildnumberfortoday the default incrementer will not know how to increment this label to match your specification. Labels following this scheme would look like 03.21.2001.25. The default incrementer would simply continue to increment the integer after the last dot, never changing the builddate portion of the label. The following day the build label might be 03.21.2001.100 when it should be 03.22.2001.1 for the first build of the day. To implement a custom label incrementation scheme like the one in this example, your development effort must provide a concrete implementation of the org.apache.tools.ant.taskdefs.LabelIncrementer interface [NOTE: package structure in flux]. This interface specifies a single method named incrementLabel. The full method signature is: public String incrementLabel(String oldLabel);Once the concrete implementation has been written, place the compiled class in the classpath. Then edit the labelIncrementerClass property value in the masterbuild.properties file. The value for this method, as stated in the comments provided therein, should be the fully qualified class name for the LabelIncrementer implementation. To implement the label incrementation scheme noted above, my development effort would write a class with the incrementLabel method as follows: public String incrementLabel(String oldLabel) { try { //Get the current build number portion of the label. int buildNumber = Integer.parseInt(oldLabel.substring(oldLabel.lastIndexOf(".") + 1)); //Get the current suffix, and what it should be. SimpleDateFormat sdf = new SimpleDateFormat("MMdd"); String newPrefix = sdf.format(new Date()); String oldPrefix = oldLabel.substring(0, oldLabel.lastIndexOf(".")); String correctPrefix = null; //If the new prefix and old prefix aren't the same, then // a new day has started. We need to reset the build number to 1. if (!newPrefix.equals(oldPrefix)) { buildNumber = 1; correctPrefix = newPrefix; } //Otherwise, we are still on the same day, so we can just increment the build number. else { buildNumber++; correctPrefix = oldPrefix; } return correctPrefix + "." + buildNumber; } catch (NumberFormatException ne) { ne.printStackTrace(); return null; } }After compiling the class called MyProjectLabelIncrementer and adding it to my classpath, the value for labelIncrementerClass will be myproject.MyProjectLabelIncrementer. The MasterBuild process will attempt to dynamically load this class and call the incrementLabel method. My development effort has now changed the behavior of MasterBuild to conform to our label incrementation scheme. In my build.xml file, which MasterBuild uses, the label given to the next successful build can be referenced using the Ant property ${label}. Some development efforts will want to use this property to tag, or label, source and binary elements controlled by their source control mechanism when a successful build occurs.
CruiseControl allows the user to specify a properties file which maps names provided from the source control mechanism to actual email addresses. This behavior is optional. If a properties map is not provided then CruiseControl will send the names provided from the source control mechanism directly to the SMTP server. If your project wants to map a source control user name to one or more actual email addresses, or would like to include email grouping information, then email aliasing and mapping will allow you to do this. This includes projects where CVS user names don't map one-to-one with actual email adresses. This also includes projects where people want to be notified of the build status at more than one email address. Since StarTeam (and potentially other source control tools) includes a rich set of user information, including an actual email address for each user, StarTeam projects will most likely not want to include an email map. CVS though only provides the user's CVS logon name with each modification. Usually this name must be mapped to a real email address. Most projects follow the convention that the CVS user name maps one-to-one with the user's actual email address when the domain name is appended to the user name. Most smtp servers will also append the domain name to the end of a user name when the @domain.name portion of the email address is left off. If your project fits into either of these two categories then email mapping is not for you. cruisecontrol.properties includes a property named "emailmap". To specify a properties file which will map source control user names to one or more actual email addresses, specify the absolute path to the file here. For example, my project is building on an NT machine and I put a properties map in the file located at "D:\projects\myfirstproject\emailmap.properties". I set the emailmap property in the cruisecontrol.properties file to read: emailmap = D:\projects\myfirstproject\emailmap.propertiesThe filename provided will be passed directly to the java.io.File class for handling and should conform to that class's specification, i.e. on a Windows machine a "\" should be used as a file seperator, and on a *Nix machine a "/" should be used. In my emailmap.properties file I include several lines to indicate the actual email addresses that correspond to the user names returned by my source control mechanism. For the user name "pauljulius" I want to send email to my regular work account and my cell phone, which is set up to receive email. I include a line in the emailmap.properties file like the following: pauljulius=pdjulius@thoughtworks.com, 62872223@mycellphoneprovider.comNow, when CruiseControl encounters the user name pauljulius in the set of modifications for the current build, it will resolve that to the two email addresses I provided and send me a notification email at both addresses to let me know the status of the build. CruiseControl also allows for email aliasing. For example, a new developer, Joe Smith, joined our team and for the first week I am assigned to keep an eye on him. I want to know every time his modified files are included in the build. So, I add a line to the emailmap.properties like: joesmith = joesmith@thoughtworks.com, pauljuliusNow, when CruiseControl encounters the user name joesmith in the modification set it will resolve it to Joe's actual email address and the email alias pauljulius. Then CruiseControl will resolve pauljulius to the addresses listed above. CruiseControl will recursively attempt to resolve any alias until either the address is fully specified, i.e. includes the "@" symbol, or it can find no alias for the name given. Note that you could enter an infinite loop by changing the the pauljulius alias to read: pauljulius=pdjulius@thoughtworks.com, 62872223@mycellphoneprovider.com, pauljuliusCruiseControl will recursively attempt to refine the alias pauljulius and never reach a stopping point. Other infinite loops include circular references such as: buildmasters = alldevelopers alldevelopers = buildmastersCruiseControl will make sure that each email appears in the mailing list only once and should never send email to the same email address twice for the same build notification. For example, in the cruisecontrol.properties file a property exists called "buildmaster". I can either specify an actual email address or an email alias which is mapped in the email.properties file. If I set the buildmaster property to pauljulius, CruiseControl will resolve that to the two addresses I provided in the email map. If I also modify files that are included in the next build, CruiseControl will encounter pauljulius as a user name in the modifications and resolve it to the same two addresses. CruiseControl will not send me 4 emails though. CruiseControl will only send a single email to each of the two addresses I have listed. This allows me to include myself in as many different recursive email aliases as I wish. I can include myself on the "notifyOnFailure" list set in cruisecontrol.properties and on the "buildmaster" list and only receive a single notification for each actual email address I provide. |