<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Chris Read &#187; Development</title>
	<atom:link href="http://blog.chris-read.net/category/software/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.chris-read.net</link>
	<description>He's just this guy, you know...</description>
	<lastBuildDate>Tue, 13 Sep 2011 11:41:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.chris-read.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Chris Read &#187; Development</title>
		<link>http://blog.chris-read.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.chris-read.net/osd.xml" title="Chris Read" />
	<atom:link rel='hub' href='http://blog.chris-read.net/?pushpress=hub'/>
		<item>
		<title>Self Identifying Software</title>
		<link>http://blog.chris-read.net/2009/09/22/self-identifying-software/</link>
		<comments>http://blog.chris-read.net/2009/09/22/self-identifying-software/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 17:09:41 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Config Management]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>

		<guid isPermaLink="false">http://blog.chris-read.net/?p=91</guid>
		<description><![CDATA[How often has someone come up to you and asked you what build of your software is currently deployed in a specific environment? How many times have you come across a .jar or .dll file and wondered what version it is? Especially when using Open Source Software? The most frightening one for me is when [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=91&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>How often has someone come up to you and asked you what build of your software is currently deployed in a specific environment?</p>
<p>How many times have you come across a <em>.jar</em> or <em>.dll</em> file and wondered what version it is? Especially when using Open Source Software?</p>
<p>The most frightening one for me is when I&#8217;ve looked at a cluster of production servers and noticed that the <em>.war</em> file for the application deployed on it is a different size on one of the nodes. Which one was the correct one to deploy? Luckily this happened to me a long time ago, but I know that people out there are still having this problem today.</p>
<p>The solution is what I call <em>&#8220;Self Identifying Software&#8221;</em>. Every build of your software needs to have something that tells you what version it is and how to get back to the source code that created it. Having a build label or release number visible in your application is a good start, but it does not make your software <em>Self Identifying</em>. Product companies have been doing this for ever. The problem is that for that number to be useful (particularly when you&#8217;re trying to access the source code to reproduce and fix a bug) you then need to refer to a build system or release notes to find out where the source code came from (if you&#8217;re lucky). It often also does not apply to development builds. To be truly <em>Self Identifying</em> you need to make sure that <em><span style="text-decoration:underline;"><strong>every</strong></span></em> build (including builds developers create on their workstations) also includes enough information from the SCM system so that anyone who has access to the source code can go right back to the exact source code that produced that binary. For example, if you use Subversion as your SCM then this will be a URL and a revision number.</p>
<p>This is not exactly a new concept, it&#8217;s something I (and others) have been doing for a number of years now. The reason I&#8217;ve decided to write about it now though is that recently I was showing a new guy around one of the projects I&#8217;m working on at the moment, and when I showed him how to determine which version of the app was deployed he was delighted.<br />
<span id="more-91"></span></p>
<h2>How do I get my software to identify itself?</h2>
<p>There are generally two scenarios where I would want to get the identity of some software. The first is where I have a service or system running somewhere that I would like to know the version of, and the second is where I have a binary artefact and I&#8217;m trying to determine it&#8217;s provenance.</p>
<p>When querying a service, the easiest is to be able to hit a well known URL (or make a well known service call) that tells me what I need to know. What the exact URL or service call is is not important, as long as those who need it know how to invoke it. This is most useful then you don&#8217;t actually have access to the binaries that power the service.</p>
<p>However, if you do have access to the binaries then it&#8217;s usually easiest just to examine the meta data of the file to see where it came from. Most modern binary formats allow for this in some way. If you&#8217;re working with Java then all <em>.jar</em>, <em>.war</em> and <em>.ear</em> files allow you to put this into the <em>META-INF/MANIFEST.MF</em> file. Creative use of <em>versioninfo</em> resources will allow you to achieve similar results if you&#8217;re dealing with Windows. Note that we&#8217;re not talking about putting this information into the file name itself &#8211; file names change.</p>
<h2>How do I use it?</h2>
<p>Having <em>Self Identifying Software</em> goes beyond just being able to quickly track down the source code that built the binaries you&#8217;re dealing with. Here are a few other uses I&#8217;ve found:</p>
<ul>
<li>When used as part of a Continuous Deployment system you can verify that you&#8217;ve got the correct version of the binaries before you start deploying things, and you can then use the service call to verify that the correct version of the app is up and running at the end of the deployment processes.</li>
<li>When used as part of a dynamic system dashboard you can quickly and easily see what&#8217;s installed where instead of relying on spreadsheets or documents that often get forgotten.</li>
</ul>
<p>If you find any more, please let me know&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/91/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=91&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2009/09/22/self-identifying-software/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Podcast on Continuous Integration available</title>
		<link>http://blog.chris-read.net/2009/04/27/podcast-on-continuous-integration-available/</link>
		<comments>http://blog.chris-read.net/2009/04/27/podcast-on-continuous-integration-available/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 08:57:04 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[jaoo]]></category>
		<category><![CDATA[podcast]]></category>
		<category><![CDATA[talks]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.chris-read.net/?p=77</guid>
		<description><![CDATA[Last year at JAOO I had the chance to speak to Markus from Software Engineering Radio about the talk I gave there on Continuous Integration. It&#8217;s finally available now over here. The slides that go along with the talk are available from the JAOO site.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=77&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Last year at JAOO I had the chance to speak to Markus from <a href="http://se-radio.net" target="_blank">Software Engineering Radio</a> about the <a href="http://jaoo.dk/aarhus-2008/presentation/Continuous+Integration" target="_blank">talk</a> I gave there on Continuous Integration. It&#8217;s finally available now over <a href="http://se-radio.net/podcast/2009-04/episode-133-continuous-integration-chris-read" target="_blank">here</a>. The slides that go along with the talk are available from the <a href="http://jaoo.dk/aarhus-2008/file?path=/jaoo-aarhus-2008/slides/ChrisRead_ContinuousIntegration.pdf" target="_blank">JAOO</a> site.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/77/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=77&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2009/04/27/podcast-on-continuous-integration-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducing ESCAPE</title>
		<link>http://blog.chris-read.net/2009/02/13/introducing-escape/</link>
		<comments>http://blog.chris-read.net/2009/02/13/introducing-escape/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 12:31:12 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Build Pipelines]]></category>
		<category><![CDATA[Config Management]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.chris-read.net/?p=50</guid>
		<description><![CDATA[Whenever I talk to new clients about Continuous Integration, and especially about using Build Pipelines to extend their CI process to cover testing things like the deployment of their application, there is always one question that is guaranteed to pop up &#8211; how do I manage the configuration of my application in all these environments? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=50&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Whenever I talk to new clients about Continuous Integration, and especially about using Build Pipelines to extend their CI process to cover testing things like the deployment of their application, there is always one question that is guaranteed to pop up &#8211; how do I manage the configuration of my application in all these environments?</p>
<p>This is always a hard one to answer. In the last place I worked as a System Administrator we used <a title="Split-Horizon DNS" href="http://en.wikipedia.org/wiki/Split-horizon_DNS" target="_blank">Split-Horizon DNS</a> as one of the ways to solve connecting to the correct host for a service. Our applications had hard coded hostnames for key services such as <em>db.internal.domain</em>, <em>loghost.internal.domain</em> and <em>mailhost.internal.domain</em>. Depending on which environment they ran in, when the did a DNS lookup they would get an answer that pointed them to the correct server providing that service for the environment they were physically running in. Combine this with tools like an LDAP Server in each of these environments containing the rest of the system configuration and life is easy. Or is it?</p>
<p>DNS and LDAP servers are relatively straight forward for experienced Sys Admins to understand and maintain, but they still can&#8217;t be described as easy to use, which is probably why so few people do it. This limits our options for fixing things down to two general categories &#8211; fix DNS and LDAP admin tools so they are easy to use, or find another way to solve the problem.</p>
<p>We chose the path of least resistance and went for the second option &#8211; creating <a href="http://code.google.com/p/escservesconfig/" target="_blank">ESCAPE</a>. In the Unix tradition, it&#8217;s an app that takes one problem and solves it simply and well (at least in our opinion). It provides a RESTful interface for both the setting and getting of environment configuration. <tt>GET</tt> requests will retrieve configuration, whereas <tt>POST/PUT</tt> requests will create new entries or update them.</p>
<p>The URL scheme we&#8217;ve decided on is most easily demonstrated by constructing an example URL:</p>
<table border="0">
<tbody>
<tr>
<td style="border:1px solid #aaaaaa;padding:5px;"><strong>URL</strong></td>
<td style="border:1px solid #aaaaaa;padding:5px;"><strong>Value returned in the body</strong></td>
</tr>
<tr>
<td style="border:1px solid #aaaaaa;padding:5px;"><tt>http://escape/</tt></td>
<td style="border:1px solid #aaaaaa;padding:5px;">User interface. No API available here.</td>
</tr>
<tr>
<td style="border:1px solid #aaaaaa;padding:5px;"><tt>http://escape/environments/</tt></td>
<td style="border:1px solid #aaaaaa;padding:5px;">A JSON list of all the available environment.</td>
</tr>
<tr>
<td style="border:1px solid #aaaaaa;padding:5px;"><tt>http://escape/environments/production/</tt></td>
<td style="border:1px solid #aaaaaa;padding:5px;">A JSON list of all the applications in the &#8220;production&#8221; environment.</td>
</tr>
<tr>
<td style="border:1px solid #aaaaaa;padding:5px;"><tt>http://escape/environments/production/mywebapp</tt></td>
<td style="border:1px solid #aaaaaa;padding:5px;">All keys and values for the &#8220;mywebapp&#8221; application in the &#8220;production&#8221; environment.e.g:<br />
key1=value1<br />
key2=value2</td>
</tr>
<tr>
<td style="border:1px solid #aaaaaa;padding:5px;"><tt>http://escape/environments/production/mywebapp/thiskey</tt></td>
<td style="border:1px solid #aaaaaa;padding:5px;">The value of &#8220;thiskey&#8221; for the &#8220;mywebapp&#8221; application in the &#8220;production&#8221; environment.</td>
</tr>
</tbody>
</table>
<p>As the tool is now usable we&#8217;ve happily released version 0.1. Currently we&#8217;re busy putting a lot of work into making the management interface understandable and intuitive to use. The closest thing we currently have to a roadmap is our <a href="http://code.google.com/p/escservesconfig/wiki/ToDo" target="_blank">ToDo</a> list.</p>
<p>Please join us on the <a href="http://groups.google.com/group/escservesconfig-discuss" target="_blank">discussion group</a> with your feedback.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=50&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2009/02/13/introducing-escape/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Retrospectively Breaching the Wall between Developers and Operations</title>
		<link>http://blog.chris-read.net/2008/11/26/retrospectively-breaching-the-wall-between-developers-and-operations/</link>
		<comments>http://blog.chris-read.net/2008/11/26/retrospectively-breaching-the-wall-between-developers-and-operations/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 09:18:00 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://chrisread.wordpress.com/?p=44</guid>
		<description><![CDATA[I like to describe my job at ThoughtWorks as helping Developers and Operations realize that they&#8217;re playing on the same team. No matter how awesome your code is, how elegantly you&#8217;ve solved the problem at hand, how nice and readable the code is &#8211; if you can&#8217;t get it into production your software is just [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=44&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I like to describe my job at ThoughtWorks as helping Developers and Operations realize that they&#8217;re playing on the same team. No matter how awesome your code is, how elegantly you&#8217;ve solved the problem at hand, how nice and readable the code is &#8211; if you can&#8217;t get it into production your software is just a collection of bits. Likewise, you can have the best network, the most scalable hardware, the neatest cable patching scheme &#8211; but it&#8217;s just a big fancy heater if it&#8217;s not running the code your business needs.</p>
<p>As I&#8217;m normally brought in with the developers, I&#8217;ve been trying to find efficient ways to engage with the client Operations teams. Normally I end up having one on one conversations with various members of the team, try to find out what their current processes are, what their major challenges are and what their concerns are regarding the project I&#8217;m involved in. I usually do this to keep the safety levels high. The problem though is that it takes quite a lot of time and effort to get things going and get some momentum going.</p>
<p>At my current client though I didn&#8217;t have the time or access to the people to do things the normal way. A meeting was arranged with the key Operations stake holders and I effectively had just 2 hours to explain our development process in general, and Continuous Integration and Build Pipelines in detail. While talking with Graham Brooks about what we wanted to cover, he came up with the idea of running it as a mini retrospective.</p>
<p>After the usual introductions, we gave them 15 minutes to list the Good, the Bad and the Puzzles of their current development and release process. We had good participation from the group and as expected had a high number Bad entries. After talking through the cards and grouping them into related sections, we then allowed them to vote on the ones they most wanted to talk about. Most votes went to the core pain points, and we spent the rest of the time talking about how our process would address those issues. It also helped a lot that most of the Good entries related to the automation they already have in place&#8230;</p>
<p>By the end of the meeting no was talking about the bad old days (lobbing releases over the wall). Everyone was engaged starting to get some spirit of collective ownership going in the whole delivery process and that breaking down the walls that exist between the various silos was high on the list of things to do. Rather than talk to them about our process and how we would like to interact with them, we had allowed them to lead the discussion on which elements from our toolbox would have the greatest value for them.</p>
<p>All I need to do now is learn how to be as good a facilitator as Graham was&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/44/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=44&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2008/11/26/retrospectively-breaching-the-wall-between-developers-and-operations/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Continuous Integration Server Comparison 2008</title>
		<link>http://blog.chris-read.net/2008/09/22/continuous-integration-server-comparison-2008/</link>
		<comments>http://blog.chris-read.net/2008/09/22/continuous-integration-server-comparison-2008/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 12:22:10 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://chrisread.wordpress.com/?p=23</guid>
		<description><![CDATA[Early last year I did a Quick Comparison of some of the popular CI servers of the time. Things have moved on since then, and I&#8217;ve actually been involved with the Cruise development team since then. Now that Cruise has been released, a number of people both inside and outside ThoughtWorks have asked me to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=23&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Early last year I did a <a href="http://blog.chris-read.net/2007/02/21/quick-comparison-of-teamcity-12-bamboo-10-and-cruisecontrol-26/" target="_blank">Quick Comparison</a> of some of the popular CI servers of the time. Things have moved on since then, and I&#8217;ve actually been involved with the <a href="http://studios.thoughtworks.com/cruise-continuous-integration" target="_blank">Cruise</a> development team since then. Now that Cruise has been released, a number of people both inside and outside <a href="http://www.thoughtworks.com" target="_blank">ThoughtWorks</a> have asked me to put together a follow up article – here it is.</p>
<p>The list of available products out there has grown a lot in the past 18 months, and the features that they support are really great. Since I did the last review I&#8217;ve actively avoided having a look at the other tools out there to keep a clear focus on what I wanted to see in Cruise. Doing this review has been a great way for me to see what everyone else has been up to.</p>
<p>Just having loads of features does not automatically make for a good tool though. Instead of having a shooting match between who does what, I&#8217;ve taken a little sample Java servlet that I use for demos and tried to get it working with all the tools. This project is hosted on a local subversion repository. I&#8217;m going to try set it up to simply run unit tests and create my distributable .war file. Areas that I&#8217;m going to look at are:</p>
<ul>
<li>Installation (on Linux, OSX and Windows)</li>
<li>Setting up my existing project</li>
<li>What did the tool inspire me to try next</li>
</ul>
<p>Tools that I&#8217;ll be trying out are (in alphabetical order):</p>
<ul>
<li><a href="http://www.anthillpro.com/html/default.html" target="_blank">AntHillPro</a> 3.5.3</li>
<li><a href="http://www.atlassian.com/software/bamboo/" target="_blank">Bamboo</a> 2.1.1</li>
<li><a href="http://studios.thoughtworks.com/cruise-continuous-integration" target="_blank">Cruise</a> 1.0</li>
<li><a href="http://cruisecontrol.sf.net" target="_blank">CruiseControl</a> 2.7.3</li>
<li><a href="https://hudson.dev.java.net/" target="_blank">Hudson</a> 1.252</li>
<li><a href="http://zutubi.com/products/pulse/" target="_blank">Pulse</a> 1.2.56</li>
<li><a href="http://www.jetbrains.com/teamcity/">TeamCity</a> 3.1.2</li>
</ul>
<h2><span id="more-23"></span>AntHillPro</h2>
<h3>Installers</h3>
<p>There are no native platform installers, but you can choose from 3 packages. Each package contains both the server and the agent components.</p>
<ul>
<li>Graphical Java Installer</li>
<li>Windows Command Line Installer</li>
<li>Unix Command Line Installer</li>
</ul>
<h3>Installation</h3>
<p>I chose the Unix Command Line. Unpacked the tarball and ran the script. It&#8217;s unique in that all the script does is kick off an ant build that asks you questions and does the installation. The defaults all seemed pretty reasonable. Installing an agent is done separately and follows the same process. Once you start the processes, hit the web frontend and finish the setup.</p>
<h3>Setting up my project</h3>
<p>This is where things go interesting. There was no obvious “add your project here” button. A bit of clicking around, and I found something under the Admin tab that looked like a good place to start. Then it asked me if I want a Life-Cycle based project or a Non Life-Cycle based one? What&#8217;s a Life-Cycle in this context? I fuddled around and took random guesses, and then figured out that I needed to add a workflow to my project to actually do anything. Fair enough, only I was half way through configuring my new workflow when it asked for my repository, but only gave me a dropdown list to choose from. Back out, into the admin page, find out where to add new repositories, add a Subversion one. Once again try to finish configuring my new project (at least it remembered where I was), but then it all fell apart when trying to add the repository to the workflow. Kept on throwing up “AttributeMissingException: project is missing”. Decided that this had already taken up far too much of my time just to get to this point, and so I gave up.</p>
<h2>Bamboo</h2>
<h3>Installers</h3>
<p>A single installer that contains both the server and the agent.</p>
<ul>
<li>Windows .exe installer</li>
<li>OSX .dmg file</li>
<li>tarball</li>
</ul>
<h3>Installation</h3>
<p>I picked the “Linux” tarball, even though I&#8217;m testing on OSX. I prefer doing this when evaluating products as I think it gives me a better feel for what&#8217;s actually going to be installed, and I&#8217;m guaranteed I can get rid of it efficiently and easily when I&#8217;m done playing with it. Unpackd the tarball, ran the start script. All looks good, but when you try use it it asks you to edit a file in the webapp path pointing to the installation directory. Nasty. Once that&#8217;s fixed and started again, you&#8217;re asked for your license key. There&#8217;s a handy link at the bottom to go get your key, copy paste and you&#8217;re away through the rest of the wizard.</p>
<h3>Setting up my project</h3>
<p>Clicked the Create Plan link. Still has my pet hate of wanting you to specify UPPER CASE KEYS for everything. Are we still using ancient Big Blue iron here that has such limitations? Wants me to specify an ant target which is also a little weird &#8211; I just want the default target! Other than that all very nice. I like how it goes right into the activity page once you&#8217;ve set up your project and you can see what&#8217;s going on, including SVN checkout.</p>
<h3>I then wanted to play with</h3>
<p>Agents. Installed agents on Ubuntu and WinXP (server running on OSX). It&#8217;s pretty easy really. Agent matrix shows you which projects will build on which agents. Also went to look at all the pretty graphs, but I don&#8217;t have much build history right now. Bamboo has built in Clover integration, but I use cobertura in my project for coverage. It looks like they have some interesting reports around code coverage, but I can&#8217;t run them&#8230;</p>
<h2>Cruise</h2>
<p>Disclosure – I wrote the installers for Cruise, so obviously I like them.</p>
<h3>Installers</h3>
<p>Separate installers for the server and the agent components.</p>
<ul>
<li>Windows .exe installer</li>
<li>OSX .app packaged in a zip</li>
<li>Linux RPM and Debian packages</li>
</ul>
<h3>Installation</h3>
<p>This is one of the few products that does not ship a generic tarball or zip file. As I&#8217;m doing all this on a Mac, I pulled down the server and agent zip files, unpacked them, and dragged the .app&#8217;s over to my Applications folder. Double click on each and we&#8217;re up. Once the server is up it opens up the admin interface in your browser. The first thing you&#8217;re asked for is your license key.</p>
<h3>Setting up my project</h3>
<p>The very first thing you&#8217;re hit with (after you&#8217;ve put in your license key) is a wizard to set up your project. Follow the prompts, and fill in where your test results and artefacts are stored. It won&#8217;t let you create the project until it verifies that it can connect to your source repository, so make sure it&#8217;s up before you start.</p>
<h3>I then wanted to play with</h3>
<p>Pipelines. I presented one of the very first papers on Build Pipelines with Jez Humble (now product manager for Cruise) and Dan North at Agile 2006. When I first started implementing them I had to do all kinds of unholy hacks with CruiseControl, but the benefit of using CI like this was well worth the pain at the time. At the moment you have to jump into nasty XML to configure pipelines in Cruise, but the whole process should be wizarded up in the next release. Having lots of agents allows you to split up jobs in your pipeline stages quite nicely so they run in parallel and speed up your feedback loop.</p>
<p>The other great feature I like that product companies are always asking me about is the ability to run parallel builds for a stage on multiple platforms. Whether you&#8217;ve got a .Net app that you need to test across multiple versions of Windows, or a web app that needs to be tested from a whole matrix of different web browsers, Cruise makes it easy to run the same tests in all these different environments using the same build of your application. If the tests pass on all of them, your stage will pass, and you know that your product is playing nicely with all of them.</p>
<h2>CruiseControl</h2>
<h3>Installers</h3>
<ul>
<li>Windows .exe installer</li>
<li>Generic zip file</li>
</ul>
<h3>Installation</h3>
<p>More unzip and run script. It just comes up with the sample project.</p>
<h3>Setting up my project</h3>
<p>This is where the venerable Granddaddy of CI servers really started showing it&#8217;s age. I had to manually check out my project, then edit the xml config file to get it going. If I&#8217;d not been using it for almost 4 years I&#8217;d get pissed off and move along.</p>
<h3>I then wanted to play with</h3>
<p>Something else. If you&#8217;re using it already and it&#8217;s doing the job you want it to, then there is no real reason to change. If you&#8217;re new to CI and are looking for something easy to get you started, then I&#8217;m sad to say I suggest you look elsewhere&#8230;</p>
<h2>Hudson</h2>
<h3>Installers</h3>
<ul>
<li>A single war file for everyone.</li>
</ul>
<h3>Installation</h3>
<p>The most basic of all, just run java -jar hudson.war or drop the war file into your favourite servlet container. Makes it kinda hard to know what version you have though, and by the look if it they release new versions quite regularly.</p>
<h3>Setting up my project</h3>
<p>Not too bad. Pointing at unit test and artefacts was a bit weird as it starts one level higher than I expected. I liked the weather reports. Because the build was failing (because it could not publish any artefacts or find test results), it had little storm clouds. Nice.</p>
<h3>I then wanted to play with</h3>
<p>The plugins. There&#8217;s quite a few, and I like how you can just download them and go.</p>
<h2>Pulse</h2>
<h3>Installers</h3>
<ul>
<li>Windows .exe installer</li>
<li>tarball</li>
<li>zip</li>
</ul>
<h3>Installation</h3>
<p>Another unpack the tarball and run the start script. I see a trend here. Hit the web interface and it asks you for a data directory. Also needs a license key to get going, but has a nice link there to go get one.</p>
<h3>Setting up my project</h3>
<p>Nice start screen with list of things to do. Hit add project, then got confused about what the URL was it was asking for. Got a test button for your SCM &#8211; yay! Setting up the artefacts you want is easy, it all just works. Only thing I can moan about is that I can&#8217;t see what&#8217;s going on in the builds, and it feels slower than the rest for some reason.</p>
<h3>I then wanted to play with</h3>
<p>Personal builds! It&#8217;s not something I&#8217;ve ever played around with, but it looked kinda straight forward with pulse, and it is! Just install a little tool on your development workstation and use it to invoke a personal build. Does require a bit of extra data in the project, but it&#8217;s great.</p>
<p>It also has agents. I love agents. They have an interesting way of doing them though. You point the agent at the server. I suppose that&#8217;s one way of getting around the security implications of other people getting their hands on your code. Agents auto-discover what their hosts provide, and when configuring a project you get a drop down list of what&#8217;s provided already. You&#8217;ve still got the freedom to add your own stuff too.</p>
<p>It has stages, kinda like our build pipelines. To use them nicely though you need to start editing their XML, but they&#8217;ve got great help along the right for you to see what your options are. Their stages run in parallel, so it&#8217;s not really like our Cruise pipelines, but at least they got the parallel stuff going.</p>
<h2>Team City</h2>
<h3>Installers</h3>
<ul>
<li>Windows .exe installer</li>
<li>tarball</li>
</ul>
<h3>Installation</h3>
<p>Unpack the tarball, find and run the start script.</p>
<h3>Setting up my project</h3>
<p>Hit the Create Project button. Interesting that you create the project first, then add the config after. Test SCM button. Auto tagging and code coverage built in. Nice. Also agent based. Option to automagically run emma for you. Tried it, but because I already use cobertura it barfed. It lost my artefacts config somehow. Lots of options. Also by default does not trigger a build on check in &#8211; what&#8217;s with that?</p>
<h3>I then wanted to play with</h3>
<p>Integration with IntelliJ. I&#8217;m a big fan of IntelliJ and use it a lot. It makes sense in a developer centric world, because the IDE is the developers portal into the world of code. I like the way you can click on a failed test and it takes you to the test code, as well as the ability to take responsibility for fixing a broken build.</p>
<h2>Summary</h2>
<p>The world of CI servers has come a long way in the past 18 months. It&#8217;s certainly reinforced my belief that competition is a great driver for innovation. When I started at ThoughtWorks clients would often complain that they&#8217;d like to do Continuous Integration, but setting up a CI server was way too hard. Complexity of tool configuration is now no longer an acceptable excuse for not doing CI.</p>
<p>It&#8217;s also great to see the trend of agents being so popular. The days of having a big mother of a build server for a project or small group of teams is over. After one of the Cruise demos I did here in the UK our client commented that it was great that he could finally find a use for all the overpowered desktop machines their managers have – use them as build agents!</p>
<p>As a final note for those of you who are trying to decide on what CI server to use &#8211; remember to pick one that supports your process and what you want CI to do for you.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=23&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2008/09/22/continuous-integration-server-comparison-2008/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Speaking at JAOO 2008</title>
		<link>http://blog.chris-read.net/2008/09/12/speaking-at-jaoo-2008/</link>
		<comments>http://blog.chris-read.net/2008/09/12/speaking-at-jaoo-2008/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 15:54:01 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://chrisread.wordpress.com/?p=30</guid>
		<description><![CDATA[I&#8217;m busy adding the finishing touches to my talk for JAOO this year and I&#8217;ve just realised that I&#8217;ve not let you guys know that I&#8217;m going to be there. Consider yourself warned. Last year at the conference I got a chance to show off the new UI we did for CruiseControl with Erik Dörnenburg. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=30&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m busy adding the finishing touches to my talk for <a href="http://jaoo.dk/conference/" target="_blank">JAOO</a> this year and I&#8217;ve just realised that I&#8217;ve not let you guys know that I&#8217;m going to be there. Consider yourself warned.</p>
<p>Last year at the conference I got a chance to show off the new UI we did for <a href="http://cruisecontrol.sourceforge.net/" target="_blank">CruiseControl</a> with <a href="http://erik.doernenburg.com/" target="_blank">Erik  Dörnenburg</a>. Afterwards I was having a chat with <a href="http://martinfowler.com/" target="_blank">Martin Fowler</a>, and I commented on how I&#8217;d like to see a whole track at JAOO dedicated to Building and Deploying software. While I&#8217;m sure I can&#8217;t take all the credit for it, this year there is going to be a short <a href="http://jaoo.dk/tracks/show_track.jsp?trackOID=175" target="_blank">Build track</a> with me talking about Continous Integration. Hope to see you there&#8230;</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/chrisread.wordpress.com/30/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/chrisread.wordpress.com/30/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=30&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2008/09/12/speaking-at-jaoo-2008/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Ant can be less verbose than Java</title>
		<link>http://blog.chris-read.net/2008/08/05/ant-can-be-less-verbose-than-java/</link>
		<comments>http://blog.chris-read.net/2008/08/05/ant-can-be-less-verbose-than-java/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 17:14:08 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://chrisread.wordpress.com/?p=19</guid>
		<description><![CDATA[I had one of those rare opportunities today when I got to pair with one of the developers on our project. The story he&#8217;s working on has to do with generating usage documentation for a webservice at runtime. What he wanted was a list of source files to be available at runtime. The solution he [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=19&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I had one of those rare opportunities today when I got to pair with one of the developers on our project. The story he&#8217;s working on has to do with generating usage documentation for a webservice at runtime. What he wanted was a list of source files to be available at runtime. The solution he came up with (which does work) was the following Java program:</p>
<pre>package com.example.service.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

public class ListControllers {
    public static void main(String[] args) throws IOException {
        String outputFile = args[0];
        String srcDir = args[1];
        File f = new File(srcDir);
        File serverDir = new File(f, "com/example/service/server");
        String[] entries = serverDir.list();
        Arrays.sort(entries);
        BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile, false));
        for(String entry : entries) {
            if(entry.endsWith("Controller.java")) {
                writer.write(name + "\n");
            }
        }
        writer.flush();
        writer.close();
    }
}</pre>
<p>This was then called by the following Ant snippet:</p>
<pre>&lt;mkdir dir="${target.dir}/war/WEB-INF/classes"/&gt;
&lt;java classname="com.example.service.utils.ListControllers"
      classpath="${main.jar}" failonerror="true"&gt;
    &lt;arg value="${target.dir}/war/WEB-INF/classes/controller.list"/&gt;
    &lt;arg value="${src.dir}"/&gt;
&lt;/java&gt;</pre>
<p>This was then bundled up in the war file so that he could get his mits on it at runtime. It works, but is not without problems. My primary complaint is that it makes the build harder to understand. To figure out what&#8217;s going you need to find and open up the .java file, and be able to understand Java in the first place.</p>
<p>After a few minutes of pairing we managed to fix it with the following Ant snippet:</p>
<pre>&lt;mkdir dir="${target.dir}/war/WEB-INF/classes"/&gt;
&lt;pathconvert property="controller.list.propery"
             pathsep="${line.separator}"&gt;
    &lt;sort&gt;
        &lt;path&gt;
            &lt;fileset dir="${src.dir}/com/example/service/server"
                     includes="*Controller.java"/&gt;
        &lt;/path&gt;
    &lt;/sort&gt;
    &lt;map from="${src.dir}/com/example/service/server/" to=""/&gt;
&lt;/pathconvert&gt;
&lt;echo message="${controller.list.propery}"
    file="${target.dir}/war/WEB-INF/classes/controller.list"/&gt;</pre>
<p>Not only is it now easy to see what we&#8217;re trying to do in the build file, but we managed to replace 29 lines of Java + Ant with 10 lines of Ant. Sweet!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/chrisread.wordpress.com/19/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/chrisread.wordpress.com/19/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/19/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=19&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2008/08/05/ant-can-be-less-verbose-than-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>CruiseControl and Buildix 2 at JAOO 2007</title>
		<link>http://blog.chris-read.net/2007/09/26/cruisecontrol-and-buildix-2-at-jaoo-2007/</link>
		<comments>http://blog.chris-read.net/2007/09/26/cruisecontrol-and-buildix-2-at-jaoo-2007/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 14:49:10 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://www.chris-read.net/index.php/2007/09/26/cruisecontrol-and-buildix-2-at-jaoo-2007/</guid>
		<description><![CDATA[I&#8217;ve been at JAOO for the past few days, and while here I had a chance to do a presentation with Erik Doernenburg on Continuous Integration and CruiseControl. We used the new Beta version of Buildix 2 to show people the new CruiseControl Dashboard, and quite a few people were impressed with it. Favourite features [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=15&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been at <a href="http://jaoo.dk" title="JAOO" target="_blank">JAOO</a> for the past few days, and while here I had a chance to do a presentation with <a href="http://erik.doernenburg.com/" target="_blank">Erik Doernenburg</a> on Continuous Integration and <a href="http://cruisecontrol.sf.net" target="_blank">CruiseControl</a>. We used the new <a href="http://buildix.thoughtworks.com/beta.html" target="_blank">Beta</a> version of Buildix 2 to show people the new CruiseControl <a href="http://cruisecontrol.sourceforge.net/dashboard.html" target="_blank">Dashboard,</a> and quite a few people were impressed with it. Favourite features were the <a href="http://confluence.public.thoughtworks.org/display/CCNET/CCTray" target="_blank">CCTray</a> integration, and the ability to see the status of a large number of projects at a glance.</p>
<p>As always, there were also people who were interested in hearing about how it can be used for non Java projects. I had a good chat to one person who is interested in using it on a mixed Common LISP and <a href="http://www.erlang.org/" target="_blank">Erlang</a> project he&#8217;s working on. I&#8217;m looking forward to hearing how it goes for him. Due to lack of experience on my part I could unfortunately not help him much with the <a href="http://darcs.net/" target="_blank">darcs</a> problems he&#8217;s having though. Some people have all the fun&#8230;</p>
<p>It was also quite useful to speak to people about the problems they&#8217;re currently facing when trying to use CruiseControl. A common theme is people trying to manage large numbers of builds, or trying to build products across large numbers of different platforms. These are problems the dedicated ThoughtWorks development team are currently working on, so it&#8217;s great to get the validation that we&#8217;re putting effort into the things people care about now.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/chrisread.wordpress.com/15/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/chrisread.wordpress.com/15/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=15&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2007/09/26/cruisecontrol-and-buildix-2-at-jaoo-2007/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Using CruiseControl for non-Java Projects</title>
		<link>http://blog.chris-read.net/2007/03/05/using-cruisecontrol-for-non-java-projects/</link>
		<comments>http://blog.chris-read.net/2007/03/05/using-cruisecontrol-for-non-java-projects/#comments</comments>
		<pubDate>Mon, 05 Mar 2007 09:57:04 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.chris-read.net/?p=14</guid>
		<description><![CDATA[A lot of people are under the impression that CruiseControl is solely intended for Java projects. This is a common misconception. At my current client we&#8217;re using CruiseControl to build a 15 year old, 2.5 million line mixed C/C++ app using GNU make. We&#8217;re also using it to build and functionally test a new C [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=13&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A lot of people are under the impression that CruiseControl is solely intended for Java projects. This is a common misconception. At my current client we&#8217;re  using CruiseControl to build a 15 year old, 2.5 million line mixed C/C++ app  using GNU make. We&#8217;re also using it to build and functionally test a new C app  we&#8217;re writing as part of the project. I&#8217;ve also used it in the past on Python  apps.</p>
<p>There are a number of ways to do this,  and they all really depend on what you&#8217;re using Cruise for. If you&#8217;re simply  using it for compilation, then you can simply use &lt;exec&gt; to  call make (or whatever you&#8217;re building with). By default it will break the build if the command returns a non-zero  return code, so it should be smart enough to do this out of the box. I know that  some of our Ruby projects that use this method too.</p>
<p>My personal preference is to get CruiseControl to do an Ant build, which  has some additional logic, including taging the source repository with the build  label if the build passes. The approach is very similar in this case, and has the  following steps:</p>
<ul>
<li>Have ant do any  additional work/checks you want to ensure the environment is how you want  it.</li>
<li>Update my working copy to an exact known  version that can be tagged at a later stage if the build is good (primarily a  CVS problem, not really needed if you&#8217;re using  Subversion).</li>
<li>Use the  &lt;exec&gt; task from  ant to run the build</li>
<li>If you have additional  tests to run, use an  &lt;exec&gt; within a  &lt;parallel&gt; block to start your  newly built binary in the background, then run the  tests</li>
<li>If everything is good and passes, tag  your source code with the build label.</li>
</ul>
<p>So,  although it is fairly easy to add build plugins for various other projects, you  can save yourself a bit of pain simply using the  one &lt;exec&gt; or shelling  out of an  &lt;ant&gt; builder.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/chrisread.wordpress.com/13/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/chrisread.wordpress.com/13/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/13/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=13&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2007/03/05/using-cruisecontrol-for-non-java-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick Comparison of TeamCity 1.2, Bamboo 1.0 and CruiseControl 2.6</title>
		<link>http://blog.chris-read.net/2007/02/21/quick-comparison-of-teamcity-12-bamboo-10-and-cruisecontrol-26/</link>
		<comments>http://blog.chris-read.net/2007/02/21/quick-comparison-of-teamcity-12-bamboo-10-and-cruisecontrol-26/#comments</comments>
		<pubDate>Wed, 21 Feb 2007 21:41:53 +0000</pubDate>
		<dc:creator>Chris Read</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.chris-read.net/?p=13</guid>
		<description><![CDATA[One of the things I spend a lot of my life doing is looking after Continuous Integration environments. As I work for ThoughtWorks, and am one of the guys who created Buildix, it should come as no surprise that this is all done with CruiseControl. However, in the past few months there a few new [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=12&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the things I spend a lot of my life doing is looking after <a target="_blank" href="http://www.martinfowler.com/articles/continuousIntegration.html">Continuous Integration</a> environments. As I work for <a target="_blank" title="ThoughtWorks" href="http://www.thoughtworks.com">ThoughtWorks</a>, and am one of the guys who created <a target="_blank" title="Buildix" href="http://buildix.thoughtworks.com">Buildix</a>, it should come as no surprise that this is all done with <a target="_blank" title="CruiseControl" href="http://cruisecontrol.sf.net">CruiseControl</a>. However, in the past few months there a few new Continuous Integration tools that have crept out onto the scene. The two that I hear the most about are <a target="_blank" title="TeamCity" href="http://www.jetbrains.com/teamcity/">TeamCity</a> and <a target="_blank" title="Bamboo" href="http://www.atlassian.com/software/bamboo/">Bamboo</a>. I finally managed to get a few hours to test them out, and here&#8217;s my impressions.</p>
<p>One of the things I wanted to see was how quick and easy it was to get these tools up and running. With this in mind, I specifically decided in advance to pull down the .war bundle of each one and try that out. In my experience, this would be the one that most of the clients I&#8217;ve been at would have gone for.</p>
<p><strong>Notes:</strong></p>
<ul>
<li>This is very much a first impressions run of the products &#8211; I had a limited time window (2 hours total) to do this in.</li>
<li>People could quite fairly say that I have a biased view, but I&#8217;ve tried to keep this as fair as possible.</li>
<li>I only tested doing an Ant build of a simple sample webapp from a subversion repository.</li>
<li>You have to buy a license for TeamCity and Bamboo (I got evaluation licenses for both), but CruiseControl is still free&#8230;</li>
</ul>
<p><strong>Test Environment:</strong></p>
<ul>
<li>Fedora Core 4</li>
<li>Via C3 800 server with 512Mb RAM</li>
<li>Sun Java 1.6.0-b105</li>
<li>Apache Ant 1.7.0</li>
<li>Jetty 6.1.1</li>
<li>Subversion 1.2.3</li>
</ul>
<p><span id="more-12"></span></p>
<p><strong>TeamCity 1.2</strong></p>
<p>This is the one I&#8217;ve heard the most about, and the one I&#8217;ve been most keen to try out. Back in the days when I used to be a developer, our IDE&#8217;s were nothing much more than glorified syntax highlighters. I&#8217;d poked Eclipse a few times in the early days, and not really seen what the fuss was about. Then I spent 10 weeks in a small room <a href="http://apcj.blogspot.com/">Alistair Jones</a> and James Lewis. They kindly took some time to show me all the funky thinks <a href="http://www.jetbrains.com/idea/">IntelliJ</a> could do. If JetBrains can write an IDE that is so good, what could they do if they turned their minds to CI?</p>
<p>Getting the webapp up and running was pretty simple (as expected). I did notice some errors scroll past the Jetty console, but chose to ignore them initially as things didn&#8217;t seem too bad. Things started to get a bit wobbly when it came to getting the agent running though. There are some basic typos in their install documentation that had me scratching my head for a minute or two. Trying to get the agent to play nice with the webapp was more of a pain, lots of NullPointerExceptions all over the place. As it all seemed to be in XML parsing, I decided to gear back to Java 1.5 and this got all the NPE&#8217;s to go away. I now had an agent up and running! Which is where my first concern pops up. It appears anyone can just spark up an agent and point it at TeamCity. I can see all those afflicted with <a href="http://en.wikipedia.org/wiki/Sarbox">SarBox</a> liking that.</p>
<p>There was not much that was configurable for the rest of the system. Mail and IM server details were pretty much it, so I decided to move on to trying to get it to do some builds.</p>
<p>I did manage to get a project configured, but things pretty much went downhill from there. I got lots of strange errors all over the place when trying to look at build reports. Bouncing the webapp seemed to trigger the agent into doing a build, but I could not get it to trigger a build from a checkin.</p>
<p>In short &#8211; quite a disappointment really. I&#8217;ll have to try out the release they bundle with Tomcat to see if that is any better. I also didn&#8217;t try get it to play with IDEA, which I&#8217;m starting to feel is what it&#8217;s all about really.</p>
<p><strong>Bamboo 1.0</strong></p>
<p>I&#8217;d only recently heard of Bamboo. I&#8217;ve used other Atlassian products (<a target="_blank" href="http://www.atlassian.com/software/jira/">Jira</a> and <a target="_blank" href="http://www.atlassian.com/software/confluence/">Confluence</a>) in the past, and so was a bit apprehensive about what this would be like as I find their other products a bit heavy. Would this be more of the same?</p>
<p>Installation was a breeze (as it is with their other products). The only bump was having to unpack the war file (one of my pet hates) to open up a properties file to set the <em>bamboo.home</em> property. It was only once I edited the file that I saw this could be set as a system property. It would have made me a whole lot happier if the nice initial system check screen had told me I could set this as a property instead of telling me to unpack a .war.</p>
<p>There are quite a few interesting system options you can set. I quite liked having a global build expiry option, and the separate build queues concept (didn&#8217;t get to play with it though). Other options I quite liked were the global JVM and Builder lists. Time to move on to actually setting something up.</p>
<p>Creating a project is pretty simple, the only thing that annoyed me the typical Atlassian fixation for mainframe style descriptors. Each project needs to have a ALLCAPSNOSPACESDESCRIPTOR to identify itself. Most intuitive. Everything else was pretty self explanitory. Even selecting build artifacts was a joy. Once the project is created, it does an initial checkout and build.</p>
<p>Now to trigger a build. This is one area they still need a bit of work on. While Bamboo did trigger a build correctly when I made repository changes, the polling mechanism is a bit heavy. It seems to do an update, and then if anything has changed it will build. Finding details on what exactly triggered the build also takes some digging, it&#8217;s not that obvious. One thing I do like though is that it keeps a history of individuals activity. You can drill down to each user and see their checkin rate, build breaking rate, build fixing rate, etc. I can see the <a target="_blank" title="Pointy Haired Boss" href="http://en.wikipedia.org/wiki/Pointy_Haired_Boss">PHB</a> types signing the cheque for this feature alone.</p>
<p>Other features I like are the way they show the ant log files for each build, and also how you can effectively tail the log file of a build in progress. The way it parses your JUnit results is also pretty nifty, going as far as building an English sentence for each of your tests if you name them in the recommended <em>testShouldDescribeWhatTheTestIsDoing</em> format.</p>
<p>Things that I felt were missing were auto refresh of your status screen, and the email reports didn&#8217;t trigger when I expected them too, and the format was pretty primitive. It also takes a long time for the app to start (probably because of the Hibernate over HSQL database it keeps everything in), and app response is pretty slow.</p>
<p>In short &#8211; not bad for a 1.0 release! Functional, but not sure if I&#8217;d use it&#8230;</p>
<p><strong>CruiseControl 2.6</strong></p>
<p>I&#8217;ve not had a chance, or the need, to upgrade any of the systems I look after to Cruise 2.6. They&#8217;re all running on 2.5 and doing pretty well. While I admit that using this on a daily basis gives it somewhat of an unfair advantage, I think it also means I&#8217;ve probably got less to say about it.</p>
<p>First off, installation is pretty easy if you&#8217;re using the embedded Jetty for your reporting. If you want to do what I&#8217;ve done with the others and run it in your own container, it&#8217;s not that much harder. The only things you need to do are edit the startup script, and edit the web.xml file in the webapp to point it to all the correct directories. As I said above, this is a pet hate of mine.</p>
<p>Configuring a new project is a real bitch after using the other two. Even with my experience, and even using the sample connectfour project as a template, I still managed to get a type in there. Enough said on the configuration front.</p>
<p>Things I still liked about it compared to the others was the speed. It&#8217;s small, simple, and fast. That&#8217;s a key thing for me as CI is all about fast feedback, and if your tools are taking their time, you&#8217;re reducing your feedback loop. The other important thing about feedback is the information. Although the others all look pretty, there is still some basic information they&#8217;re missing for the builds &#8211; who changed what and why.</p>
<p>The new kids on the block are really make the grand pappy of them all show its age. I don&#8217;t think this is a bad thing though. New ideas should always be welcome in any field. They also show how much they still have to learn.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/chrisread.wordpress.com/12/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/chrisread.wordpress.com/12/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrisread.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrisread.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrisread.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrisread.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrisread.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrisread.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrisread.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrisread.wordpress.com/12/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.chris-read.net&amp;blog=4083712&amp;post=12&amp;subd=chrisread&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.chris-read.net/2007/02/21/quick-comparison-of-teamcity-12-bamboo-10-and-cruisecontrol-26/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Chris Read</media:title>
		</media:content>
	</item>
	</channel>
</rss>
