<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>ccnet &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/ccnet/</link>
	<description>Feed of posts on WordPress.com tagged "ccnet"</description>
	<pubDate>Sun, 06 Dec 2009 13:50:18 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Move CCNET to a different server]]></title>
<link>http://p3john.wordpress.com/2009/09/17/move-ccnet-to-a-different-server/</link>
<pubDate>Thu, 17 Sep 2009 22:13:18 +0000</pubDate>
<dc:creator>p3john</dc:creator>
<guid>http://p3john.wordpress.com/2009/09/17/move-ccnet-to-a-different-server/</guid>
<description><![CDATA[I have been using CCNET for about a year now and love it. Once setup, it makes automating the proces]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I have been using CCNET for about a year now and love it. Once setup, it makes automating the process of compiling software easy and fast &#8211; which makes me and my customers happy.
<p>Yesterday I decide, pretty much on a whim, to move my build server to a new, slightly used, server. Turns out it was pretty easy, here’s how I did it…</p>
<p>First, setup the new server:</p>
<ul>
<li>Install the same version of CCNET (version 1.4.2.14), </li>
<li>Install the SVN client (if you use SVN),</li>
<li>Install any other software you need to during the build process… stuff like NUnit, NAnt, the Windows SDK, and 3rd party controls (I use DevExpress), etc. </li>
</ul>
<p>Next, stop the CCNET service on the new server and copy the ccnet.config, ccnet.exe.config, and ccservice.exe.config from the old server to the new server.    <br />Also, copy over the build projects – for example I use NAnt, so I copied those build scripts.     <br />Don’t forget the state files from the old server – otherwise when you run the builds on the new server the state of the build will revert to a first build state. </p>
<p>Restart the CCNET service on the new server and that should do it.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[HTTP Error 500.23 - Internal Server Error : An ASP.NET setting has been detected that does not apply in Integrated naged pipeline mode]]></title>
<link>http://nightbugs.wordpress.com/2009/09/11/http-error-500-23-internal-server-error-an-asp-net-setting-has-been-detected-that-does-not-apply-in-integrated-naged-pipeline-mode/</link>
<pubDate>Fri, 11 Sep 2009 06:04:03 +0000</pubDate>
<dc:creator>sborkar</dc:creator>
<guid>http://nightbugs.wordpress.com/2009/09/11/http-error-500-23-internal-server-error-an-asp-net-setting-has-been-detected-that-does-not-apply-in-integrated-naged-pipeline-mode/</guid>
<description><![CDATA[1.Changed the app pool of the default web site to &#8220;Classic .NET AppPool&#8221; The ccnet site ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>1.Changed the app pool of the default web site to &#8220;Classic .NET AppPool&#8221;  The ccnet site is now appearing in IIS     under default web.<br />
2.Changed the app pool of ccnet site to &#8220;Classic .NET AppPool&#8221;.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Ring-a-Round 2: Queens University Belfast v Doug Keenan]]></title>
<link>http://wattsupwiththat.com/2009/08/20/ring-a-round-2-queens-university-belfast-v-doug-heenan/</link>
<pubDate>Thu, 20 Aug 2009 13:58:51 +0000</pubDate>
<dc:creator>John A</dc:creator>
<guid>http://wattsupwiththat.com/2009/08/20/ring-a-round-2-queens-university-belfast-v-doug-heenan/</guid>
<description><![CDATA[WUWT readers may recall that Queens University Belfast is being asked to provide tree ring data and ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>WUWT readers may recall that Queens University Belfast is being asked to provide tree ring data and so far has been refusing all but a small portion. Here is an update on that story first carried in WUWT.</p>
<p><strong>Guest Post by John A</strong></p>
<div class="wp-caption alignnone" style="width: 443px"><img src="http://www.msstate.edu/dept/geosciences/CT/TIG/WEBSITES/LOCAL/Summer2003/Harman_Pamela/tree%20rings.JPG" alt="http://www.msstate.edu/dept/geosciences/CT/TIG/WEBSITES/LOCAL/Summer2003/Harman_Pamela/tree%20rings.JPG" width="433" height="312" /><p class="wp-caption-text">Image courtesy Mississippi State University Dept of Geosciences</p></div>
<p>Following on from the <a href="http://wattsupwiththat.com/2009/08/14/another-uk-climate-data-scandal-is-emerging/" target="_blank">last post on Doug Keenan&#8217;s struggle to get tree ring data</a> from Queen&#8217;s University, Belfast, we have Mike Baillie from QUB to explain to Benny Peiser of CCNet:</p>
<blockquote><p>Dear Benny,</p>
<p>although I am retired from basic dendrochronological work, I would like to correct a small part of the diatribe against Queen&#8217;s University, Belfast, that you carried on CCNet on the 15 August, namely the allegation that we are deliberately withholding data of climatic significance.</p>
<p>Your source, Mr Keenan, gives the impression that data from only one Irish oak site is available, namely Garryland Wood, Co Galway.  This is a site he used in an attempted correlation with temperature records.  He points out the problem of dealing with data from an individual site, and states that &#8220;Those problems could be at least partially addressed by considering the individual trees at the site, rather than the average for the site, and also by considering trees at other sites in the British Isles.  Doing so would presumably lead to additional increases in the correlation (that he found between Garryland tree rings and temperature records)&#8221;.<!--more--></p>
<p>Now any fair minded reader would take it from that quotation that &#8220;the individual tree&#8221; data from Garryland is not available.  Also that same reader would take it that data from other &#8220;trees at other sites in the British Isles&#8221; are not available.  Presumably, if the data were available, Mr Keenan would have extended his analysis in the search for an even better correlation between tree-growth in the British Isles and temperature, either local or Hemispheric.</p>
<p>The point is, not only are the individual tree data (14 trees) available from Garryland Wood, but equivalent individual tree-ring data is available from twelve other modern oak sites in Ireland, namely Ardara, Baron&#8217;s Court, Breen Wood, Caledon, Cappoquin, Enniscorthy, Glen of the Downs, Killarney, Loch Doon, Rostrevor and Shane&#8217;s Castle.  Moreover, individual tree data is also available for seven English and Scottish sites originally sampled by myself and colleagues at Belfast.  Thus anyone wanting to undertake research on tree-rings from the British Isles with respect to climate variables simply has to go into the NOAA World Data Centre for Paleoclimatology and access the data laboriously assembled, measured, documented and presented by workers at <a class="zem_slink" title="Queen's University Belfast" rel="geolocation" href="http://maps.google.com/maps?ll=54.5841666667,-5.93472222222&#38;spn=1.0,1.0&#38;q=54.5841666667,-5.93472222222%20%28Queen%27s%20University%20Belfast%29&#38;t=h">Queen&#8217;s University Belfast</a>.</p>
<p>These comments are necessary because Mr Keenan has stated on your web site that at &#8220;QUB researchers do not have the expertise to analyse the data themselves and they do not want to share their data with other researchers who do&#8221;. Personally I would like an apology from both Mssrs Keenan and Peiser. However, I don&#8217;t expect to see one.</p>
<p>Mike Baillie</p>
<p>EDITOR&#8217;S NOTE [Benny Peiser]: Mike &#8211; Thanks for your response to Doug Keenan&#8217;s account. Let me make just one correction, as far as my role as editor of CCNet is concerned. Contrary to your perception, Keenan did not publish his text on my website. He published it on a popular U.S. climate blog called &#8220;Watts Up With That.&#8221; &#60;<a href="http://wattsupwiththat.com/2009/08/14/another-uk-climate-data-scandal-is-emerging/" target="_blank">http://wattsupwiththat.com/2009/08/14/another-uk-climate-data-scandal-is-emerging/</a>&#62; I only forwarded the essay because I considered it to be in the public interest, particularly in light of the ongoing data withholding controversy surrounding CRU (see &#60;<a href="http://www.nature.com/news/2009/090812/full/460787a.html" target="_blank">http://www.nature.com/news/2009/090812/full/460787a.html</a>&#62; ). In short, just because I circulated Doug Keenan&#8217;s text does not mean that I support his views or claims. As the CCNet disclaimer states explicitly: &#8220;The opinions, beliefs and viewpoints expressed in the articles and texts and in other CCNet contributions do not necessarily reflect the opinions, beliefs and viewpoints of the editor.&#8221; I hope this clarification will reassure you. BJP</p></blockquote>
<p>Well it appears that Doug Keenan is not apologizing or going away:</p>
<blockquote><p>D.J. Keenan &#60;<a href="mailto:doug.keenan@informath.org">doug.keenan@informath.org</a>&#62;</p>
<p>Following are some comments on the claims in the Response of Mike Baillie (CCNet, 18 August 2009).</p>
<p>The Response claims that &#8220;anyone wanting to undertake research on tree-rings from the British Isles with respect to climate variables simply has to go into the NOAA World Data Centre for Paleoclimatology and access the data laboriously assembled, measured, documented and presented by workers at Queen&#8217;s University Belfast&#8221;.</p>
<p>Only a tiny portion of the data from QUB is in the World Data Centre (i.e. ITRDB). For example, there is no data in the ITRDB for prior to AD 1500; yet measurements go back 7000 years&#8211;as Baillie&#8217;s own publications state.</p>
<p>QUB originally made the same claim, but has now admitted that most data is on disks that have not been uploaded. And the Assistant Information Commissioner has visited QUB, and confirmed that he saw much more data. That most of the data has not been uploaded and that QUB has been &#8220;deliberately withholding data of climatic significance&#8221; (Baillie&#8217;s phrase) is thus provable, acknowledged by QUB, and independently verified.</p>
<p>The Response also claims that my post &#8220;gives the impression that data from only one Irish oak site is available, namely Garryland Wood&#8221;. It further claims that my post implied &#8220;the individual tree data from Garryland is not available&#8221;. These claims are not based on my main post, but on the page, linked by my post, at &#60;<a href="http://www.informath.org/apprise/a3900/b910.htm" target="_blank">http://www.informath.org/apprise/a3900/b910.htm</a>&#62;</p>
<p>That page presents a short, simplified, theory how Ireland is uniquely affected by the North Atlantic Drift and deep water formation and how this links with global climate.  Briefly, if you had to pick one place in the world to study the climate, Ireland would seem to be it.</p>
<p>After presenting the theory to support that, the page gives a simple example, to illustrate that the theory works in practice. The example uses averages from one site in Ireland&#8211;Garryland Wood&#8211;and some basic mathematics&#8211;correlation and addition. This was done so that readers who are unfamiliar with the relevant science could judge the viability of the theory for themselves, at least to some extent. (The page was originally written for people who might not have any scientific training &#8212; staff at the Information Commissioner&#8217;s Office and the Aarhus Convention Secretariat, to support my requests for the data.)</p>
<p>After presenting the simplified example, the page notes that a proper analysis should consider individual trees, trees at other sites, and more sophisticated mathematics.  The claims of the Response are based on misrepresenting all this, as if the example comprised the only data and the only mathematics that were available. Those claims are thus baseless.</p>
<p>The Response additionally quotes from my post, &#8220;QUB researchers do not have the expertise to analyse the data themselves&#8221;, and says that Baillie wants an apology for that. If Baillie has the expertise, why did he never publish any research using it?  Moreover, I have had several discussions with Baillie over the years, and have a rough idea of his mathematical skills. The branch of statistics that seems most relevant for analyzing the data (multidimensional time series, probably nonlinear) is difficult and specialized: if Baillie can pass an introductory-level examination in the subject, I&#8217;ll pay a large sum. (Note: I would not pass either.)</p>
<p>To summarize, the untruthfulness in Baillie&#8217;s Response is so obvious that it seems unlikely that it was intended to be believed. Rather, this is perhaps just Baillie&#8217;s way of saying &#8220;go away&#8221;. Up until 2005, there would have been nothing that could be done.  In 2005, though, the UK Freedom of Information Act came into effect. I look forward to seeing the Act enforced for such important data.</p>
<p>Douglas J. Keenan<br />
<a href="http://www.informath.org/" target="_blank">http://www.informath.org</a></p></blockquote>
<p>Now all of this is really about principles &#8211; the question of ownership of scientific data and the principle of scientific replicability and analysis that can only happen if data and methodology are willingly shared.</p>
<p>Doug also noted to me that the <a href="http://blogs.nature.com/news/thegreatbeyond/2009/08/climate_researcher_vs_foi_part.html" target="_blank">blog at Nature also mentions this spat</a> and Doug appears to think that Nature is being rather disparaging about him being  praised on <a href="http://www.climateaudit.org/?p=884">Climate Audit</a>. I can&#8217;t quite see the slight myself but then I&#8217;m not an academic trying to protect my hoard of data from hordes of unwashed mathematical analysts who &#8220;might find something wrong with it&#8221;.</p>
<p>I think more importantly that both Climate Audit and WUWT have both opened the way for many people to reanalyze what we&#8217;re been told by populist magazines like Nature or Science <a href="http://www.phdcomics.com/comics/archive.php?comicid=1201" target="_blank">which cheerfully admits that they filter their received papers</a> to those that are deemed &#8220;provocative&#8221; by junior editors. Its easy to see how a science magazine&#8217;s published output can be skewed to the belief system of those junior editors.</p>
<div class="zemanta-pixie" style="margin-top:10px;height:15px;"><strong>Prediction: This will go the distance.</strong></div>
<div class="zemanta-pixie" style="margin-top:10px;height:15px;"><strong>=============================<br />
</strong></div>
<div class="zemanta-pixie" style="margin-top:10px;height:15px;">(FROM BENNY PEISER&#8217;S EMAIL NEWSLETTER &#8211; ADDED 8/22/09)</div>
<div class="zemanta-pixie" style="margin-top:10px;height:15px;">EDITORIAL APOLOGY</p>
<p>I wish to apologise unequivocally to Mike Baillie  for allowing an ad hominem attack to be included in a CCNet posting on 19 August  2009. I value vigorous and open debate, even hard-nosed controversies. It is  essential for truth-finding in science. But I abhor personal attacks. This is  the first time that such an issue has arisen on CCNet in more than 12 years. I  will ensure that it won’t happen again as attacks on the integrity of CCNet  members and other individuals are totally inappropriate in an academic network.</p>
<p>Benny Peiser</p></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[TCP Model]]></title>
<link>http://networksinfo.wordpress.com/2009/08/03/tcp-model/</link>
<pubDate>Mon, 03 Aug 2009 15:35:15 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/03/tcp-model/</guid>
<description><![CDATA[The TCP/IP model has only four layers: . Application . Transport . Internet . Network interface]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The TCP/IP model has only four layers:<br />
. Application<br />
. Transport<br />
. Internet<br />
. Network interface</p>
<p><img src="http://img145.imageshack.us/img145/8774/tcp.jpg" alt="" /></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Packet Data Unit ( PDU )]]></title>
<link>http://networksinfo.wordpress.com/2009/08/03/packet-data-unit-pdu/</link>
<pubDate>Mon, 03 Aug 2009 15:30:49 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/03/packet-data-unit-pdu/</guid>
<description><![CDATA[We nee to understand the flow of information between two networked hosts. The OSI model describes th]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>We nee to understand the flow of information between two networked hosts. The OSI model describes the framework for this flow. As we move down the layers from application to physical, the data is encapsulated, which means that headers and trailers are added by each layer. The following section describes the process of creating a piece of data on one host and sending it to another host:</p>
<p>. At Layer 7, the user generates some data, perhaps an email message or a Word document. This data is passed down to Layer 6.</p>
<p>. At Layer 6, the data is formatted so that the same application on the other host can recognize and use it. The data is passed down to Layer 5.</p>
<p>. At Layer 5, the request to initiate a session for the transfer of the data is started. The data is passed down to Layer 4.</p>
<p>. At Layer 4, the data is encapsulated as either a TCP or UDP segment. The choice depends on what application generated the data. Source and destination port numbers are added, as are sequence and acknowledgment numbers and window size. The segment is passed down to Layer 3.</p>
<p>. At Layer 3, the segment is encapsulated with a Layer 3 header and becomes a packet. The packet header contains source and destination IP addresses and a label indicating what Layer 4 protocol it is carrying. The<br />
packet is passed down to Layer 2.</p>
<p>. At Layer 2, a header with source and destination MAC addresses is added. This encapsulation creates the frame. The trailer at this layer contains an error-checking calculation called the FCS (Frame Check<br />
Sequence). The frame header also contains a label indicating which Layer 3 protocol it is carrying (IP, IPX, and so on). The frame is sent to the interface for transmission onto the media (Layer 1).</p>
<p>. At Layer 1, the binary string that represents the frame is transmitted onto the media, whether electrically, optically, or by radio. Bits are transmitted across the media to the network interface of the other host.</p>
<p>. When received by the other host, the Layer 1 bits are sent up to Layer 2.</p>
<p>. At Layer 2, the destination MAC is examined to make sure that the frame was intended for this host. The FCS is calculated to check the frame for errors. If there are errors, the frame is discarded. If there are<br />
none, the frame is decapsulated and the packet is sent to the correct Layer 3 protocol based on the protocol ID in the header.</p>
<p>. At Layer 3, the destination IP address is checked to see if it is intended for this host. The packet header is checked to see which Layer 4 protocol to send it to. The packet is decapsulated, and the segment is sent up to Layer 4.</p>
<p>. At Layer 4, the destination port in the segment header is checked and the segment is decapsulated. The data is sent to the correct upper layer application. Depending on the application, it might go directly to Layer 7 or through 5 and 6.</p>
<p>This process of encapsulation, transmission, and decapsulation makes data flow in an organized and manageable fashion down the OSI stack on the sender, across the transmission media, and up the OSI stack on the receiving host. It is important to understand that layer 3 on the sender is communicating with layer 3 on the receiver as well by way of the information in the headers.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[TCP Sliding Window]]></title>
<link>http://networksinfo.wordpress.com/2009/08/03/tcp-sliding-window/</link>
<pubDate>Mon, 03 Aug 2009 15:12:03 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/03/tcp-sliding-window/</guid>
<description><![CDATA[The receiver has a method to tell the sender(s) to slow down the transmission rate. It’s called the ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The receiver has a method to tell the sender(s) to slow down the transmission rate. It’s called the sliding window. The window size indicates how many segments can be sent before an acknowledgment will be sent. If it is not busy, the receiver can handle a large number of segments and send a single acknowledgment. If it gets very busy, it can make the window size very small, allowing the sender(s) to send only a<br />
few segments before an acknowledgment is sent. The window size of the sender and receiver is included in the segment header and can change during the lifetime of the conversation.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[3 WayHandshack]]></title>
<link>http://networksinfo.wordpress.com/2009/08/03/3-wayhandshack/</link>
<pubDate>Mon, 03 Aug 2009 15:01:30 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/03/3-wayhandshack/</guid>
<description><![CDATA[When a host sends a segment of data, it is labeled with a sequence number that identifies that segme]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>When a host sends a segment of data, it is labeled with a sequence number that identifies that segment and<br />
where it belongs in the series of segments being sent. When the receiving host gets that segment, it sends an acknowledgment back to the sender with an acknowledgment number; the value of this number is the sequence number of the last segment it received, plus one. In effect, the receiver is saying, “I got your last<br />
one, now I am ready for the next one.”<br />
The first step in establishing a reliable connection between hosts is the three-way handshake. This initial signaling allows hosts to exchange their starting sequence numbers and to test that they have reliable communication between them.</p>
<p><img src="http://img150.imageshack.us/img150/8255/3wayc.jpg" alt="" /></p>
<p>From this point, the sender continues to send segments of data. A system known as PAR (Positive acknowledgment and Retransmission) makes sure that all the segments get where they are going. Following are the three main elements of PAR:</p>
<p>1. The sender starts a timer when it sends a segment, and will re-transmit that segment if the timer expires before an acknowledgment is received for that segment.</p>
<p>2. The sender keeps a record of all segments sent and expects an acknowledgment of each one.</p>
<p>3. The receiving device acknowledges the receipt of a segment by sending a segment back to the sender indicating the next sequence number it expects. If any of the segments of data should go missing—perhaps due to interference, collisions, or a link failure—the sender will not receive an acknowledgment of it<br />
and will retransmit it. The sequence number enables the receiver to put all the segments back in the correct order.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[OSI Model]]></title>
<link>http://networksinfo.wordpress.com/2009/08/03/osi-model/</link>
<pubDate>Mon, 03 Aug 2009 14:40:30 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/03/osi-model/</guid>
<description><![CDATA[Application: If you are using any program or utility that can astore, send, or retrieve data over a ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong><u>Application:</u></strong><br />
If you are using any program or utility that can astore, send, or retrieve data over a network, it is a Layer 7 application.Some application protocol: HTTP, FTP, SMTP, POP3, NTP, TFTP, DNS, DHCP &#38; Telnet.</p>
<p><strong><u>Presentation Layer:</u></strong><br />
The presentation layer is responsible for formatting data so that applicationlayer protocols (and then the users) can recognize and work with it.  The presentation layer does this formatting, taking the application layer data and marking it with the formatting codes so that it can be viewed reliably when accessed later.</p>
<p><strong><u>Session Layer:</u></strong><br />
The session layer deals with initiating and terminating network connections. It provides instructions to connect, authenticate (optionally), and disconnect from a network resource.</p>
<p><strong><u>Transport Layer:</u></strong><br />
The transport layer deals with exactly how two hosts are going to send data. The two main methods are called connection-oriented and connectionless . Connectionoriented transmission is said to be reliable, and connectionless is unreliable. Every network protocol stack will have a protocol that handles each style; in the TCP/IP stack, reliable transmission is done by TCP, and unreliable by UDP.</p>
<p><strong><u>Network Layer:</u></strong><br />
The network layer deals with logical addressing.  The last function of the network layer is to communicate with the layer above (transport) and the layer below (data link). This is achieved by attaching a header to the beginning of the segment that Layer 4 built. The addition of this header makes the segment into a packet. The packet header has a field that indicates the type of segment it is carrying—TCP or UDP, for example—so that the packet can be sent to the correct function at Layer 4. Communicating with Layer 2 in this case means that an IP packet can be sent to Layer 2 to become an Ethernet frame, Frame Relay, Point-to-Point Protocol, or almost any other Layer 2 technology.</p>
<p><strong><u>DataLink layer:</u></strong><br />
The data link layer is responsible for taking the Layer 3 packet (regardless of which protocol created it—IP, IPX, and so on) and preparing a frame for the packet to be transmitted on the media.</p>
<p><strong><u>Physical layer:</u></strong><br />
The physical layer defines the mechanical, procedural, and electrical standards for accessing the media so that you can transmit your Layer 2 frames.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Cisco Hierarchical Model]]></title>
<link>http://networksinfo.wordpress.com/2009/08/03/cisco-hierarchical-model/</link>
<pubDate>Mon, 03 Aug 2009 14:09:32 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/03/cisco-hierarchical-model/</guid>
<description><![CDATA[Cisco has created a reference model for the functions its equipment performs.The three-layer hierarc]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Cisco has created a reference model for the functions its equipment performs.The three-layer hierarchical model describes the major functional roles in any networkand provides a basis for understanding and troubleshooting scalable networks.</p>
<p>The three-layer hierarchical model are:</p>
<p><strong><span style="text-decoration:underline;"><span style="color:#ff0000;">Access Layer:</span></span></strong><br />
The access layer is the point that connects end users to the network. This can be achieved by a hub or switch to which PCs are connected, a wireless access point, a remote office connection, a dial-up service, or a VPN tunnel from the Internet into the corporate network.</p>
<p><span style="color:#ff0000;"><strong><span style="text-decoration:underline;">Distribution Layer:</span></strong><br />
</span>The distribution layer provides routing, packet filtering, WAN access, and QoS (Quality of Service).</p>
<p><span style="text-decoration:underline;">A. Routing:</span><br />
The access layer devices (usually switches) connect to a router or Layer 3 switch so that traffic can be routed to another network.</p>
<p><span style="text-decoration:underline;">B. Packet Filter:</span><br />
Packet filtering refers to the use of access control lists to identify certain types of traffic and control where it might go.</p>
<p><span style="text-decoration:underline;">C. QoS:</span><br />
If our network needs to use QoS features to make it run well, these features are typically first implemented<br />
at the distribution layer.</p>
<p><span style="text-decoration:underline;">D. Wan access</span><br />
Traditional WAN access usually involves a specialized interface—perhaps a serial port or ISDN Primary Rate Interface controller.</p>
<p><strong><span style="text-decoration:underline;"><span style="color:#ff0000;">Core layer:</span></span></strong><br />
The core does not usually do any routing or packet filtering, but it might do QoS if that is an important part of the network (if using Voice over IP [VoIP], for example).</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Wan Technologies]]></title>
<link>http://networksinfo.wordpress.com/2009/08/01/wan-technologies/</link>
<pubDate>Sat, 01 Aug 2009 13:45:56 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/01/wan-technologies/</guid>
<description><![CDATA[Deticated leased line connection: A leased line refers to a connection that is installed and provisi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong><u>Deticated leased line connection:</u></strong><br />
A leased line refers to a connection that is installed and provisioned for the exclusive use of the customer. Essentially, when you order a leased line, you get your very own piece of wire from your location to the service provider’s network. This is good because no other customer can affect your line, as can be the case with other WAN services. You have a lot of control over this circuit to do things such as Quality of Service and other traffic management. The downside is that a leased line is expensive and gets a lot more expensive if you need to connect offices that are far apart.</p>
<p><strong><u>Circuit switched:</u></strong><br />
A circuit-switched WAN uses the phone company as the service provider, either with analog dial-up or digital ISDN connections. With circuit-switching, if you need to connect to the remote LAN, a call is dialed and a circuit is established; the data is sent across the circuit, and the circuit is taken down when it is no longer needed. Circuit-switched WANs usually use PPP, HDLC, or SLIP, and they tend to be really slow—anywhere from 19.2K for analog dialup to 128K for ISDN using a Basic Rate Interface (BRI). They can also get expensive because most contracts specify a pay-per-usage billing.</p>
<p><strong><u>Packet Switch:</u></strong><br />
Packet-switched WAN services allow you to connect to the provider’s network in much the same way as a PC connects to a hub: When connected, your traffic is affected by other customers’ and theirs by you. This can be an issue sometimes, but it can be managed. The advantage of this shared-bandwidth technology<br />
is that with a single physical connection from your router’s serial port (typically), you can establish virtual connections to many other locations around the world. So if you have a lot of branch offices and they are far away from the head office, a packet-switched solution is a good idea. Packet-switched circuits usually<br />
use Frame Relay or possibly X.25.</p>
<p><strong><u>Cell Switched:</u></strong><br />
Cell switching is similar to packet switching; the difference is that with packetswitched networks, the size of the units of data being sent (called frames) is variable. Cell-switched units (cells) are of a constant size. This makes dealing with heavy traffic loads easier and more efficient.<br />
Cell-switched solutions such as Asynchronous Transfer Mode (ATM) tend to be big, fast, and robust.</p>
<p>- Cell-switched connections use fixed-length (53 bytes) packets to transmit information.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[CSMA/CD]]></title>
<link>http://networksinfo.wordpress.com/2009/08/01/csmacd/</link>
<pubDate>Sat, 01 Aug 2009 13:25:14 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/01/csmacd/</guid>
<description><![CDATA[Is the method Ethernet uses to deal with collisions. When a host wants to transmit, it first listens]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Is the method Ethernet uses to deal with collisions. When a host wants to transmit, it first listens to the wire to see if anyone else is transmitting at that moment. If it is clear, it can transmit; if not, it will wait 	for the host that is transmitting to stop. Sometimes, two hosts decide at the same instant that the wire is clear, and collide When this happens, the hosts that were involved with the with each other. collision send a special jam signal that advises everyone on that segment of the collision. Then all the hosts wait for a random period of time before they check the wire and try transmitting again. This wait time is tiny—a few millionths of a second—and is determined by the backoff algorithm. (The backoff algorithm is the mathematical equation a host runs to come up with the random number.) The theory is that if each host waits a different amount of time, the wire should be clear for all of them when they decide to transmit again. Any Ethernet segment that uses coaxial cable (10-BASE 2, 10-BASE 5) or a hub with twisted-pair cabling is a collision environment.</p>
<p><strong><u>Collision domain:</u></strong><br />
A group of devices that are affected by one another’s collisions is called a collision domain.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Topologies]]></title>
<link>http://networksinfo.wordpress.com/2009/08/01/topologies/</link>
<pubDate>Sat, 01 Aug 2009 13:16:10 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/01/topologies/</guid>
<description><![CDATA[Point-to-point: it&#8217;s involves two hosts or devices that are directly connected to each other a]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong><u>Point-to-point:</u></strong><br />
it&#8217;s involves two hosts or devices that are directly connected to each other and nothing else. Serial communication is usually point-to-point, but not always.</p>
<p><strong><u>Star:</u></strong><br />
A star topology is one in which one host or device has multiple connections to other hosts.<br />
If a host wants to send to another host, it must send traffic through the hub or central device.</p>
<p><strong><u>Ring:</u></strong><br />
A ring topology is created when one device is connected to the next one sequentially, with the last device being connected to the first. FDDI and Token Ring are examples of ring topologies.</p>
<p><strong><u>Bus:</u></strong><br />
A bus topology uses a single coaxial cable, to which hosts are attached at intervals. Ethernet that uses coaxial cable creates a bus topology.</p>
<p><strong><u>Mesh:</u></strong><br />
Is a topology with multiple point-to-point connections that connect each location to the others.<br />
The advantage is that you can send data directly from any location to any other location instead of having to send it through a central point.</p>
<p><strong><u>Ethernet:</u></strong><br />
The way Ethernet works is closely linked to its original connection type: A coaxial cable was used to join all the hosts together. This formed a segment. On a single segment, only one host could use the cable at a time; because the wire was coaxial, with one positive conductor and one negative conductor, it created a single electrical circuit. This single circuit could be energized by only one host at a time, or a conflict would result as two hosts tried to talk at once and nothing got through.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Components of the network]]></title>
<link>http://networksinfo.wordpress.com/2009/08/01/intro/</link>
<pubDate>Sat, 01 Aug 2009 13:08:18 +0000</pubDate>
<dc:creator>amiriraqi</dc:creator>
<guid>http://networksinfo.wordpress.com/2009/08/01/intro/</guid>
<description><![CDATA[Network: is a set of devices, software, and cables that enables the exchange of information between ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong><u>Network:</u></strong><br />
is a set of devices, software, and cables that enables the exchange of information 	between them.</p>
<p><strong><u>Host Devices:</u></strong><br />
Are computers, servers, laptops, PDAs or anything a person uses to access the network.</p>
<p><strong><u>Network Devices:</u></strong><br />
Are hubs, repeaters, bridges, switches, routers, and firewalls.</p>
<p><strong><u>Cables:</u></strong><br />
Can be copper, fiberoptic or even wireless radio.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[CCNet vs. CruiseControl]]></title>
<link>http://boathill.wordpress.com/2009/07/16/ccnet-vs-cruisecontrol/</link>
<pubDate>Thu, 16 Jul 2009 17:00:00 +0000</pubDate>
<dc:creator>Boathill</dc:creator>
<guid>http://boathill.wordpress.com/2009/07/16/ccnet-vs-cruisecontrol/</guid>
<description><![CDATA[Set once and let it go, this is how Continuous Integration works for automated build process along w]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><i>Set once and let it go, this is how <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/What+is+Continuous+Integration">Continuous Integration</a> works for automated build process along with development cycle. For a large number of projects, the maintenance for such continously integrated build environment could be complicate and cumbersome. This article will provide and discuss sample config files from practice experience to make easy using <a href="http://confluence.public.thoughtworks.org/display/CCNET/" target="_blog">CruiseControl.NET</a> and <a href="http://cruisecontrol.sourceforge.net/main/configxml.html" target="_blog">CruiseControl</a> with <a target="_blog" href="http://subversion.tigris.org/">subversion</a> repository. For comparison of all other similar products, see ThoughtWorks <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CC/CI+Feature+Matrix">CI Feature Matrix</a>.</i> </p>
<h4>Contents</h4>
<ul>
<li><a href="#ccnet">CruiseControl.NET</a> &#8211; [see <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/Documentation">online documentation</a>]</li>
<li><a href="#cruisecontrol">CruiseControl</a> &#8211; [see <a target="_blog" href="http://cruisecontrol.sourceforge.net/main/configxml.html">configuration reference</a>]</li>
<li><a href="#comparison">Comparison</a></li>
</ul>
<h4><a name="ccnet">CruiseControl.NET</a></h4>
<p>CCNET (<a href="http://confluence.public.thoughtworks.org/display/CCNET/" target="_blog">CruiseControl.NET</a>) starts with ccnet.config:</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--ccnet.config--&#62;
&#60;?xml version="1.0" encoding="utf-8" ?&#62;
&#60;!DOCTYPE cruisecontrol SYSTEM "file:ccnet_definitions.dtd"&#62;

&#60;cruisecontrol xmlns:cb="urn:ccnet.config.builder"&#62;
  &#60;cb:include href="ccnet_definitions.xml" xmlns:cb="urn:ccnet.config.builder"/&#62;

  &#60;queue name="$(computername)" duplicates="ApplyForceBuildsReAdd" /&#62;
  &#60;cb:include href="ccnet_Project.Standard_Solution.xml" xmlns:cb="urn:ccnet.config.builder"/&#62;

  &#60;cb:include href="ccnet_MyProject.xml" xmlns:cb="urn:ccnet.config.builder"/&#62;
&#60;/cruisecontrol&#62;
</pre>
<p>In order to maintain CCNET config and projects in clear XML code, the <code>ccnet.config</code> in above example takes advantage of CCNET powerful preprocessor features. There are three types of CCNET <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor">configuration preprocessors</a>: constant (including text/variable and nodeset XML fragment), nested expansion (defining a class whose instance can take parameters), and include file (<code>&#60;cb:include /&#62;</code>).</p>
<p>Including external config files helps putting constant/variable definitions, project definitions, and reusable XML pieces together in an organized structure, so that <code>ccnet.config</code> can be read in a from-top-to-down order while presenting high-level view in the main config. Another advanced use of include files is to allow editing definition or project file individually without touching ccnet.config. CCNET has the ability to notice any include file changed and reload ccnet.config automatically.</p>
<p>Like writing a program, the first thing in design is to define constants, variables, and reusable functions (or templates) that can be shared across the projects. These are all implemented by <code>&#60;cb:define /&#62;</code> in CCNET. Constants and XML fragments can be defined by <a target="_blog" href="http://xmlfiles.com/dtd/">DTD</a>, such as in <a target="_blog" href="http://www.w3.org/TR/xhtml1/dtds.html">XHTML DTDs</a> and following sample of <code>ccnet_definitions.dtd</code> included in <code>ccnet.config</code>.</p>
<pre class="brush:xhtml;first-line:0;" style="background-color:lavender;">
&#60;!--ccnet_definitions.dtd--&#62;
&#60;!ENTITY dir_ccnet &#34;$(ProgramFiles)\CruiseControl.NET&#34;&#62;
&#60;!ENTITY dir_ccnet_server &#34;$(ProgramFiles)\CruiseControl.NET\server&#34;&#62;
&#60;!ENTITY dir_ccnet_artifacts &#34;$(ProgramFiles)\CruiseControl.NET\server\projects&#34;&#62;
&#60;!ENTITY dir_svn &#34;$(ProgramFiles)\CollabNet Subversion Server&#34;&#62;
&#60;!ENTITY dir_svn_target &#34;\\10.0.1.100\svnbuilds&#34;&#62;
&#60;!ENTITY dir_dotnet &#34;$(SystemRoot)\Microsoft.NET\Framework\v3.5&#34;&#62;
&#60;!ENTITY dir_msvs &#34;$(ProgramFiles)\Microsoft Visual Studio 9.0&#34;&#62;

&#60;!ENTITY svn_server &#34;svn://192.168.0.100&#34;&#62;
&#60;!ENTITY auth_svn &#34;&#60;username&#62;svn_user&#60;/username&#62;&#60;password&#62;svn_password&#60;/password&#62;&#34; &#62;

&#60;!ENTITY exec_devenv &#34;&#60;executable&#62;&#38;dir_msvs;\Common7\IDE\devenv.com&#60;/executable&#62;&#34; &#62;
&#60;!ENTITY exec_nmake &#34;&#60;executable&#62;&#38;dir_msvs;\VC\bin\nmake.exe&#60;/executable&#62;&#34; &#62;
&#60;!ENTITY exec_msbuild &#34;&#60;executable&#62;&#38;dir_dotnet;\MSBuild.exe&#60;/executable&#62;&#34; &#62;
&#60;!ENTITY exec_svn &#34;&#60;executable&#62;&#38;dir_svn;\svn.exe&#60;/executable&#62;&#34; &#62;

&#60;!ENTITY url_ccnet &#34;http://localhost/ccnet&#34;&#62;
</pre>
<p>However, entity definition has its limitation in use (such as in string value of a property) and modifying a system file included by <code>&#60;!DOCTYPE &#62;</code> cannot trigger <code>ccnet.config</code> to reload. In CCNET, <code>&#60;cb:define /&#62;</code> is recommended to perform the same and even better job. The following sample illustrates syntax of defining text constant (variable) and nodeset (xml fragment). The third usage of <code>&#60;cb:define /&#62;</code>, nested expansion, is for reusable class that can take parameters by instance, such as defining a project template.</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--ccnet_definitions.xml--&#62;
&#60;cb:config-template xmlns:cb=&#34;urn:ccnet.config.builder&#34;&#62;
&#60;!--# Preprocessor: Text Constants --&#62;
  &#60;cb:define const_name=&#34;value&#34; /&#62; &#60;-- defines $(const_name), or &#60;cb:const_name/&#62; --&#62;
  &#60;cb:define dir_ccnet=&#34;$(ProgramFiles)\CruiseControl.NET&#34; /&#62;
  &#60;cb:define dir_ccnet_server=&#34;$(dir_ccnet)\server&#34; /&#62;
  &#60;cb:define dir_ccnet_artifacts=&#34;$(dir_ccnet_server)\projects&#34; /&#62;
  &#60;cb:define dir_ccnet_buildlogger=&#34;$(dir_ccnet)\server\ThoughtWorks.CruiseControl.MsBuild.dll&#34; /&#62;
  &#60;cb:define dir_dotnet=&#34;$(SystemRoot)\Microsoft.NET\Framework\v3.5&#34; /&#62;
  &#60;cb:define dir_svn=&#34;$(ProgramFiles)\CollabNet Subversion Server&#34; /&#62;
  &#60;cb:define dir_svn_source=&#34;c:\svn_checkout&#34; /&#62;
  &#60;cb:define dir_svn_builds=&#34;d:\svn_builds&#34; /&#62;
  &#60;cb:define dir_svn_target=&#34;\\10.0.1.100\svnbuilds&#34; /&#62;
  &#60;cb:define dir_system32=&#34;$(SystemRoot)\system32&#34; /&#62;
  &#60;cb:define dir_msvs=&#34;$(ProgramFiles)\Microsoft Visual Studio 9.0&#34; /&#62;

  &#60;cb:define svn_username=&#34;svn_username&#34; /&#62;
  &#60;cb:define svn_password=&#34;svn_password&#34; /&#62;

  &#60;cb:define url_svn_target=&#34;file://///10.0.1.100/svnbuilds&#34; /&#62;
  &#60;cb:define url_ccnet=&#34;http://localhost/ccnet&#34; /&#62;

&#60;!--# Preprocessor: Nodeset Constants --&#62;
  &#60;cb:define name=&#34;xml_default_extlink&#34;&#62;
    &#60;externalLink name=&#34;CCNET Builds [Ctrl+Click to open in Explorer]&#34; url=&#34;$(url_svn_target)&#34; /&#62;
  &#60;/cb:define&#62;
  &#60;cb:define name=&#34;xml_logger&#34;&#62;
    &#60;xmllogger logDir=&#34;$(dir_ccnet_server)\projects&#34; /&#62;
  &#60;/cb:define&#62;

  &#60;cb:define name=&#34;auth_svn&#34;&#62;
    &#60;username&#62;$(svn_username)&#60;/username&#62;
    &#60;password&#62;$(svn_password)&#60;/password&#62;
  &#60;/cb:define&#62;
  &#60;cb:define name=&#34;exec_devenv&#34;&#62;
    &#60;executable&#62;$(dir_msvs)\Common7\IDE\devenv.com&#60;/executable&#62;
  &#60;/cb:define&#62;
  &#60;cb:define name=&#34;exec_nmake&#34;&#62;
    &#60;executable&#62;$(dir_msvs)\VC\bin\nmake.exe&#60;/executable&#62;
  &#60;/cb:define&#62;
  &#60;cb:define name=&#34;exec_vcvars&#34;&#62;
    &#60;executable&#62;$(dir_msvs)\VC\vcvarsall.bat&#60;/executable&#62;
    &#60;baseDirectory&#62;$(dir_msvs)\VC&#60;/baseDirectory&#62;
    &#60;buildArgs&#62;x86&#60;/buildArgs&#62;
  &#60;/cb:define&#62;
  &#60;cb:define name=&#34;exec_msbuild&#34;&#62;
    &#60;executable&#62;$(dir_dotnet)\MSBuild.exe&#60;/executable&#62;
  &#60;/cb:define&#62;
  &#60;cb:define name=&#34;exec_svn&#34;&#62;
    &#60;executable&#62;$(dir_svn)\svn.exe&#60;/executable&#62;
  &#60;/cb:define&#62;

&#60;!--# Preprocessor: Nested Expansions (see other ccnet_*.xml)
  &#60;cb:define name=&#34;xml_element&#34;&#62;&#60;some_element property=&#34;$(var1)&#34; /&#62;&#60;more&#62;$(var2)&#60;/more&#62;&#60;/cb:define&#62;
  &#60;cb:xml_element var1=&#34;value1&#34; var2=&#34;value2&#34; /&#62;
--&#62;

&#60;/cb:config-template&#62;
</pre>
<p>The use of definitions in CCNET is easy to understand from above sample config file. First of all, any system environment variables can be referenced by <code>$(env_var)</code>, where <code>$(env_var)</code> is an environment variable accessible in CCNET runtime context. For example, if CCNET is started by <code>ccnet.exe</code> manually in a <i>Command Prompt</i> window, all system variables and logon user variables should be available; otherwise, if CCNET is started in <code>service.msc</code>, only system variables can be used. </p>
<p>Once a CCNET constant/variable (<code>&#60;cb:define <i>var_name</i>="text" /&#62;</code>) or XML fragment (<code>&#60;cb:define name="<i>element_name</i>" &#62;...&#60;/cb:define&#62;</code>) is defined, it can be referenced immediately afterward thru whole CCNET runtime environment. The constant/variable can be referenced as a string by <code>$(<i>var_name</i>)</code>, or <code>&#60;cb:<i>var_name</i> /&#62;</code>. The XML fragment must be referenced by <code>&#60;cb:<i>element</i> /&#62;</code>. All <code>&#60;cb:define /&#62;</code> are global definitions. To control the scope of a preprocessor definition, use <code>&#60;cb:scope /&#62;</code>. See <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor">configuration preprocessors</a>.</p>
<p>Next, let&#8217;s take a look at how to use CCNET nested expansions and parameters of preprocessor definition to create a project template. This template can be used to meet the following conditions:</p>
<ul>
<li>All project properties can be initiated by an instance of the template</li>
<li>There is only one build target path needed to be published</li>
<li>There is only one developer and who will be in notification for all build states</li>
<li>The project can be built by a MS Visual Studio 2008 solution file</li>
</ul>
<p>Similar to <code>ccnet_definitions.xml</code>, <code>ccnet_Project.Standard_Solution.xml</code> uses <code>&#60;cb:config-template /&#62;</code> but only defines one XML fragment named &#8220;<code>project_template_solution</code>&#8220;.</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--ccnet_Project.Standard_Solution.xml--&#62;
&#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&#62;
&#60;cb:config-template xmlns:cb=&#34;urn:ccnet.config.builder&#34;&#62;
&#60;cb:define name=&#34;project_template_solution&#34;&#62;
&#60;project name=&#34;$(project_name)&#34; queue=&#34;$(project_queue)&#34; queuePriority=&#34;0&#34;&#62;
  &#60;category&#62;$(project_category)&#60;/category&#62;
  &#60;workingDirectory&#62;$(dir_svn_source)\$(project_name)&#60;/workingDirectory&#62;
  &#60;artifactDirectory&#62;$(dir_ccnet_artifacts)\$(project_name)&#60;/artifactDirectory&#62;
  &#60;webURL&#62;$(url_ccnet)&#60;/webURL&#62;

  &#60;labeller type=&#34;svnRevisionLabeller&#34;&#62;
    &#60;prefix&#62;$(project_name)-r&#60;/prefix&#62;
    &#60;major&#62;0&#60;/major&#62;
    &#60;minor&#62;0&#60;/minor&#62;
    &#60;url&#62;svn://$(project_svnServer)$/(project_Root)$(project_Path)/$(project_Branch)&#60;/url&#62;
    &#60;cb:auth_svn /&#62;
  &#60;/labeller&#62;
  &#60;!--
  &#60;labeller type=&#34;lastChangeLabeller&#34;&#62;&#60;prefix&#62;$(project_name)-&#60;/prefix&#62;&#60;/labeller&#62;
  --&#62;
    &#60;triggers&#62;
    &#60;!--NOTE: build machine must sync clock with svn server!!!--&#62;
    &#60;intervalTrigger buildCondition=&#34;IfModificationExists&#34; seconds=&#34;$(project_checkTime)&#34; initialSeconds=&#34;60&#34; /&#62;
  &#60;/triggers&#62;
  &#60;sourcecontrol type=&#34;svn&#34;&#62;
    &#60;trunkUrl&#62;svn://$(project_svnServer)$/(project_Root)$(project_Path)/$(project_Branch)&#60;/trunkUrl&#62;
    &#60;cb:auth_svn /&#62;
    &#60;cb:exec_svn /&#62;
    &#60;workingDirectory&#62;$(dir_svn_source)\$(project_name)&#60;/workingDirectory&#62;
    &#60;timeout units=&#34;seconds&#34;&#62;$(project_checkTime)&#60;/timeout&#62;
  &#60;/sourcecontrol&#62;

  &#60;tasks&#62;
    &#60;msbuild&#62;
      &#60;cb:exec_msbuild /&#62;
      &#60;projectFile&#62;$(project_solution)&#60;/projectFile&#62;
      &#60;workingDirectory&#62;$(dir_svn_source)\$(project_name)&#60;/workingDirectory&#62;
      &#60;buildArgs&#62;/noconsolelogger /p:Configuration=Release&#60;/buildArgs&#62;
      &#60;logger&#62;$(dir_ccnet_buildlogger)&#60;/logger&#62;
    &#60;/msbuild&#62;
  &#60;/tasks&#62;

  &#60;publishers&#62;
    &#60;cb:xml_logger /&#62;

    &#60;buildpublisher&#62;
      &#60;sourceDir&#62;$(dir_svn_source)\$(project_name)\$(project_buildTarget)&#60;/sourceDir&#62;
      &#60;publishDir&#62;$(dir_svn_target)&#60;/publishDir&#62;
      &#60;useLabelSubDirectory&#62;true&#60;/useLabelSubDirectory&#62;
      &#60;alwaysPublish&#62;false&#60;/alwaysPublish&#62;
    &#60;/buildpublisher&#62;

    &#60;cb:include href=&#34;ccnet_email.xml&#34; xmlns:cb=&#34;urn:ccnet.config.builder&#34; /&#62;
    &#60;cb:ccnet_email
        developer_name=&#34;Developer&#34; developer_alias=&#34;$(project_developer)&#34;
        notification=&#34;Always&#34;
        /&#62;
  &#60;/publishers&#62;

&#60;/project&#62;
&#60;/cb:define&#62;

&#60;/cb:config-template&#62;
</pre>
<p>Different from <code>ccnet_definitions.xml</code>, <code>ccnet_Project.Standard_Solution.xml</code> also uses some variables that have never been defined, such as <code>$(project_name)</code>, <code>$(project_path)</code>, and etc., basically anything with &#8220;<code>project_</code>&#8221; prefix in this example. This is the exclusive feature of CCNET preprocessor that allow all these variable dynamically bound to an instance of the template when it is used. In <code>ccnet.config</code>, after <code>ccnet_Project.Standard_Solution.xml</code> is loaded, a project file <code>ccnet_MyProject.xml</code> comes after to initiate a project configuration based on the template. Here is code:</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--ccnet_MyProject.xml--&#62;
&#60;cb:config-template xmlns:cb=&#34;urn:ccnet.config.builder&#34;&#62;
&#60;cb:project_template_solution
    project_name=&#34;My Project&#34;
    project_alias=&#34;myproject&#34;
    project_category=&#34;My Category&#34;
    project_path=&#34;MyProject&#34;
    project_root=&#34;&#34;
    project_branch=&#34;trunk&#34;
    project_svnServer=&#34;192.168.10.100&#34;
    project_svnPath=&#34;svn://192.168.10.100/Software/MyProject/trunk&#34;
    project_solution=&#34;MyProject.sln&#34;
    project_buildTarget=&#34;Setup\Release&#34;
    project_buildTime=&#34;1800&#34;
    project_checkTime=&#34;600&#34;
    project_developer=&#34;myalias&#34;
    project_queue=&#34;$(computername)&#34;
/&#62;

&#60;/cb:config-template&#62;
</pre>
<p>The properties defined in &#8220;My Project&#8221; configuration makes the template used in complete. Actually, the property names after <code>cb:project_template_solution</code> may not be necessary matching what have been defined in the template. At least CCNET does not check if a referenced constant or variable is predefined. Undefined constant/variable will be replaced by empty string (- be caution that this could cause exception at the runtime). And any property defined in the instance but not used in the template will be ignored (e.g. <code>project_svnPath</code>).</p>
<p>CCNET preprocessor config template can be nested. Here is the file of <code>ccnet_email.xml</code> that has been included in <code>ccnet_Project.Standard_Solution.xml</code>:</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--ccnet_email.xml--&#62;
&#60;cb:config-template xmlns:cb=&#34;urn:ccnet.config.builder&#34;&#62;

  &#60;cb:define name=&#34;ccnet_email&#34;&#62;
    &#60;email from=&#34;Builder@mycompany.com&#34;
           mailhost=&#34;192.168.10.25&#34; includeDetails=&#34;TRUE&#34; useSSL=&#34;FALSE&#34;
           subjectPrefix=&#34;CCNET:&#34; description=&#34;CruiseControl.NET E-mail Notification &#34;&#62;
      &#60;users&#62;
        &#60;user name=&#34;Builder&#34; group=&#34;Builder&#34; address=&#34;builder@mycompany.com&#34;/&#62;
        &#60;user name=&#34;$(developer_name)&#34; group=&#34;Developer&#34; address=&#34;$(developer_alias)@mycompany.com&#34;/&#62;
        &#60;user name=&#34;Build Request&#34; group=&#34;Supervisor&#34; address=&#34;buildrequest@mycompany.com&#34;/&#62;
        &#60;user name=&#34;Admin&#34; group=&#34;Admin&#34; address=&#34;admin@mycompany.com&#34;/&#62;
      &#60;/users&#62;
      &#60;groups&#62;
        &#60;group name=&#34;Admin&#34; notification=&#34;Failed&#34;/&#62;
        &#60;group name=&#34;Builder&#34; notification=&#34;Success&#34;/&#62;
        &#60;group name=&#34;Developer&#34; notification=&#34;$(notification)&#34;/&#62;
      &#60;/groups&#62;

      &#60;modifierNotificationTypes&#62;
        &#60;NotificationType&#62;Always&#60;/NotificationType&#62;
        &#60;NotificationType&#62;Failed&#60;/NotificationType&#62;
        &#60;NotificationType&#62;Fixed&#60;/NotificationType&#62;
        &#60;NotificationType&#62;Success&#60;/NotificationType&#62;
        &#60;NotificationType&#62;Change&#60;/NotificationType&#62;
      &#60;/modifierNotificationTypes&#62;

      &#60;subjectSettings&#62;
        &#60;subject buildResult=&#34;Broken&#34; value=&#34;Build Failed - ${CCNetProject} - [Broken] :: ${CCNetBuildCondition}&#34; /&#62;
        &#60;subject buildResult=&#34;StillBroken&#34; value=&#34;Build Failed - ${CCNetProject} - [StillBroken] :: ${CCNetBuildCondition}&#34; /&#62;
        &#60;subject buildResult=&#34;Fixed&#34; value=&#34;Build Success - ${CCNetProject} - [Fixed] :: ${CCNetBuildCondition}&#34; /&#62;
        &#60;subject buildResult=&#34;Exception&#34; value=&#34;Build Failed - ${CCNetProject} - [Exception] :: ${CCNetBuildCondition}&#34; /&#62;
        &#60;subject buildResult=&#34;Success&#34; value=&#34;Build Success - ${CCNetProject} - [Success] :: ${CCNetBuildCondition}&#34; /&#62;
      &#60;/subjectSettings&#62;
    &#60;/email&#62;
  &#60;/cb:define&#62;

  &#60;!--# after &#60;cb:include href=&#34;ccnet_email.xml&#34; /&#62;, define following properties:
        developer_name  - developer name
        developer_alias - developer email alias
        notification    - notification type: Always&#124;Change&#124;Failed&#124;Success&#124;Fixed
  &#60;cb:ccnet_email
      developer_name=&#34;&#34;
      developer_alias=&#34;&#34;
      notfication=&#34;&#34;
    /&#62;
  ==--&#62;
&#60;/cb:config-template&#62;
</pre>
<p>For label variables used in <code>&#60;subjectSettings /&#62;</code>, please refer to CCNET <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/Email+Publisher">Email Publisher</a>.</p>
<p>The last thing left uncovered in the project template is &#8220;svnRevisionLabeller&#8221;. This is a modified plugin based on original <a target="_blog" href="http://code.google.com/p/svnrevisionlabeller/">svnrevisionlabeller</a>. The code (<b><code>SvnRevisonLabeller.cs</code></b>) is attached below:</p>
<pre class="brush:csharp;collapse:true;" style="background-color:lavender;">
/**
 ****************************************
 * Class Name:  SvnRevisionLabeller
 * Description: Subversion functions used in NAnt
 * Requisite:   Reference to NAnt.Core.dll
 * Notes:       See http://code.google.com/p/svnrevisionlabeller/
 ****************************************
 */
using System;
using System.Xml;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Core.Util;

namespace ccnet.SvnRevisionLabeller.plugin
{
 /// &#60;summary&#62;
 /// Generates label numbers using the Subversion revision number.
 /// &#60;/summary&#62;
 /// &#60;remarks&#62;
 /// This class was inspired by Jonathan Malek's post on his blog
 /// (&#60;a href=&#34;http://www.jonathanmalek.com/blog/CruiseControlNETAndSubversionRevisionNumbersUsingNAnt.aspx&#34;&#62;CruiseControl.NET and Subversion Revision Numbers using NAnt&#60;/a&#62;),
 /// which used NAnt together with Subversion to retrieve the latest revision number. This plug-in moves it up into
 /// CruiseControl.NET itself, so that you can see the latest revision number appearing in CCTray. The label can
 /// then be retrieved from within NAnt by accessing the property &#60;c&#62;${CCNetLabel}&#60;/c&#62;.
 /// &#60;/remarks&#62;
 [ReflectorType(&#34;svnRevisionLabeller&#34;)]
 public class SvnRevisionLabeller : ILabeller
 {
  #region Private members

  private int major;
  private int minor;
  private string _url;
  private string executable;
  private string prefix;
  private string username;
  private string password;
  private const string RevisionXPath = &#34;/log/logentry/@revision&#34;;

  #endregion

  #region Constructors

  /// &#60;summary&#62;
  /// Initializes a new instance of the &#60;see cref=&#34;SvnRevisionLabeller&#34;/&#62; class.
  /// &#60;/summary&#62;
  public SvnRevisionLabeller()
  {
   major = 1;
   minor = 0;
   executable = &#34;svn.exe&#34;;
   prefix = String.Empty;
  }

  #endregion

  #region Public methods

  /// &#60;summary&#62;
  /// Returns the label to use for the current build.
  /// &#60;/summary&#62;
  /// &#60;param name=&#34;resultFromLastBuild&#34;&#62;IntegrationResult from last build used to determine the next label&#60;/param&#62;
  /// &#60;returns&#62;the label for the new build&#60;/returns&#62;
  public string Generate(IIntegrationResult resultFromLastBuild)
  {
   // Get the last revision from the Subversion repository
   int svnRevision = GetRevision();

   // Get the last revision from CruiseControl
   Version version = ParseVersion(svnRevision, resultFromLastBuild);

   // If the revision number hasn't changed (because no new check-ins have been made), increment the build number;
   // Otherwise, reset the build number to 0
   int revision = (svnRevision == version.Build) ? version.Revision + 1 : 0;

   // Construct a new version number, adding any specified prefix
   Version newVersion = new Version(major, minor, svnRevision, revision);

            if (major == 0 &#38;&#38; minor == 0)
            {
                // &#60;major&#62;0&#60;/major&#62;&#60;minor&#62;0&#60;/minor&#62; must be explicitly defined
                // assume we only care about subversion revision - 2008-11-18 jzhu@zetron.com
                return prefix + svnRevision;
            }
            else // keep original usage for a 4-field version format
            {
                return prefix + newVersion;
            }
  }

  /// &#60;summary&#62;
  /// Runs the task, given the specified &#60;see cref=&#34;IIntegrationResult&#34;/&#62;, in the specified &#60;see cref=&#34;IProject&#34;/&#62;.
  /// &#60;/summary&#62;
  /// &#60;param name=&#34;result&#34;&#62;&#60;/param&#62;
  public void Run(IIntegrationResult result)
  {
   result.Label = Generate(result);
  }

  #endregion

  #region Public properties

  /// &#60;summary&#62;
  /// Gets or sets the major build number.
  /// &#60;/summary&#62;
  /// &#60;value&#62;The major build number.&#60;/value&#62;
  [ReflectorProperty(&#34;major&#34;, Required=false)]
  public int Major
  {
   get
   {
    return major;
   }
   set
   {
    major = value;
   }
  }

  /// &#60;summary&#62;
  /// Gets or sets the minor build number.
  /// &#60;/summary&#62;
  /// &#60;value&#62;The minor build number.&#60;/value&#62;
  [ReflectorProperty(&#34;minor&#34;, Required=false)]
  public int Minor
  {
   get
   {
    return minor;
   }
   set
   {
    minor = value;
   }
  }

  /// &#60;summary&#62;
  /// Gets or sets the repository URL from which the &#60;c&#62;svn log&#60;/c&#62; command will be run.
  /// &#60;/summary&#62;
  /// &#60;value&#62;The repository.&#60;/value&#62;
  [ReflectorProperty(&#34;url&#34;, Required = true)]
  public string Url
  {
   get
   {
    return _url;
   }
   set
   {
    _url = value;
   }
  }

  /// &#60;summary&#62;
  /// Gets or sets the Subversion client executable.
  /// &#60;/summary&#62;
  /// &#60;value&#62;The path to the executable.&#60;/value&#62;
  /// &#60;remarks&#62;
  /// If the value is not supplied, the task will expect to find &#60;c&#62;svn.exe&#60;/c&#62; in the &#60;c&#62;PATH&#60;/c&#62; environment variable.
  /// &#60;/remarks&#62;
  [ReflectorProperty(&#34;executable&#34;, Required=false)]
  public string Executable
  {
   get
   {
    return executable;
   }
   set
   {
    executable = value;
   }
  }

  /// &#60;summary&#62;
  /// Gets or sets an optional prefix for the build label.
  /// &#60;/summary&#62;
  /// &#60;value&#62;A string to prefix the version number with.&#60;/value&#62;
  [ReflectorProperty(&#34;prefix&#34;, Required=false)]
  public string Prefix
  {
   get
   {
    return prefix;
   }
   set
   {
    prefix = value;
   }
  }

  /// &#60;summary&#62;
  /// Gets or sets the username to access SVN repository.
  /// &#60;/summary&#62;
  /// &#60;value&#62;The repository.&#60;/value&#62;
  [ReflectorProperty(&#34;username&#34;, Required = false)]
  public string Username
  {
   get
   {
    return username;
   }
   set
   {
    username = value;
   }
  }

  /// &#60;summary&#62;
  /// Gets or sets the password to access SVN repository.
  /// &#60;/summary&#62;
  /// &#60;value&#62;The repository.&#60;/value&#62;
  [ReflectorProperty(&#34;password&#34;, Required = false)]
  public string Password
  {
   get
   {
    return password;
   }
   set
   {
    password = value;
   }
  }

  #endregion

  #region Private methods

  /// &#60;summary&#62;
  /// Parses the version.
  /// &#60;/summary&#62;
  /// &#60;param name=&#34;revision&#34;&#62;The revision.&#60;/param&#62;
  /// &#60;param name=&#34;resultFromLastBuild&#34;&#62;The result from last build.&#60;/param&#62;
  private Version ParseVersion(int revision, IIntegrationResult resultFromLastBuild)
  {
   try
   {
    string label = resultFromLastBuild.LastSuccessfulIntegrationLabel;
    if (prefix.Length &#62; 0)
    {
     label = label.Replace(prefix, String.Empty).TrimStart('_');
    }
    return new Version(label);
   }
   catch (SystemException)
   {
    return new Version(major, minor, revision, 0);
   }
  }

  /// &#60;summary&#62;
  /// Gets the latest Subversion revision by checking the last log entry.
  /// &#60;/summary&#62;
  private int GetRevision()
  {
   // Set up the command-line arguments required
   ProcessArgumentBuilder argBuilder = new ProcessArgumentBuilder();
   argBuilder.AppendArgument(&#34;log&#34;);
   argBuilder.AppendArgument(&#34;--xml&#34;);
   argBuilder.AppendArgument(&#34;--limit 1&#34;);
   argBuilder.AppendArgument(Url);
   if (Username != null &#38;&#38; Username.Length &#62; 0 &#38;&#38; Password != null &#38;&#38; Password.Length &#62; 0)
   {
    AppendCommonSwitches(argBuilder);
   }

   // Run the svn log command and capture the results
   ProcessResult result = RunProcess(argBuilder);
   Log.Debug(&#34;Received XML : &#34; + result.StandardOutput);

   // Load the results into an XML document
   XmlDocument xml = new XmlDocument();
   xml.LoadXml(result.StandardOutput);

   // Retrieve the revision number from the XML
   XmlNode node = xml.SelectSingleNode(RevisionXPath);
   return Convert.ToInt32(node.InnerText);
  }

  /// &#60;summary&#62;
  /// Appends the arguments required to authenticate against Subversion.
  /// &#60;/summary&#62;
  /// &#60;param name=&#34;buffer&#34;&#62;&#60;The argument builder./param&#62;
  private void AppendCommonSwitches(ProcessArgumentBuilder buffer)
  {
   buffer.AddArgument(&#34;--username&#34;, Username);
   buffer.AddArgument(&#34;--password&#34;, Password);
   buffer.AddArgument(&#34;--non-interactive&#34;);
   buffer.AddArgument(&#34;--no-auth-cache&#34;);
  }

  /// &#60;summary&#62;
  /// Runs the Subversion process using the specified arguments.
  /// &#60;/summary&#62;
  /// &#60;param name=&#34;arguments&#34;&#62;The Subversion client arguments.&#60;/param&#62;
  /// &#60;returns&#62;The results of running the process, including captured output.&#60;/returns&#62;
  private ProcessResult RunProcess(ProcessArgumentBuilder arguments)
  {
   ProcessInfo info = new ProcessInfo(executable, arguments.ToString(), null);
   Log.Debug(&#34;Running Subversion with arguments : &#34; + info.Arguments);

   ProcessExecutor executor = new ProcessExecutor();
   ProcessResult result = executor.Execute(info);
   return result;
  }
  #endregion
 }
}
</pre>
<h4><a name="cruisecontrol">CruiseControl</a></h4>
<p>Comparing to <a href="#ccnet">CCNET</a>, <a href="http://cruisecontrol.sourceforge.net/main/configxml.html" target="_blog">CruiseControl</a> does not provide very powerful preprocessor and template feature. There is no syntax to define XML fragment (except using DTD). The main config file, <code>config.xml</code>, cannot be automatically reloaded if any configuration changed. </p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--config.xml--&#62;
&#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&#62;
&#60;!--# Always deploy ccnet.config with following files under ${env.CCDIR}
                    config.properties
                    cc_antpublisher_copy.xml
                    prj_*.xml
      also place cruisecontrol.jar under &#34;${env.CCDIR}\lib&#34; to overwrite
      original one for a customized new plugin: &#60;ZSVNLabeller /&#62;
==--&#62;
&#60;cruisecontrol&#62;
  &#60;property file=&#34;config.properties&#34; /&#62;
  &#60;property environment=&#34;env&#34; toupper=&#34;true&#34; /&#62;
  &#60;property name=&#34;url_cruisecontrol&#34; value=&#34;${url_cchost}/cruisecontrol&#34; /&#62;
  &#60;property name=&#34;url_buildresults&#34; value=&#34;${url_cruisecontrol}/buildresults&#34; /&#62;
  &#60;property name=&#34;url_ccdashboard&#34; value=&#34;${url_cchost}/dashboard&#34; /&#62;
  &#60;property name=&#34;url_ccdoc&#34; value=&#34;${url_cchost}/documentation&#34; /&#62;

  &#60;include.projects file=&#34;prj_MyProject.xml&#34; /&#62;

&#60;/cruisecontrol&#62;
</pre>
<p>As in above sample of <code>config.xml</code>, property definition is either by <code>&#60;property name="var" value="text" /&#62;</code> element or an external file (e.g. <code>config.properties</code>).</p>
<pre class="brush:bash;first-line:1;" style="background-color:lavender;">
###############################################################################
# Filename: config.properties
#    Usage: called by cruisecontrol element, i.e.:
#           &#60;property file="config.properties" /&#62;
#   Syntax: defined by the class java.util.Properties, with the same rules
#           about how non-ISO8859-1 characters must be escaped.
###############################################################################

### default value predefinitions
def_hostip=10.0.1.194
def_hostname=hostname
def_project_buildTime=1800
def_project_checkTime=600

### dir/path predefinitions
dir_cruisecontrol=%ProgramFiles%\CruiseControl
dir_svn_target=\\10.0.1.100\svnbuilds
pwd_cruisecontrol=/srv/cruisecontrol-bin-2.8.2
smb_svn_target=/svnbuilds

### svn settings predefinitions
svn_server=svn://192.168.10.100
svn_username=svn_username
svn_password=svn_password

### user id predefinitions
uid_admin=admin
uid_builder=builder

### url predefinitions
url_cchost=http://hostname:8080
url_ccdashboard=http://hostname:8080/dashboard
url_ccdoc=http://hostname:8080/documentation
url_cruisecontrol=http://hostname:8080/cruisecontrol
url_buildresults=http://hostname:8080/cruisecontrol/buildresults
url_ccnet=http://localhost/ccnet
</pre>
<p>Certainly, a project file (e.g. <code>prj_MyProject.xml</code>) can be included in <code>config.xml</code> so that the configuration is well organized by each individual config file. Here only provides a project template file that a real project config (e.g. <code>prj_MyProject.xml</code>) will be based on.</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--prj_project.template.xml--&#62;
&#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&#62;
&#60;!--#
  For each project, use following steps to create a project file from this template by
  copying this file to a new project file, in convention of &#34;prj_$[project_name].xml&#34;:
  (1) replace &#34;$[project_name]&#34; with a project name
  (2) replace any place holder definition, like in format of $[place_holder], in property definitions
  (3) optionally use ${def_project_buildTime} for ${project_buildTime}
  (4) optionally add more ${project_buildTarget[n]} properties and publishers
  (5) choose one of the build methods in &#60;project&#62;&#60;schedule&#62;&#60;/schedule&#62;&#60;/project&#62; block
  (6) replace &#34;\\&#34; to &#34;/&#34; on Linux system
  (7) replace ${dir_svn_target} with ${smb_svn_target} on a Linux build system
  (8) define properties ${eid_*} for build notification; ${uid_builder} has been notified on success
  (9) refer to any property definitions in config.properties
==--&#62;
&#60;cruisecontrol&#62;
  &#60;project name=&#34;$[project_name]&#34;&#62;
    &#60;property name=&#34;project_name&#34;        value=&#34;${project.name}&#34; /&#62;
    &#60;property name=&#34;project_alias&#34;       value=&#34;$[project_alias]&#34; /&#62;
    &#60;property name=&#34;project_category&#34;    value=&#34;$[project_category]&#34; /&#62;
    &#60;property name=&#34;project_root&#34;        value=&#34;$[project_root]&#34; /&#62;
    &#60;property name=&#34;project_path&#34;        value=&#34;$[project_path]&#34; /&#62;
    &#60;property name=&#34;project_branch&#34;      value=&#34;$[project_branch]&#34; /&#62;
    &#60;property name=&#34;project_svnServer&#34;   value=&#34;$[project_svnServer]&#34; /&#62;
    &#60;property name=&#34;project_svnPath&#34;     value=&#34;svn://${project_svnServer}/${project_root}${project_path}/${project_branch}&#34; /&#62;
    &#60;property name=&#34;project_source&#34;      value=&#34;${env.CCDIR}\\projects\\${project.name}&#34; /&#62;
    &#60;property name=&#34;project_buildTarget&#34; value=&#34;$[project_buildTarget]&#34; /&#62;
    &#60;property name=&#34;project_buildTime&#34;   value=&#34;${def_project_buildTime}&#34; /&#62;
    &#60;property name=&#34;project_buildTime&#34;   value=&#34;$[project_buildTime]&#34; /&#62;
    &#60;property name=&#34;project_checkTime&#34;   value=&#34;30&#34; /&#62;
    &#60;property name=&#34;url_cruisecontrol&#34;   value=&#34;${url_cruisecontrol}&#34; /&#62;
    &#60;property name=&#34;eid_failure&#34;         value=&#34;builder&#34; /&#62;
    &#60;property name=&#34;eid_success&#34;         value=&#34;builder&#34; /&#62;
    &#60;property name=&#34;eid_always&#34;          value=&#34;developer_alias&#34; /&#62;

    &#60;plugin name=&#34;svn&#34; classname=&#34;net.sourceforge.cruisecontrol.sourcecontrols.SVN&#34; /&#62;
    &#60;plugin name=&#34;ZSVNLabeller&#34; classname=&#34;net.sourceforge.cruisecontrol.labelincrementers.ZSVNLabeller&#34; /&#62;

    &#60;ZSVNLabeller separator=&#34;r&#34; labelprefix=&#34;r&#34; workingcopypath=&#34;${project_source}&#34;
                  /&#62;
    &#60;!--#
    &#60;listeners&#62;
      &#60;currentbuildstatuslistener file=&#34;logs/${project.name}/status.txt&#34;/&#62;
    &#60;/listeners&#62;
    ==--&#62;
    &#60;bootstrappers&#62;
      &#60;!--#
      &#60;antbootstrapper anthome=&#34;apache-ant-1.7.0&#34;
                       buildfile=&#34;projects/${project.name}/build.xml&#34;
                       target=&#34;clean&#34; /&#62;
     &#60;execbootstrapper command=&#34;&#34;
                       args=&#34;&#34; workingdir=&#34;projects/${project.name}&#34;
                       errorstr=&#34;&#34; showProgress=&#34;&#34;
                       timeout=&#34;&#34;
                       /&#62;
      ==--&#62;
      &#60;svnbootstrapper localWorkingCopy=&#34;${project_source}&#34;
                       username=&#34;${svn_username}&#34;
                       password=&#34;${svn_password}&#34;
                       /&#62;
    &#60;/bootstrappers&#62;

    &#60;modificationset quietperiod=&#34;60&#34;&#62;
      &#60;!--# &#60;filesystem/&#62; triggers a build if any file in ${project.name} project is touched
      &#60;filesystem folder=&#34;${project_source}&#34; includedirectories=&#34;false&#34; /&#62;
      ==--&#62;
      &#60;!--# &#60;svn/&#62; sets property ${svnrevision}
      ==--&#62;
      &#60;svn localWorkingCopy=&#34;${project_source}&#34;
           useLocalRevision=&#34;false&#34;
           username=&#34;${svn_username}&#34;
           password=&#34;${svn_password}&#34;
           property=&#34;&#34;
         /&#62;
    &#60;/modificationset&#62;

    &#60;schedule interval=&#34;{project_checkTime}&#34;&#62;
      &#60;!--#&#60;ant /&#62;
      &#60;ant anthome=&#34;apache-ant-1.7.0&#34; buildfile=&#34;projects/${project.name}/build.xml&#34;/&#62;
      ==--&#62;
      &#60;!--#&#60;exec/&#62;
      ==--&#62;
      &#60;exec command=&#34;.\\build.cmd&#34;
            args='&#34;${project_source}&#34;' workingdir=&#34;${project_source}&#34;
            errorstr=&#34;Build Failed&#34; showProgress=&#34;true&#34;
            timeout=&#34;${project_buildTime}&#34;
            /&#62;
    &#60;/schedule&#62;

    &#60;log&#62;
      &#60;!--# merge from log files with specified pattern from specified dir
      &#60;merge dir=&#34;${project_source}\\log&#34; pattern=&#34;*.log&#34; /&#62;
      ==--&#62;
      &#60;deleteartifacts every=&#34;30&#34; unit=&#34;DAY&#34; /&#62;
      &#60;delete every=&#34;30&#34; unit=&#34;DAY&#34; /&#62;
    &#60;/log&#62;

    &#60;publishers&#62;
      &#60;htmlemail buildresultsurl=&#34;${url_cruisecontrol}/buildresults/${project_name}&#34;
                 defaultsuffix=&#34;.com&#34; mailhost=&#34;192.168.10.66&#34; mailport=&#34;25&#34; usessl=&#34;false&#34;
                 returnaddress=&#34;builder@mycompany.com&#34; returnname=&#34;Builder&#34;
                 subjectprefix=&#34;CruiseControl:&#34;
           &#62;
        &#60;success address=&#34;${uid_builder}@mycompany.com&#34; /&#62;&#60;!--send to builder success notification--&#62;
        &#60;success address=&#34;${eid_success}@mycompany.com&#34; /&#62;
        &#60;failure address=&#34;${eid_failure}@mycompany.com&#34; /&#62;
        &#60;always  address=&#34;${eid_always}@mycompany.com&#34;  /&#62;
      &#60;/htmlemail&#62;

      &#60;onsuccess&#62;
        &#60;antpublisher anthome=&#34;apache-ant-1.7.0&#34;
                      buildfile=&#34;${env.CCDIR}\\cc_antpublisher_copy.xml&#34;
                      target=&#34;publish_dir&#34;
                      &#62;
          &#60;property name=&#34;publish_source&#34; value=&#34;${project_source}\\${project_buildTarget}&#34; /&#62;
          &#60;property name=&#34;publish_target&#34; value=&#34;${dir_svn_target}\\${project_alias}&#34; /&#62;
        &#60;/antpublisher&#62;
        &#60;!--
        &#60;antpublisher anthome=&#34;apache-ant-1.7.0&#34;
                      buildfile=&#34;${env.CCDIR}\\cc_antpublisher_copy.xml&#34;
                      target=&#34;publish_file&#34;
                      &#62;
          &#60;property name=&#34;publish_source&#34; value=&#34;${project_source}\\${project_buildTarget}&#34; /&#62;
          &#60;property name=&#34;publish_target&#34; value=&#34;${dir_svn_target}\\${project_alias}&#34; /&#62;
        &#60;/antpublisher&#62;
        ==--&#62;
      &#60;/onsuccess&#62;
    &#60;/publishers&#62;

  &#60;/project&#62;

&#60;/cruisecontrol&#62;
</pre>
<p>The template cannot be used as nicely as in CCNET. But it gives a start for most projects. Please refer to usage comments at beginning of the template. Also remember since CruiseControl is running on both Windows and Linux systems, backslash or forward-slash need to be carefully used wherever a path is typed. </p>
<p>One of the difference in CruiseControl than CCNET is the sequence of continuous integration cycle. In CCNET, the <code>&#60;sourcecontrol /&#62;</code> compares last build state with repository server, then checkout (for the first time of check) or update source code on local working directory before starting build tasks. But in CruiseControl, the bootstrapper is always called at the beginning to update local working directory from server before using <code>&#60;modificationset /&#62;</code> to detect if tasks in <code>&#60;schedule /&#62;</code> need to be executed. </p>
<p>Such difference implies that the local working directory and source code in CruiseControl project must be manually checked out from the repository (such as <code>`svn co`</code>) at the time when the project is setup, which is not necessary in CCNET &#8211; where the local working directory can be created automatically if it does not exist. This also explains why <code>LocalWorkingCopy</code> (rather than <code>RepositoryLocation</code>) property should be used in <code>&#60;svn /&#62;</code> source control under <code>&#60;modificationset /&#62;</code> to detect new commit for a CruiseControl project. </p>
<p><b><u>Note</u></b>: There could be a chance that local working copy has not been updated yet when a new change is committed on repository server after <code>bootstrapper</code> but before <code>modificationset</code>. The race condition will end up building old source against a newer revision label. </p>
<p>Modification of subversion in CruiseControl is parsed from <code>`svn log -r`</code> by checking between last build time and current time. If <code>useLocalRevision</code> property is used in <code>&#60;svn /&#62;</code> source control, the local revision number will be in place of current time.</p>
<p>At the end of the template, artifacts publishing is implemented by the following include file.</p>
<pre class="brush:xml;first-line:0;" style="background-color:lavender;">
&#60;!--cc_antpublisher_coppy.xml--&#62;
&#60;project name=&#34;antpublisher_copy&#34; default=&#34;publish&#34;&#62;
    &#60;target name=&#34;publish&#34;&#62;
        &#60;echo&#62;Copying ${publish_source} to ${publish_target} ...&#60;/echo&#62;
        &#60;copy todir=&#34;${publish_target}&#34;&#62;&#60;fileset dir=&#34;${publish_source}&#34; /&#62;&#60;/copy&#62;
    &#60;/target&#62;
    &#60;target name=&#34;publish_dir&#34;&#62;
        &#60;echo&#62;Copying ${publish_source} to ${publish_target}-${label} ...&#60;/echo&#62;
        &#60;copy todir=&#34;${publish_target}-${label}&#34;&#62;&#60;fileset dir=&#34;${publish_source}&#34; /&#62;&#60;/copy&#62;
    &#60;/target&#62;
    &#60;target name=&#34;publish_file&#34;&#62;
        &#60;echo&#62;Copying ${publish_source} to ${publish_target}-${label} ...&#60;/echo&#62;
        &#60;copy todir=&#34;${publish_target}-${label}&#34; file=&#34;${publish_source}&#34;&#62;&#60;/copy&#62;
    &#60;/target&#62;
    &#60;target name=&#34;publish_artifacts&#34;&#62;
        &#60;echo&#62;Copying ${publish_source_dir} to ${publish_target} ...&#60;/echo&#62;
        &#60;copy todir=&#34;${publish_target}&#34;&#62;
   &#60;fileset dir=&#34;${publish_source_dir}&#34;&#62;
    &#60;include name=&#34;${publish_source_files}&#34; /&#62;
   &#60;/fileset&#62;
  &#60;/copy&#62;
    &#60;/target&#62;
&#60;/project&#62;
</pre>
<p>The Java source code of &#8220;<b>ZSVNLabeller</b>&#8221; plugin (based on <code>SVNLabelIncrementer</code>, implements <code>LabelIncrementer</code>) is attached as below. The file &#8220;<code>ZSVNLabeller.java</code>&#8221; should be place under source code folder &#8220;<code>net\sourceforge\cruisecontrol\labelincrementers</code>&#8220;. After rebuilt, copy &#8220;<code>cruisecontrol.jar</code>&#8221; to <code>${env.CCDIR}</code>, where CruiseControl installed.</p>
<pre class="brush:java;collapse:true;" style="background-color:lavender;">
package net.sourceforge.cruisecontrol.labelincrementers;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import net.sourceforge.cruisecontrol.LabelIncrementer;

import org.apache.log4j.Logger;
import org.jdom.Element;

/**
 * This class provides a label incrementation based on svn revision numbers.
 * This class expects the label format to be &#34;x&#38;lt;sep&#38;gt;y[&#38;lt;sep&#38;gt;z]&#34;,
 * where x is any String and y is an integer and &#38;lt;sep&#38;gt; a separator, the
 * last part z, is optional, and gets generated and later incremented in case a
 * build is forced. The default separator is &#34;.&#34; and can be modified using
 * {@link #setSeparator}.
 *
 * @author Ketan Padegaonkar &#38;lt; KetanPadegaonkar gmail &#38;gt;
 */

/// UPDATE: return revisionNumber if separator is as same as prefix - Boathill

public class ZSVNLabeller implements LabelIncrementer {
    private static final Logger LOG = Logger.getLogger(ZSVNLabeller.class);

    private String workingCopyPath = &#34;.&#34;;

    private String labelPrefix = &#34;svn&#34;;

    private String separator = &#34;.&#34;;

    public boolean isPreBuildIncrementer() {
        return true;
    }

    public String incrementLabel(String oldLabel, Element buildLog) {
        String revisionNumber = &#34;&#34;;
        String result = oldLabel;
        try {
            revisionNumber = getSvnRevision();

            if (getSeparator().equals(getLabelPrefix())) {
                return labelPrefix + revisionNumber; // return svn revison only
            }
            if (revisionNumber == null &#124;&#124; revisionNumber.equals(&#34;&#34;)) {
                return labelPrefix;
            }
            result = labelPrefix + getSeparator() + revisionNumber;

            if (oldLabel.indexOf(result) &#62; -1) {
                int lastSeparator = oldLabel.lastIndexOf(getSeparator());
                int firstSeparator = oldLabel.indexOf(getSeparator());
                int lastPart = 1;
                if (lastSeparator != firstSeparator) {
                    String suffix = oldLabel.substring(lastSeparator + 1);
                    lastPart = Integer.parseInt(suffix) + 1;
                }
                result += getSeparator() + lastPart;
            }
            LOG.debug(&#34;Incrementing label from &#34; + oldLabel + &#34; to &#34; + result);
        } catch (IOException e) {
            LOG.error(&#34;could not execute svn binary&#34;, e);
        } catch (NumberFormatException e) {
            LOG.error(&#34;could not increment label. Old label was &#34; + oldLabel + &#34;. svn revision was &#34; + revisionNumber,
                    e);
        }

        return result;
    }

    protected String getSvnRevision() throws IOException {
        String rev;
        Process p = null;
        try {
            p = Runtime.getRuntime().exec(new String[]{&#34;svnversion&#34;, workingCopyPath});
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
            rev = stdInput.readLine();
        } finally {
            if (p != null) {
                p.destroy();
            }
        }
        LOG.debug(&#34;SVN revision is: &#34; + rev);
        return rev;
    }

    public boolean isValidLabel(String label) {
        // we don't mind what the previous label is,
        // when the next label is built, then parsing is performed to add / increment a suffix.
        return true;
    }

    public void setWorkingCopyPath(String path) {
        LOG.debug(&#34;Working Path is: &#34; + path);
        workingCopyPath = path;
    }

    public String getLabelPrefix() {
        return this.labelPrefix;
    }

    public void setLabelPrefix(String labelPrefix) {
        this.labelPrefix = labelPrefix;
    }

    public String getDefaultLabel() {
        return getLabelPrefix() + getSeparator() + &#34;0&#34;;
    }

    public String getSeparator() {
        return this.separator;
    }

    public void setSeparator(String separator) {
        this.separator = separator;
    }
}
</pre>
<h4><a name="comparison">Comparison</a></h4>
<p>Some other Continuous Integration products, e.g. <a target="_blog" href="http://www.thoughtworks.com/cruise">Cruise</a> and <a target="_blog" href="https://hudson.dev.java.net/">Hudson</a>, have much nicer web interface, while <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/">CruiseControl.NET</a> and <a target="_blog" href="http://cruisecontrol.sourceforge.net/main/configxml.html">CruiseControl</a> provides better flexibility and can be greatly customized. However, the flexibility sometimes means difficulty. For example, CruiseControl has three web sites &#8211; dashboard (:8080), project cruisecontrol (:8000), and JMS console &#8211; but not be seen on one page; CruiseControl supports CCNET CCTray but could not integrate with CCNET projects or dashboard (even if both developed by <a target="_blog" href="http://opensource.thoughtworks.com/">ThoughtWorks</a>).</p>
<p>The build publisher supports using build label in both CCNET (by <code>&#60;labeller /&#62;</code>) and CruiseControl (<code>${label}</code> in <a target="_blog" href="http://ant.apache.org/manual/index.html">ant</a> config). And in CCNET, the build publisher has to copy all contents in a specified source to another location although <a target="_blog" href="http://ant.apache.org/manual/index.html">ant</a> or <a target="_blog" href="http://nant.sourceforge.net/">nant</a> can be used to customize such task. CruiseControl web interfaces do have a little more advanced features than CCNET. As an instance, the build target files (artifacts) can be published on CruiseControl dashboard so that can be downloaded. But the artifact in CCNET is just a local folder not accessible from the web. </p>
<p>On the other hand, CruiseControl does not display the runtime log on web interfaces. The build log can only be reviewed after the build is done. In CCNET dashboard, this is provided by a server log link. Although the server log in CCNET is not automatically updated (as nicely as a real time console display in Hudson), it at least gives user some hint before knowing the build succeeded or failed. Having better integration with Windows, CCNET can be run in either command line or service mode. For CruiseControl, you have to write a <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CC/RunningCruiseControlFromUnixInit"><code>/etc/init.d/cruisecontrol</code></a>.</p>
<p>Since <a target="_blog" href="http://confluence.public.thoughtworks.org/display/CCNET/">CruiseControl.NET</a> derived from <a target="_blog" href="http://cruisecontrol.sourceforge.net/main/configxml.html">CruiseControl</a>, both work the same way and the cofiguration shares similarity. As open source projects, it is convenient to develop or modify plugin to suite need during implementation. CruiseControl is cross-platform by Java technology. CCNET has improved on web integration and preprocessor configuration so that project file can be well structured via nodeset expansion template.</p>
<p><b><u>Note</u></b>: Source code samples are formatted by <a target="_blog" href="http://alexgorbatchev.com/wiki/SyntaxHighlighter">SyntaxHighlighter</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Component Building Flow]]></title>
<link>http://mfathur.wordpress.com/2009/07/10/component-building-flow/</link>
<pubDate>Fri, 10 Jul 2009 09:43:09 +0000</pubDate>
<dc:creator>mfathur</dc:creator>
<guid>http://mfathur.wordpress.com/2009/07/10/component-building-flow/</guid>
<description><![CDATA[Ada puluhan project, ribuan file. Sama dengan sebuah mobil dengan ribuan komponen. Dalam software de]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img class="alignnone size-full wp-image-76" title="ComBuildFlow" src="http://mfathur.wordpress.com/files/2009/07/combuildflow.gif" alt="ComBuildFlow" width="450" height="349" /></p>
<p>Ada puluhan project, ribuan file. Sama dengan sebuah mobil dengan ribuan komponen.</p>
<p>Dalam software development, segala sesuatunya menjadi lebih ribet. Apalagi dalam lingkungan yang koplingnya lepas. Lebih lengkap lagi deritanya, kita harus maintain ribuan library, yang masing2 punya versinya sendiri.</p>
<p>Berdasarkan tulisan <a href="http://www.martinfowler.com/articles/continuousIntegration.html">Martin Fowler</a> building saya bagi menjadi 3 tahap.</p>
<p>Tahap pertama, building dalam lingkungan CCNet. CCNet akan ngebuild dan dimasukkan kedalam folder build internal dia. Untuk ngebuild project berikutnya yang membutuhkan library dari hasil build project yang lain, CCNet akan menugaskan NAnt untuk mengambil dari folder build dan dimasukkan ke external-lib.</p>
<p>Tahap kedua, jika tahap pertama sukses, CCNet akan menugaskan NAnt untuk mengkopi hasil build&#8211;semuanya, ke <strong>folder build yang tershare</strong> untuk semua developer. Semua developer harus mengupdate library dia setiap kali run build project.</p>
<p>Tahap ketiga, secara manual, kita bisa meminta CCNet untuk build semua project dan dimasukkan ke folder build 3. Ditujukan untuk end-to-end testing. Bisa mungkin memanfaatkan Fit.</p>
<p>Tahap 1 dan 2 membutuhkan NAnt file build yang sama. Karena source eksternal buildnya berbeda&#8211;beda lokasi, mau tidak mau kita harus membuat satu property &#8220;Eksternal-lib-Source&#8221;. Alamat dari setiap folder berbeda untuk tiap komputer, jadi tidak perlu dikomit.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[MSBuild: Custom Task MetaData]]></title>
<link>http://davidphenry.wordpress.com/2009/03/25/msbuild-custom-task-metadata/</link>
<pubDate>Thu, 26 Mar 2009 02:10:44 +0000</pubDate>
<dc:creator>davidphenry</dc:creator>
<guid>http://davidphenry.wordpress.com/2009/03/25/msbuild-custom-task-metadata/</guid>
<description><![CDATA[Been working with CruiseControl.Net to connect to our CMSynergy source control for some continous in]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Been working with CruiseControl.Net to connect to our CMSynergy source control for some continous integration goodness. While configuring CCNet, I&#8217;ve had the oppurtunity to spend some more time with MSBuild - which always makes for some interesting times.</p>
<p>I plan on posting more info once this round is over, but I wanted to make a note about custom tasks from MSBuild. The setup for this, is that I am using a custom task to parse some input files based  on how the release is being defined &#8211; and then output the files that should be included in the final install package. Without going too much further into detail, the intial condition was that if this is a .0 release, all files are returned.<br />
The task xml looked like:<br />
&#60;CustomTask SourceFiles=&#8221;@(SourceFiles)&#8221; Release=&#8221;$(ReleaseCondition)&#8221;&#62;<br />
&#60;OutPut TaskParameter=&#8221;PublishFiles&#8221;  ItemName=&#8221;OutFiles&#8221;/&#62;<br />
&#60;/CustomTask&#62;</p>
<p>The interesting bit to note here, was that just setting the output property to the input property (PublishFiles = SourceFiles) &#8211; ended up with the MetaData RecursiveDir on PublishFiles being reset  once the output was set to a new variable OutFiles. To get around this, I ended up setting a new custom metadata on the PublishFiles property that copies the RecursiveDir property from SourceFiles.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Kyoto and Sons of Kyoto: A Few Months Then The Truth]]></title>
<link>http://omniclimate.wordpress.com/2009/02/16/kyoto-and-sons-of-kyoto-a-few-months-then-the-truth/</link>
<pubDate>Mon, 16 Feb 2009 13:21:46 +0000</pubDate>
<dc:creator>omnologos</dc:creator>
<guid>http://omniclimate.wordpress.com/2009/02/16/kyoto-and-sons-of-kyoto-a-few-months-then-the-truth/</guid>
<description><![CDATA[The text below has been published today on Benny Peiser&#8217;s CCNet. The original author is Col. G]]></description>
<content:encoded><![CDATA[The text below has been published today on Benny Peiser&#8217;s CCNet. The original author is Col. G]]></content:encoded>
</item>
<item>
<title><![CDATA[Deja vu Avec Nant &amp; Continous Integration]]></title>
<link>http://shaunakpandit.wordpress.com/2008/10/02/deja-vu-avec-nant-continous-integration-shaunak-pandit/</link>
<pubDate>Thu, 02 Oct 2008 06:52:35 +0000</pubDate>
<dc:creator>Shaunak Pandit</dc:creator>
<guid>http://shaunakpandit.wordpress.com/2008/10/02/deja-vu-avec-nant-continous-integration-shaunak-pandit/</guid>
<description><![CDATA[Got lucky to try my hand at Continous integration once again.. I remember it has been like more than]]></description>
<content:encoded><![CDATA[Got lucky to try my hand at Continous integration once again.. I remember it has been like more than]]></content:encoded>
</item>
<item>
<title><![CDATA[We won!]]></title>
<link>http://hyperthunk.wordpress.com/2008/09/25/we-won/</link>
<pubDate>Thu, 25 Sep 2008 13:40:47 +0000</pubDate>
<dc:creator>loggerheadz</dc:creator>
<guid>http://hyperthunk.wordpress.com/2008/09/25/we-won/</guid>
<description><![CDATA[We won an award from CNET this week. Here&#8217;s the list of winners. Pictures to follow!]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a title="Web21C" href="http://web21c.bt.com/" target="_blank">We</a> won an award from CNET this week. <a title="CCNET Awards 2008 - winners" href="http://www.onlineawards.co.uk/cnetawards2008/2008winners.asp" target="_blank">Here&#8217;s</a> the list of winners. Pictures to follow!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Update! CruiseControl.net Advanced Metrics - RC1 1.4 Build]]></title>
<link>http://team.pushbomb.com/2008/06/19/open-source-project-updated-cruise-controlnet-advanced-metrics/</link>
<pubDate>Thu, 19 Jun 2008 16:25:11 +0000</pubDate>
<dc:creator>Damon Wilder Carr</dc:creator>
<guid>http://team.pushbomb.com/2008/06/19/open-source-project-updated-cruise-controlnet-advanced-metrics/</guid>
<description><![CDATA[We finally had time to perform some much needed upgrades to the code base for the qualitative and qu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>We finally had time to perform some much needed upgrades to the code base for the qualitative and quantitative metrics produced by our addin to CruiseControl.net continuous integration system</p>
<p>Anyway here&#8217;s an idea of how the framework API is shaping up. Expect this to move dramatically toward&#8217;s Fowler&#8217;s fantastic coverage of <a href="http://www.martinfowler.com/dslwip/ExpressionBuilder.html">&#8216;Expression Builder&#8217;</a>.</p>
<p><a href="http://www.ayende.com/projects/rhino-mocks/downloads.aspx"><img class="size-full wp-image-274 alignleft" style="margin:0 20px 0 0;" src="http://dcarr.wordpress.com/files/2008/06/rhinomocks-120x90.png" alt="dont mock around" width="104" height="78" /></a></p>
<p>We hope that this will evolve into a full Linq provider, and due to the XML foundation this is not all that unrealistic a goal.<br />
 </p>
<p> </p>
<p> </p>
<pre><span style="background:black;color:#bbfdcc;">namespace </span><span style="background:black;color:#ffffff;">CCStatisticsTDD
{
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">System;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">System.Collections.Generic;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">System.Linq;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">CCStatistics.Domain.Api;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">CCStatistics.Domain.Api.Interfaces;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">NUnit.Framework;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">Rhino.Mocks;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">TDDViewOutputStatus;
    </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">ThoughtWorks.CruiseControl.Core;

    </span><span style="background:black;color:#808080;">/// &#60;summary&#62;
    /// </span><span style="background:black;color:#008000;">This is a monolitic 'Smoke Test'. There are many fine grained tests to be writtem!
    </span><span style="background:black;color:#808080;">/// &#60;/summary&#62;
    </span><span style="background:black;color:#ffffff;">[</span><span style="background:black;color:#2b91af;">TestFixture</span><span style="background:black;color:#ffffff;">]
    </span><span style="background:black;color:#bbfdcc;">public class </span><span style="background:black;color:#2b91af;">MainTestFixtureBaselineSmokes </span><span style="background:black;color:#ffffff;">: </span><span style="background:black;color:#2b91af;">TestBase
    </span><span style="background:black;color:#ffffff;">{
        </span><span style="background:black;color:#808080;">/// &#60;summary&#62;
        /// </span><span style="background:black;color:#008000;">Gets the mock list.
        </span><span style="background:black;color:#808080;">/// &#60;/summary&#62;
        /// &#60;param name="mockBuildName"&#62;</span><span style="background:black;color:#008000;">Name of the mock build.</span><span style="background:black;color:#808080;">&#60;/param&#62;
        /// &#60;param name="repositoryBuildCount"&#62;</span><span style="background:black;color:#008000;">The repository build count.</span><span style="background:black;color:#808080;">&#60;/param&#62;
        /// &#60;returns&#62;&#60;/returns&#62;
        /// </span><span style="background:black;color:#008000;">Documentation Created 6/23/2008
        </span><span style="background:black;color:#bbfdcc;">private static </span><span style="background:black;color:#2b91af;">List</span><span style="background:black;color:#ffffff;">&#60;</span><span style="background:black;color:#bbfdcc;">string</span><span style="background:black;color:#ffffff;">&#62; GetMockList(</span><span style="background:black;color:#bbfdcc;">string </span><span style="background:black;color:#ffffff;">mockBuildName, </span><span style="background:black;color:#bbfdcc;">int </span><span style="background:black;color:#ffffff;">repositoryBuildCount)
        {
            </span><span style="background:black;color:#008000;">// Add the build name to the array tht is expected to be available for ALL builds
            // from the repositoy. Here we use 10

            </span><span style="background:black;color:#bbfdcc;">return
                </span><span style="background:black;color:#2b91af;">Enumerable</span><span style="background:black;color:#ffffff;">.Repeat(mockBuildName + </span><span style="background:black;color:#a31515;">" {0}"</span><span style="background:black;color:#ffffff;">, repositoryBuildCount).Select(
                    s =&#62; </span><span style="background:black;color:#2b91af;">String</span><span style="background:black;color:#ffffff;">.Format(s, </span><span style="background:black;color:#2b91af;">DateTime</span><span style="background:black;color:#ffffff;">.Now.TimeOfDay.TotalMilliseconds/1000)).ToList();
        }

        </span><span style="background:black;color:#bbfdcc;">protected override </span><span style="background:black;color:#2b91af;">ICCStatsProject </span><span style="background:black;color:#ffffff;">Prepare()
        {
            </span><span style="background:black;color:#008000;">// We need a name for this project
            </span><span style="background:black;color:#bbfdcc;">const </span><span style="background:black;color:#2b91af;">String </span><span style="background:black;color:#ffffff;">mockBuildName = </span><span style="background:black;color:#a31515;">"CCStatisticsBuildMock"</span><span style="background:black;color:#ffffff;">;

            </span><span style="background:black;color:#008000;">// Simulate 100 legacy build results
            </span><span style="background:black;color:#bbfdcc;">const int </span><span style="background:black;color:#ffffff;">repositoryBuildCount = 100;

            </span><span style="background:black;color:#bbfdcc;">var </span><span style="background:black;color:#ffffff;">repository = mocks.Stub&#60;</span><span style="background:black;color:#2b91af;">IIntegrationRepository</span><span style="background:black;color:#ffffff;">&#62;();
            </span><span style="background:black;color:#bbfdcc;">var </span><span style="background:black;color:#ffffff;">buildNames = GetMockList(mockBuildName, repositoryBuildCount);

            </span><span style="background:black;color:#008000;">// OK set this up to return our builds
            </span><span style="background:black;color:#ffffff;">repository.Stub(x =&#62; x.GetBuildNames()).Return(buildNames.ToArray());

            </span><span style="background:black;color:#bbfdcc;">var </span><span style="background:black;color:#ffffff;">currentProject = mocks.Stub&#60;</span><span style="background:black;color:#2b91af;">ICCStatsProject</span><span style="background:black;color:#ffffff;">&#62;();

            currentProject.Stub(x =&#62; x.IntegrationRepository).Return(repository);
            currentProject.Stub(x =&#62; x.StatisticsForPublisher).Return(MockStats);

            currentProject.StubEx(x =&#62; x.Name, mockBuildName).
                StubEx(x =&#62; x.BuildLogDirectory, DefaultDirectory).
                StubEx(x =&#62; x.ArtifactDirectory, DefaultDirectory).
                StubEx(x =&#62; x.WorkingDirectory, DefaultDirectory).
                Stub(x =&#62; x.StatsPostPublisher).Return(InitializePublisher(currentProject));

            </span><span style="background:black;color:#bbfdcc;">return </span><span style="background:black;color:#ffffff;">currentProject;
        }

        </span><span style="background:black;color:#bbfdcc;">private </span><span style="background:black;color:#2b91af;">IMetricPublisher </span><span style="background:black;color:#ffffff;">InitializePublisher(</span><span style="background:black;color:#2b91af;">ICCStatsProject </span><span style="background:black;color:#ffffff;">project)
        {
            </span><span style="background:black;color:#008000;">// OK now it's interesting.. We have our own IMetricPublisher which is a stand-in for the
            // StattisticsPublisher concrete class in CruiseControl. We need to add a new overload
            // and obviously make this behave in ways it was not intended to (as we are doing all the legacy builds)
            </span><span style="background:black;color:#bbfdcc;">var </span><span style="background:black;color:#ffffff;">_statisticsPublisher = mocks.Stub&#60;</span><span style="background:black;color:#2b91af;">IMetricPublisher</span><span style="background:black;color:#ffffff;">&#62;();

            </span><span style="background:black;color:#008000;">// Here we use the mock array of stats created above. This is a duplicate of StatisticsForPublisher
            // Need to look into consolodating that.
            </span><span style="background:black;color:#ffffff;">_statisticsPublisher.Stub(x =&#62; x.ConfiguredStatistics).Return(MockStats);

            </span><span style="background:black;color:#008000;">// Core Validation is Below
            </span><span style="background:black;color:#ffffff;">_statisticsPublisher.Expect(x =&#62; x.ProcesLogFile(project.Name)).
                IgnoreArguments().Repeat.Times(project.BuildCount);

            </span><span style="background:black;color:#bbfdcc;">return </span><span style="background:black;color:#ffffff;">_statisticsPublisher;
        }

        </span><span style="background:black;color:#808080;">/// &#60;summary&#62;
        /// </span><span style="background:black;color:#008000;">NOTE: This is a FULL CYCLE Mock Smoke test. We need many more finely grained
        </span><span style="background:black;color:#808080;">/// </span><span style="background:black;color:#008000;">tests. This is just to ensure all is well in the application. Each subcomponent
        </span><span style="background:black;color:#808080;">/// </span><span style="background:black;color:#008000;">will need to have tests added as this evolves. In the mean time this works
        </span><span style="background:black;color:#808080;">/// </span><span style="background:black;color:#008000;">well to ensure we fundamentally work and this is called from OUR BuildServer
        </span><span style="background:black;color:#808080;">/// </span><span style="background:black;color:#008000;">(how META is that?) to ensure this is working.
        </span><span style="background:black;color:#808080;">/// </span><span style="background:black;color:#008000;">This should be your first stop to undersand this code
        </span><span style="background:black;color:#808080;">/// &#60;/summary&#62;
        </span><span style="background:black;color:#ffffff;">[</span><span style="background:black;color:#2b91af;">Test</span><span style="background:black;color:#ffffff;">]
        </span><span style="background:black;color:#bbfdcc;">public void </span><span style="background:black;color:#ffffff;">ShouldSmokeTestProjectAPI()
        {
            </span><span style="background:black;color:#bbfdcc;">using </span><span style="background:black;color:#ffffff;">(mocks.Record())
                </span><span style="background:black;color:#2b91af;">Assert</span><span style="background:black;color:#ffffff;">.IsTrue(</span><span style="background:black;color:#2b91af;">ForStatistics</span><span style="background:black;color:#ffffff;">.RefreshValues(</span><span style="background:black;color:#2b91af;">MockTDDView</span><span style="background:black;color:#ffffff;">.New, Prepare()));
        }
    }

    </span><span style="background:black;color:#bbfdcc;">public static class </span><span style="background:black;color:#2b91af;">MockExtensions
    </span><span style="background:black;color:#ffffff;">{
        </span><span style="background:black;color:#808080;">/// &#60;summary&#62;
        /// </span><span style="background:black;color:#008000;">Stubs the type defined
        </span><span style="background:black;color:#808080;">/// &#60;/summary&#62;
        /// &#60;typeparam name="TType"&#62;</span><span style="background:black;color:#008000;">The type of the type.</span><span style="background:black;color:#808080;">&#60;/typeparam&#62;
        /// &#60;param name="currentProject"&#62;</span><span style="background:black;color:#008000;">The current project.</span><span style="background:black;color:#808080;">&#60;/param&#62;
        /// &#60;param name="funcMock"&#62;</span><span style="background:black;color:#008000;">The func mock.</span><span style="background:black;color:#808080;">&#60;/param&#62;
        /// &#60;param name="returnString"&#62;</span><span style="background:black;color:#008000;">The return string.</span><span style="background:black;color:#808080;">&#60;/param&#62;
        /// &#60;returns&#62;&#60;/returns&#62;
        /// </span><span style="background:black;color:#008000;">Documentation Created 6/20/2008
        </span><span style="background:black;color:#bbfdcc;">public static </span><span style="background:black;color:#ffffff;">TType StubEx&#60;TType&#62;(</span><span style="background:black;color:#bbfdcc;">this </span><span style="background:black;color:#ffffff;">TType currentProject, </span><span style="background:black;color:#2b91af;">Func</span><span style="background:black;color:#ffffff;">&#60;TType, </span><span style="background:black;color:#2b91af;">String</span><span style="background:black;color:#ffffff;">&#62; funcMock,
                                          </span><span style="background:black;color:#2b91af;">String </span><span style="background:black;color:#ffffff;">returnString)
            </span><span style="background:black;color:#bbfdcc;">where </span><span style="background:black;color:#ffffff;">TType : </span><span style="background:black;color:#bbfdcc;">class</span><span style="background:black;color:#ffffff;">, </span><span style="background:black;color:#2b91af;">ICCStatsProject
        </span><span style="background:black;color:#ffffff;">{
            currentProject.Expect(funcMock).Return(returnString).Repeat.Any();
            </span><span style="background:black;color:#bbfdcc;">return </span><span style="background:black;color:#ffffff;">currentProject;
        }
    }
}</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[CruiseControl.Net Tutorial - Part 2]]></title>
<link>http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/</link>
<pubDate>Sun, 15 Jun 2008 22:14:53 +0000</pubDate>
<dc:creator>ilmatte</dc:creator>
<guid>http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/</guid>
<description><![CDATA[1. Introduction (part 1) 2. Resources (part 1) 3. Installation (part 1) 3.1. Install CruiseControl.N]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a title="ccnettut2top" name="ccnettut2top"></a><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutintro">1. Introduction (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutresources">2. Resources (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutinstallation">3. Installation (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutinstallccnet">3.1. Install CruiseControl.NET (part 1)</a></span></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutiiscreatesite">3.2. Create a CCNet Website in IIS (part 1)</a></span></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutinstallnunit">3.3. Install Nunit (part 1)</a></span></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutconfiguration">4. CruiseControl.NET Server Configuration &#8211; General (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutprojectconfiguration">5. Structure of a &#8216;Project&#8217; Configuration File (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutsourcecontrolblock">6. Source Control Block (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettuttriggerblock">7. Trigger Block (part 1)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutlabellerblock">8. Labeller Block (part 1)</a></span><br />
<a href="#ccnettuttasksblock">9. Tasks Block</a><br />
<a href="#ccnettutmsbuildtask">10. MsBuild Task</a><br />
<span style="position:relative;left:10px;"><a href="#ccnettutreferencepath">10.1. MSBuild and ReferencePath &#8211; CruiseControl.NET not resolving reference to Nunit</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutrodemeyer">10.2. An Alternative MSBuild Logger &#8211; Christian Rodemeyer&#8217;s MsBuildToCCNet</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutwebdashboardimages">10.3. CruiseControl.NET Webdashboard fails in finding images if not installed in virtual directory</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutnumberofprojects">10.4. MSBuildToCCNET reports wrong number of compiled projects</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutassemblylinker">10.5. CruiseControl.NET, MsBuild Task and Resources &#8211; Assembly Linker</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutwebappprojects">10.6. CruiseControl.NET, MsBuild Task and Web Application projects</a></span><br />
<a href="#ccnettutnunittask">11. Nunit Task</a><br />
<span style="position:relative;left:10px;"><a href="#ccnettutnunittask1">11.1. Nunit Task</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutnunittask2">11.2. Executable Task</a></span><br />
<a href="#ccnettutpublishersblock">12. Publishers Block</a><br />
<a href="#ccnettutprebuildblock">13. PreBuild Block</a><br />
<span style="position:relative;left:10px;"><a href="#ccnettutinstallnant">13.1. Install Nant</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutnantfundamentals">13.2. Nant Fundamentals</a></span></p>
<p>This article is the second one of a series dedicated to CruiseControl.Net.<br />
In the first part (which you can find <a title="part1" href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/" target="_blank">here</a>) we installed it and had an overview of how to configure it.<br />
Then we started to configure a project file: we instructed the <strong>Source Control Block</strong> to use Subversion, the <strong>Trigger Block</strong> to check it periodically and the <strong>Labeller Block</strong> to use: svnRevisionLabeller<br />
In this second article we will see the <strong>Tasks Block</strong> and I will point out some issues that might arise and provide solutions as well.</p>
<p>Thanks to Frank Geerlings for making me aware of a casing problem with the xml samples.<br />
By talking with WordPress support it came out that there was a little bug and they suggested me<br />
how to fix the problem.</p>
<h3><a title="ccnettuttasksblock" name="ccnettuttasksblock"></a><span style="font-size:small;color:#993300;">9. Tasks Block</span></h3>
<p>The tasks block represents how the build of the project actually takes place.<br />
In our example we will use an <strong>MsBuild Task</strong> to accomplish the main purpose of our project, which is to compile the versioned Visual Studio solution.<br />
After that we will use an <strong>Executable Task</strong> to run our unit tests, if the build succeeds.<br />
Let&#8217;s see the <a title="ccnettutsamplexml" name="ccnettutsamplexml">whole Tasks Block</a>, at first:</p>
<pre class="brush: xml;">
&lt;tasks&gt;
&lt;!-- compiles working copy -- &gt;
  &lt;msbuild&gt;
    &lt;executable&gt;C:\WINDOWS\Microsoft.NET\Framework\
      v2.0.50727\MSBuild.exe
    &lt;/executable&gt;
    &lt;workingDirectory&gt;C:\develop\CCnet\project1WorkingDir
    &lt;/workingDirectory&gt;
&lt;projectFile&gt;DummySolution.sln&lt;/projectFile &gt;
    &lt;buildArgs&gt;/noconsolelogger /v:quiet
      /p:Configuration=Debug
      /p:ReferencePath=&quot;C:\Program Files\NUnit 2.4.7\bin&quot;
    &lt;/buildArgs&gt;
    &lt;targets&gt;ReBuild&lt;/targets &gt;
    &lt;timeout&gt;600&lt;/timeout &gt;
    &lt;logger&gt;c:\Program Files\CruiseControl.NET\server\
      Rodemeyer.MsBuildToCCNet.dll&lt;/logger &gt;
  &lt;/msbuild&gt;
&lt;!-- launches nunit tests on working copy -- &gt;
  &lt;exec&gt;
    &lt;executable&gt;C:\Program Files\NUnit 2.4.7\
      bin\nunit-console.exe
    &lt;/executable &gt;
    &lt;buildArgs&gt;/xml:..\project1CCnetArtifacts\nunit-results.xml
      /nologo Dummy.sln.nunit
      /exclude:LongRunning,AnotherCategoryName
    &lt;/buildArgs&gt;
  &lt;/exec&gt;
&lt;/tasks&gt;
</pre>
<p>Let&#8217;s focus on the <strong>MsBuild Task</strong> first and see how we can configure and customize it:</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettuttasksblock"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutmsbuildtask" name="ccnettutmsbuildtask"></a><span style="font-size:small;color:#993300;">10. MsBuild Task</span></h3>
<p>Let&#8217;s have a look at the meaning of the xml nodes children of the <strong>&#60;msbuild&#62;</strong> node:</p>
<p><strong>&#60;executable&#62;</strong>: contains the path to the msbuild executable file. You don&#8217;t really need to set it because the default value is the standard installation path: <span style="color:#808080;">C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</span>.<br />
I decided to set it explicitly just to be sure about it .<br />
<strong>&#60;workingDirectory&#62;</strong>: is the directory in which MsBuild will be run, so it must be the directory containing our project&#8217;s checked out working copy. You can provide a path relative to the current project&#8217;s workinDirectory but I preferred to provide the full path. Actually, the path to the CCNET checked out working copy is the same as the <strong>&#60;workingDirectory&#62;</strong> field of the <strong>Source Control Block</strong>.<br />
<strong>&#60;projectFile&#62;</strong>: is the name of the project to build. MsBuild accepts a Visual Studio solution file as the project file to build. Obviously the <strong>MsBuild Task</strong> accepts it as well.<br />
<strong>&#60;buildArgs&#62;</strong> This row provides additional command line arguments to MsBuild. We tell it not to log events to the console (<span style="color:#808080;">/noconsolelogger</span>), to build the Debug configuration (<span style="color:#808080;">/p:Configuration=Debug</span>) and to provide a reduced output (<span style="color:#808080;">/v:quiet</span>).<br />
As far as the <span style="color:#808080;">/p:ReferencePath</span> buildArg is concerned it is worth to talk extensively about a problem that could arise with Nunit, so have a look at <a href="#ccnettutreferencepath" target="_self">paragraph 10.1</a>.</p>
<h4><a title="ccnettutreferencepath" name="ccnettutreferencepath"></a><span style="font-size:x-small;color:#993300;">10.1 MSBuild and ReferencePath &#8211; CruiseControl.NET not resolving reference to Nunit</span></h4>
<p>It could happen that CCNET is not able to locate Nunit (or some other dependency assembly) depending on how your project file has been created by Visual Studio.<br />
Open your project file (<strong>DummyProject.csproj</strong>) with a text editor (e.g.: Notepad++). If you find an entry as follows in it:</p>
<pre class="brush: xml;">
&lt;Itemgroup&gt;
  &lt;Reference Include=&quot;nunit.framework, Version=2.4.7.0,
    Culture=neutral, PublicKeyToken=96d09a1eb7f44a77,
    processorArchitecture=MSIL&quot; /&gt;
      ....
&lt;/Itemgroup&gt;
</pre>
<p>with no &#60;HintPath&#62; associated to the Nunit &#60;Reference&#62; it could be that CCNET will not be able to resolve that reference if you don&#8217;t register nunit.framework.dll in the server&#8217;s GAC.</p>
<p>You can make sure that CCNET is able to resolve the dependency by providing an alternative search path in which to look for.<br />
Each assembly referenced in the Visual Studio project file needs to be located by MSBUild at compile time.<br />
The location of the referenced assemblies is resolved by MSBuild by looking in several locations in a particular search order (as explained <a title="reference path vs2005" href="http://blogs.msdn.com/manishagarwal/archive/2005/09/28/474769.aspx" target="_blank">here</a>).<br />
We could modify the .csproj file by providing a  value as a child node of the  node, e.g.:</p>
<pre class="brush: xml;">
&lt;Reference Include=&quot;DummyLibrary, Version=1.0.0.0,
    Culture=neutral, processorArchitecture=MSIL&quot;&gt;
  &lt;SpecificVersion&gt;False&lt;/SpecificVersion&gt;
  &lt;HintPath&gt;..\..\CommonReferencedDLLs\DummyLibrary.dll
  &lt;/HintPath&gt;
&lt;/Reference&gt;
</pre>
<p>This approach has two drawbacks:</p>
<ol>
<li> the hintpath is a relative path, thus making the build success depend on the location of the project relative to the referenced assembly (this could be a problem if we reference an external assembly);</li>
<li>we need to modify each Visual Studio project file by hand  and we don&#8217;t want to do it!</li>
</ol>
<p>Fortunately there&#8217;s an easy way out:<br />
We can override all the project specific settings for path resolving by passing a <strong>ReferencePath </strong>property from the MSBuild command line.<br />
Such property accepts as value a list of paths (<em>MSBuild DummySolution.sln  /p:&#8221;ReferencePath=&#60;Path1;Path2;Path3&#62;&#8221;</em>) and it is checked by the build process before checking other locations (<strong>HintPath</strong> for example).<br />
So the way to provide an alternative search path from the command line is to pass as argument a <strong>ReferencePath</strong> property.<br />
This is the reason why the command line provided in the &#60;buildArgs&#62; field contains the <strong>ReferencePath</strong> property pointing to the Nunit install path:<br />
<span style="color:#808080;">/p:ReferencePath=&#8221;C:\Program Files\NUnit 2.4.7\bin&#8221;</span>.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutmsbuildtask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<p><span style="font-size:x-small;color:#993300;">end of paragraph 10.1</span><br />
<span style="font-size:x-small;color:#993300;">continues paragraph 10. MsBuild Task</span></p>
<p>Let&#8217;s go on with the analysis of the xml nodes children of the &#60;msbuild&#62; node:<br />
<strong>&#60;targets&#62;</strong> specifies which targets to build in this msbuild project file. It represents the MSbuild&#8217;s /target command line argument. We set it to <strong>Rebuild</strong> (clean and build).<br />
<strong>&#60;timeout&#62;</strong> is the number of seconds before assuming that the process has hung. If timeout is exceeded the process will be killed.<br />
<strong>&#60;logger&#62;</strong> specifies the path to the assembly containing the logger to use to format the log output of MSbuild .<br />
If you don&#8217;t want to use the alternative logger that I used in the configuration shown above, you can rely on the default logger as explained here and skip the following<br />
<a href="#ccnettutrodemeyer" target="_self">paragraph 10.2</a>.<br />
To use the default logger:</p>
<ul>
<li>leave out the &#60;logger&#62; field,</li>
<li>download the assembly containing the default xml logger <a title="default logger" href="http://ccnetlive.thoughtworks.com/MSBuildXmlLogger%2DBuilds/" target="_blank">here</a> (find info <a title="loggers description" href="http://confluence.public.thoughtworks.org/display/CCNET/Using+CruiseControl.NET+with+MSBuild" target="_blank">here</a>),</li>
<li>copy the downloaded assembly (<strong>ThoughtWorks.CruiseControl.MSBuild.dll</strong>) to the folder: <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\server</span>.</li>
</ul>
<p>I suggest to use the alternative logger (by Christian Rodemeyer) as explained in the following paragraph. The RodeMeyer&#8217;s logger provide lighter msbuild output and his modified stylesheets provide much more readable display of such information.</p>
<h4><a title="ccnettutrodemeyer" name="ccnettutrodemeyer"></a><span style="font-size:x-small;color:#993300;">10.2. An Alternative MSBuild Logger &#8211; Christian Rodemeyer&#8217;s MsBuildToCCNet</span></h4>
<p>I chose to use a logger alternative to the default one: Christian Rodemeyer&#8217;s MsBuildToCCNet.<br />
You can find it at:  <a title="rodemeyer page" href="http://confluence.public.thoughtworks.org/display/CCNETCOMM/Improved+MSBuild+Integration" target="_blank">Improved MSBuild Integration</a>.  From there either you can download separately the assembly and all related stuff needed to correctly display the results from Rodemeyer&#8217;s logger or you can download a zip file with the whole project and source code.</p>
<p>In the page cited above you can find detailed instructions on how the logger works and how it should be configured.<br />
In the current paragraph I&#8217;ll illustrate the installation process and add some useful tips for making it work.<br />
I suggest to download the full project that comes in a zip file named: MsBuildToCCNet.zip (download <a title="download rodemeyer" href="http://confluence.public.thoughtworks.org/download/attachments/6253/MsBuildToCCNet.zip?version=5" target="_blank">here</a>).<br />
Unzipping the package you will have a directory named: MsBuildToCCNet. Inside this directory you will find, among the rest, a directory named <strong>Release</strong>, containing the assembly: <strong>Rodemeyer.MsBuildToCCnet.dll</strong>.<br />
Just copy the assembly to the <span style="color:#808080;">\CruiseControl.NET\server</span> folder (e.g.: <span style="color:#808080;">c:\Program Files\CruiseControl.NET\server\</span>).<br />
There&#8217;s another subdirectory of the <span style="color:#808080;">MsBuildToCCNet</span> folder, named <span style="color:#808080;">ccnet</span> where you can find the resources needed to correctly display the logs produced by Rodemeyer&#8217;s logger. Those resources are:<br />
<strong>cruisecontrol.css</strong> and<br />
<strong>msbuild2ccnet.xsl</strong>.</p>
<p>You need to use those two files and to configure the Webdshboard:</p>
<ol>
<li>Move into your CruiseControl.NET Webdashboard folder, under the path: <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\webdashboard</span> (e.g.: <span style="color:#808080;">c:\Program Files\CruiseControl.NET\webdashboard\</span>) and back up the file: <strong>cruisecontrol.css</strong>.<br />
Then replace it with the <strong>cruisecontrol.css</strong> file you found in the Rodemeyer&#8217;s MsBuildToCCNet folder (e.g.: copy <span style="color:#808080;">MsBuildToCCNet\ccnet\cruisecontrol.css</span> to <span style="color:#808080;">c:\Program Files\CruiseControl.NET\webdashboard\cruisecontrol.css</span>);</li>
<li>There&#8217;s a subdirectory of the CruiseControl.NET Webdashboard folder, named: <strong>xsl</strong>.<br />
You need to copy the other resource (<strong>msbuild2ccnet.xsl</strong>) you found in the <span style="color:#808080;">MsBuildToCCNet\ccnet</span> folder in that directory: <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\webdashboard\xsl\</span>;</li>
<li>You need to modify the <strong>dashboard.config</strong> file in the CruiseControl.NET Webdashboard folder in order to correctly show the output of the logger.<br />
Being that we&#8217;re talking about the Webdashboard configuration I will show you all the changes you will need to do to let it work with the following three components (even if we&#8217;ll see two of them only in the following paragraphs):</p>
<ul>
<li> MsBuildToCCNet</li>
<li> Nunit integration</li>
<li> FxCop integration</li>
</ul>
<p>First of all choose a 32 x 32 jpg image representing a smiling icon and place it in the CruiseControl.NET Webdashboard folder: <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\webdashboard</span>.<br />
Rename the image file: <em>your_happy_image.jpg</em> and, when a new build succeeds, you&#8217;ll obtain a smiling icon in the Webdashboard report! (you can find a sample image <a title="happy image" href="http://ilmatte.wordpress.com/files/2008/06/your_happy_image.jpg" target="_blank">here</a>).<br />
Then open <span style="color:#808080;">CruiseControl.NET\webdashboard\xsl\msbuild2ccnet.xsl</span> and go to line 24:</p>
<pre class="brush: xml;">
&lt;xsl :if test=&quot;@error_count = 0 and @warning_count = 0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src=&quot;/ccnet/your_happy_image.jpg&quot;
           alt=&quot;Happy Image <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> &quot; /&gt; Juchuu !!!&lt;/td&gt;
&lt;/tr&gt;
&lt;/xsl&gt;
</pre>
<p>replace the <em>img src</em> attribute: <span style="color:#808080;">/ccnet/your_happy_image.jpg</span> with <span style="color:#808080;">/your_happy_image.jpg</span> if you configured iis with a new website for the webdashboard instead of a virtual directory. If you&#8217;re usign the default virtual directory named <strong>ccnet</strong>, don&#8217;t modify that row.<br />
Next you need to locate the field: <strong>&#60;buildPlugins&#62;</strong> in <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\webdashboard\dashboard.config</span> and arrange or delete its children nodes in order to obtain the following configuration (remember to back up the file first):</p>
<pre class="brush: xml;">
&lt;buildplugins&gt;
  &lt;buildreportbuildplugin&gt;
    &lt;xslfilenames&gt;
      &lt;xslfile&gt;xsl\header.xsl&lt;/xslfile&gt;
      &lt;xslfile&gt;xsl\modifications.xsl&lt;/xslfile&gt;
      &lt;xslfile&gt;xsl\msbuild2ccnet.xsl&lt;/xslfile&gt;
      &lt;xslfile&gt;xsl\unittests.xsl&lt;/xslfile&gt;
      &lt;xslfile&gt;xsl\compile.xsl&lt;/xslfile&gt;
      &lt;xslfile&gt;xsl\fxcop-summary.xsl&lt;/xslfile&gt;
    &lt;/xslfilenames&gt;
  &lt;/buildreportbuildplugin&gt;
  &lt;buildlogbuildplugin /&gt;
  &lt;xslreportbuildplugin description=&quot;NUnit Details&quot;
       actionName=&quot;NUnitDetailsBuildReport&quot;
       xslFileName=&quot;xsl\tests.xsl&quot; /&gt;
  &lt;xslreportbuildplugin description=&quot;NUnit Timings&quot;
       actionName=&quot;NUnitTimingsBuildReport&quot;
       xslFileName=&quot;xsl\timing.xsl&quot; /&gt;
   &lt;xslreportbuildplugin description=&quot;FxCop Report&quot;
       actionName=&quot;FxCopBuildReport&quot;
       xslFileName=&quot;xsl\FxCopReport.xsl&quot; /&gt;
&lt;/buildplugins&gt;
</pre>
<p>As you can see, such configuration includes also stylesheet files for nunit and fxcop integration. We will soon configure the server to integrate those components.</li>
</ol>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutmsbuildtask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<p><span style="font-size:x-small;color:#993300;">end of paragraph 10.2</span><br />
<span style="font-size:x-small;color:#993300;">continues paragraph 10. MsBuild Task</span></p>
<p>While adding the smiling image in the previous paragraph we had to change the path in the xsl file.<br />
The same problem could arise with other stylesheet files if you configured the webdashboard to be a website instead that a virtual directory named ccnet.<br />
Have a look at the next paragraph for details:</p>
<h4><a title="ccnettutwebdashboardimages" name="ccnettutwebdashboardimages"></a><span style="font-size:x-small;color:#993300;">10.3. CruiseControl.NET Webdashboard Fails in Finding Images if Not Installed in Virtual Directory</span></h4>
<p>If you unchecked <span style="color:#808080;">&#8216;Create virtual directory in IIS for Web dashboard&#8217;</span> as shown in part 1 of this tutorial at <a title="install part 1" href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutinstallccnet" target="_blank">3.1. Install CruiseControl.NET</a> and installed the Webdashboard as a new website as shown in the paragraph: <a title="create iis website part 1" href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutiiscreatesite" target="_blank">3.2. Create a CCNet Website in IIS</a>, the webdashboard could have problems in resolving image paths.<br />
You will realize it as soon as you will configure the server to integrate nunit or fxcop (will see it in  following paragraphs).<br />
To make sure not to have this problems you must modify the following files:<br />
<strong>xsl\tests.xsl</strong><br />
<strong>xsl\fxcop-summary.xsl</strong><br />
under: <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\webdashboard\</span></p>
<p>you have to replace all the paths relative to the root of the website with relative paths, e.g:</p>
<p>in the file: <strong>xsl\tests.xsl</strong> you should replace all entries like:</p>
<pre class="brush: xml;">
eImg.src = &quot;&lt;xsl :value-of select=&quot;$applicationPath&quot;/&gt;/images/arrow_minus_small.gif&quot;;
</pre>
<p>with:</p>
<pre class="brush: xml;">
eImg.src = &quot;&lt;xsl :value-of select=&quot;$applicationPath&quot;/&gt;images/arrow_minus_small.gif&quot;;
</pre>
<p>and entries like:</p>
<pre class="brush: xml;">
&lt;img src=&quot;{$applicationPath}/images/fxcop-error.gif&quot;/&gt;
</pre>
<p>with:</p>
<pre class="brush: xml;">
&lt;img src=&quot;{$applicationPath}images/fxcop-error.gif&quot;/&gt;
</pre>
<p>that is, you simply need to delete the leading &#8216;forward slash&#8217; at the beginning of the path (just before the &#8216;images&#8217; folder name).</p>
<p>you need to accomplish the same task with the file <strong>xsl\fxcop-summary.xsl</strong>, e.g.:</p>
<p>you should replace entries like:</p>
<pre class="brush: xml;">
&lt;xsl :attribute name=&quot;src&quot;&gt;&lt;xsl :value-of select=&quot;$applicationPath&quot; /&gt;/images/fxcop-critical-error.gif&lt;/xsl&gt;
</pre>
<p>with:</p>
<pre class="brush: xml;">
&lt;xsl :attribute name=&quot;src&quot;&gt;&lt;xsl :value-of select=&quot;$applicationPath&quot; /&gt;images/fxcop-critical-error.gif&lt;/xsl&gt;
</pre>
<p>Actually, you should find all paths to images in those two files and delete the leading forward slash.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutmsbuildtask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<p><span style="font-size:x-small;color:#993300;">end of paragraph 10.3</span><br />
<span style="font-size:x-small;color:#993300;">continues paragraph 10. MsBuild Task</span></p>
<p>Back to the MSBuildToCCNET alternative Logger for MsBuild, I will explain now why I decided to recompile the source code instead of using the assembly provided: <span style="color:#808080;">MsBuildToCCNet\Release\Rodemeyer.MsBuildToCCnet.dll</span></p>
<h4><a title="ccnettutnumberofprojects" name="ccnettutnumberofprojects"></a><span style="font-size:x-small;color:#993300;">10.4. MSBuildToCCNET Reports Wrong Number of Compiled Projects</span></h4>
<p>I found that MsBuildToCCNet reported the wrong number of projects in the webdashboard in the page reporting the details of the last build.<br />
There&#8217;s a row that sounds like the following, displaied in that page:</p>
<p><span style="color:#0000ff;">&#8216;15 Projects built with 2 warnings&#8217;</span></p>
<p>Looking at the source code (in the file: <strong>Logger.cs</strong>) I realized that the list of <em>Project</em> type instances includes the solution file (<span style="color:#666699;">DummySolution.sln</span>) and a <em>Project</em> object named &#8220;<span style="color:#ff6600;">MSBuild</span>&#8220;, somehow representing the MsBuild process.<br />
Appearently this is the reason why the reported number of projects is wrong.<br />
I still haven&#8217;t tried to contact the author so I don&#8217;t know very well how the Logger is supposed to work as far as this count is concerned.<br />
As a workaround I modified the following row:</p>
<pre class="brush: csharp;">
w.WriteAttributeString(&quot;project_count&quot;,
                     XmlConvert.ToString(projects.Count));
</pre>
<p>turning it into:</p>
<pre class="brush: csharp;">
w.WriteAttributeString(&quot;project_count&quot;,
                     XmlConvert.ToString(projects.Count - 2));
</pre>
<p>in the &#8216;WriteLog(XmlWriter w)&#8217; method (file: <strong>Logger.cs</strong> at row 104).</p>
<p>This seems having fixed the problem with no side effects.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutmsbuildtask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<p><span style="font-size:x-small;color:#993300;">end of paragraph 10.4</span><br />
<span style="font-size:x-small;color:#993300;">continues paragraph 10. MsBuild Task</span></p>
<p>You could have problems running msbuild task if your server machine (the one in which you installed CruiseControl.NET) is not updated with all the software installed in a developer workstation. Let&#8217;s see which problems could arise:</p>
<h4><a title="ccnettutassemblylinker" name="ccnettutassemblylinker"></a><span style="font-size:x-small;color:#993300;">10.5. CruiseControl.NET, MsBuild Task and Resources &#8211; Assembly Linker</span></h4>
<p>If you want to provide localization for any of your projects or somehow use resources files (.resx) you will get an error during the build on the CruiseControl.NET server if MsBuild is not able to locate the Assembly Linker.<br />
The error should look something like:</p>
<p><span style="color:#ff0000;">C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1950,9): error MSB3011: &#8220;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\AL.exe&#8221; was not found. Either 1) Install the .NET Framework SDK, which will install AL.exe. Or 2) Pass the correct location of AL.exe into the &#8220;ToolPath&#8221; parameter of the AL task.</span></p>
<p>AL.exe is used to produce the satellite assemblies and the executable file is placed in the .NET framework directory.<br />
But Al.exe is a .Net Framework SDK tool. It is not included in .Net Framework 2.0 runtime installation.<br />
You need to install the .NET framework SDK on the server machine if you don&#8217;t want to encounter this problem.<br />
If you want to solve this particular issue in a tricky way without installing the whole SDK, you can copy <strong>al.exe.config</strong> e <strong>al.exe</strong> from a developer workstation and place them in the <span style="color:#808080;">C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727</span> directory on the server machine.<br />
This is how I solved the problem but I suggest you to install the .NET framework SDK on the server machine.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutmsbuildtask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h4><a title="ccnettutwebappprojects" name="ccnettutwebappprojects"></a><span style="font-size:x-small;color:#993300;">10.6. CruiseControl.NET, MsBuild Task and Web Application projects</span></h4>
<p>A particular note is due for Web projects.<br />
Updating Visual Studio 2005 you get the SP1. Together with the Service Pack 1 for Visual Studio you get the WebApplication project template.<br />
Such template lets us add a new kind of project to our solution: a web site project structured exactly like any other Visual Studio project.<br />
So you can quit creating new websites (<strong>File &#8211;&#62; New &#8211;&#62; Web Site&#8230;</strong>) and start creating new WebApplication projects (<strong>File &#8211;&#62; New &#8211;&#62; Project&#8230;</strong> and then choose &#8216;<strong>ASP.NET Web Application</strong>&#8216;).</p>
<p>In order to use WebApplication projects you need to have Visual Studio installed on your machine and the WebApplication project plugin (that comes with the Visual Studio 2005 SP1).<br />
If the server in which CruiseControl.NET server is running is not a develpment workstation you will get an error when trying to build a WebApplication project, beacuse you miss those two prerequisites.</p>
<p>You can easily fix this problem: you simply need to copy the file: <strong>Microsoft.WebApplication.targets</strong> that you can find under:<br />
<span style="color:#808080;">&#8220;C:\Program Files\MSBuild\Microsoft\VisualStudio\v8.0\WebApplications\&#8221;</span><br />
from a development workstation and paste it to the corresponding path on the server machine (creating the directories in the path if needed).</p>
<p>Additionally, if you&#8217;re using an ASP.NET AJAX Enabled WebApplication as the web project template you need to install the aspnet-ajax extensions as well.<br />
You can find the installer (ASPAJAXExtSetup.msi) for .NET framework 2.0 <a title="asp.net ajax download" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&#38;displaylang=en" target="_blank">here</a></p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutmsbuildtask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutnunittask" name="ccnettutnunittask"></a><span style="font-size:small;color:#993300;">11. Nunit Task</span></h3>
<p>The second Task Block that you find in the xml fragment <a title="xml msbuild task" href="#ccnettutsamplexml" target="_self">above</a> is an Executable Task used to instruct CruiseControl.NET to run unit tests with Nunit.</p>
<p>At first I tried to use a <strong>Nunit Task Block</strong> but I soon realized that it was not good for me because it was not possible to provide arguments to the task that should be used as arguments of the Nunit command-line executable.</p>
<p>This is a problem because there&#8217;s no way to let the Nunit task be aware of Nunit categories.<br />
For those who don&#8217;t know, Nunit lets you specify a &#8216;<em>Category</em>&#8216; attribute in test methods, with the following syntax:</p>
<pre class="brush: csharp;">
[Test]
[Category(&quot;LongRunning&quot;)]
public void VeryLongTest()
{ /* ... */ }
</pre>
<p>This attribute allows you to instruct Nunit to treat all the methods belonging to the same category in the same way.<br />
Usually what we want to do is to exclude a cluster of tests from running.<br />
Typically we exclude tests that take too much to run, using the following syntax with the nunit command-line tool:</p>
<p><strong>nunit-console.exe /exclude:LongRunning,AnotherCategoryName</strong></p>
<p>You can configure excluded categories in nunit GUI as well, by clicking the &#8216;<strong>Categories</strong>&#8216; tab in the top left corner.<br />
A list of available categories will be shown. Just select the categories of interest and click the <strong>Add</strong> button.<br />
Then check the <strong>Exclude these categories</strong> checkbox at the bottom of the page and run the nunit project.</p>
<p>It is very useful to be able to exclude some categories of tests from the continuous integration environment, still being able to run them on developer machines.</p>
<p>This is the reason why I recently submitted a patch to CruiseControl.Net adding support for Nunit categories.<br />
It&#8217;s not included in the official release yet, because I submitted it too late for this purpose.<br />
However you can find it in the current build which is publicly available at: <a href="http://ccnetlive.thoughtworks.com/CCNet-builds/">ccnetlive</a>. The patch is included starting from build: <a href="http://ccnetlive.thoughtworks.com/CCNet-builds/1.4/1.4.0.3591/CruiseControl.NET-1.4.0.3591.zip">3591</a>.<br />
So now you have two chances to use categories:</p>
<ol>
<li>If you really want to use the last officially released version, read the <a href="#ccnettutnunittask2">paragraph 11.2</a> about how to use an Executable Task (the method described can be useful also if you want to use any other unsupported Nunit command line argument);</li>
<li><span style="text-decoration:underline;">Instead if you can download the latest build from ccnetlive you will be able to specify categories</span> inside the Nunit Task block, as explained in <a href="#ccnettutnunittask">paragraph 11.1</a></li>
</ol>
<h4><a title="ccnettutnunittask1" name="ccnettutnunittask1"></a><span style="font-size:x-small;color:#993300;">11.1. Nunit Task</span></h4>
<p>If you downloaded the most recent build and followed the installation instructions (see: <a href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/#ccnettutinstallation">3. Installation</a>) you can go on reading this paragraph.<br />
If you installed the official release or a build older than 1.4.0.3591, you can still modify your installation with the following instructions:</p>
<p>download the zipped package (<a href="http://ccnetlive.thoughtworks.com/CCNet-builds/1.4/1.4.0.3591/CruiseControl.NET-1.4.0.3591.zip">here</a>) or source code. Unzip it in a temporary directory and locate the assembly: ThoughtWorks.CruiseControl.Core.dll (which, for the zip package, is in the directory: &#8217;server&#8217;).<br />
Copy and replace it to the original one in your CCNET installation directory (back up the original one first) that should be: <span style="color:#808080;">Program Files\CruiseControl.NET\server</span>.</p>
<p>That&#8217;s it! Now you can use the CruiseControl.NET&#8217;s Nunit Task Block also for specifying Nunit categories (see: <a href="http://www.nunit.org/index.php?p=category&#38;r=2.4.8">Nunit categories</a> for reference).</p>
<p>It is possible to specify a list of the categories of tests that we want to be excluded.<br />
It is possible, as well, to specify a list of the only categories that we want to be included as allowed by the Nunit Command-line or GUI interface.<br />
The configuration syntax for the Nunit task becomes:</p>
<pre class="brush: xml;">
&lt;nunit&gt;
&lt;path&gt;C:\Program Files\NUnit 2.4.7\bin\nunit-console.exe
&lt;/path&gt;
    &lt;assemblies&gt;
        &lt;assembly&gt;Dummy.sln.nunit&lt;/assembly&gt;
    &lt;/assemblies&gt;
    &lt;excludedCategories&gt;
        &lt;excludedCategory&gt;LongRunning&lt;/excludedCategory&gt;
	&lt;excludedCategory&gt;Category 2&lt;/excludedCategory&gt;
    &lt;/excludedCategories&gt;
&lt;/nunit&gt;
</pre>
<p>for excluded categories, or:</p>
<pre class="brush: xml;">
&lt;nunit&gt;
&lt;path&gt;C:\Program Files\NUnit 2.4.7\bin\nunit-console.exe
&lt;/path&gt;
    &lt;assemblies&gt;
        &lt;assembly&gt;Dummy.sln.nunit&lt;/assembly&gt;
    &lt;/assemblies&gt;
    &lt;includedCategories&gt;
        &lt;includedCategory&gt;LongRunning&lt;/includedCategory&gt;
	&lt;includedCategory&gt;Category 2&lt;/includedCategory&gt;
    &lt;/includedCategories&gt;
&lt;/nunit&gt;
</pre>
<p>for included categories. You can find the official reference at <a href="http://confluence.public.thoughtworks.org/display/CCNET/NUnit+Task" target="_blank">this page</a> on the official website.</p>
<p>The Nunit task output log file is automatically integrated in the CCNET build results.<br />
So you don&#8217;t need to specify the Merge task (needed if you use the procedure explaine in paragraph 11.2 instead of this one) in the Publishers block as explained in <a href="#ccnettutpublishersblock">paragraph 12</a>:</p>
<pre class="brush: xml;">
&lt;merge&gt;
  &lt;files&gt;
    &lt;file&gt;..\project1CCnetArtifacts\nunit-results.xml&lt;/file&gt;
  &lt;/files&gt;
&lt;/merge&gt;
</pre>
<p>Instead you still need to delete the previous Nunit log file before each build process as explained in the <a href="#ccnettutprebuildblock">paragraph 13 &#8211; PreBuild Block</a>.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutnunittask"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h4><a title="ccnettutnunittask2" name="ccnettutnunittask2"></a><span style="font-size:x-small;color:#993300;">11.2. Executable Task</span></h4>
<p>If you&#8217;re working with the official release of CruiseControl.Net (release 1.4) Nunit Task Block syntax only allows you to specify the target solution and little more. In our example it would be:</p>
<pre class="brush: xml;">
&lt;nunit&gt;
&lt;path&gt;C:\Program Files\NUnit 2.4.7\bin\nunit-console.exe
&lt;/path&gt;
	&lt;assemblies&gt;
		&lt;assembly&gt;Dummy.sln.nunit&lt;/assembly&gt;
	&lt;/assemblies&gt;
&lt;/nunit&gt;
</pre>
<p>where <strong>Dummy.sln.nunit</strong> is the Nunit project file for our solution.</p>
<p>The solution I strongly suggest is to replace the Nunit Task with an Executable Task like the one shown below:</p>
<pre class="brush: xml;">
&lt;exec&gt;
  &lt;executable&gt;
    C:\Program Files\NUnit 2.4.7\bin\nunit-console.exe
  &lt;/executable&gt;
  &lt;buildArgs&gt;/xml:..\project1CCnetArtifacts\nunit-results.xml
    /nologo Dummy.sln.nunit
    /exclude:LongRunning,AnotherCategoryName
  &lt;/buildArgs&gt;
&lt;/exec&gt;
</pre>
<p>You only need to specify the full path to the Nunit command-line executable file in the <strong>&#60;executable&#62;</strong> field and the command-line arguments in the <strong>&#60;buildArgs&#62;</strong> field.</p>
<p>In the <strong>&#60;buildArgs&#62;</strong> field you specify arguments as if provided directly to <strong>nunit-console.exe</strong>:</p>
<ol>
<li>specify the path to the file in which nunit will write its output: <span style="color:#808080;">/xml:..\project1CCnetArtifacts\nunit-results.xml</span>.<br />
The file should be produced in the artifactDirectory of the current CCNET project.<br />
By default the executable run by an executable task is run in the Project Working Directory, so the path to the output file is relative to such directory.</li>
<li> You can pass many things as Nunit targets (assemblies, Visual Studio projects or Nunit project files). I suggest to create an Nunit project and pass it as argument to <strong>nunit-console.exe</strong> as shown in the sample above (where the nunit project file is called: <strong>Dummy.sln.nunit</strong>).</li>
<li> you can then add: <span style="color:#808080;">/exclude:LongRunning,AnotherCategoryName</span> thus excluding unwanted tests.</li>
</ol>
<p>Specifying the name of the output file is not enough.<br />
In order to make the output written by nunit in the file nunit-results.xml (arbitrary name specified in the buildArgs tag), available to CruiseControl.NET we need to use a File Merge Task.<br />
If we used Nunit task the output file would have been automatically merged with other output for CruiseControl.NET.<br />
Using the Executable Task we need to explicitly configure CruiseControl.NET to merge the Nunit output file in the log file parsed by CruiseControl.NET.<br />
We will tell CruiseControl.NET to do it at the end of the build process, namely in the Publishers section.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutnunittask2"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutpublishersblock" name="ccnettutpublishersblock"></a><span style="font-size:small;color:#993300;">12. Publishers Block</span></h3>
<p>We will add a <strong>File Merge Task</strong> at the beginning of the Publishers section. You can see below the publishers section as it is defined in our project configuration file:</p>
<pre class="brush: xml;">
&lt;publishers&gt;
  &lt;merge&gt;
    &lt;files&gt;
      &lt;file&gt;..\project1CCnetArtifacts\nunit-results.xml
      &lt;/file&gt;
    &lt;/files&gt;
  &lt;/merge&gt;
  &lt;xmllogger /&gt;
  &lt;statistics /&gt;
  &lt;modificationHistory onlyLogWhenChangesFound=&quot;true&quot; /&gt;
  &lt;artifactcleanup cleanUpMethod=&quot;KeepLastXBuilds&quot;
    cleanUpValue=&quot;20&quot; /&gt;
      ...
&lt;/publishers&gt;
</pre>
<p>The File Merge Task specifies the paths to the files that we want to be merged by the <strong>Xml Log Publisher Task</strong> with the rest of its own output (you don&#8217;t need to specify nunit output file if you used the Nunit Task as in paragraph <a href="#ccnettutnunittask1">11.1. Nunit Task</a>).<br />
All of this output is placed by default in the <strong>buildlogs</strong> directory under the Project&#8217;s Artifact Directory.<br />
So the <strong>File Merge Task</strong> should appear before the <strong>Xml Log Publisher Task</strong> in the publishers section.<br />
The <strong>Xml Log Publisher Task</strong> (&#8216;<strong>xmllogger</strong>&#8216;) is needed for making the web dashboard work correctly.<br />
The &#8216;<strong>statistics</strong>&#8216; field collects and updates statistics for each build. You can see them clicking: <strong>View Statistics</strong> on the left side of the Web Dashboard.<br />
The &#8216;<strong>modificationHistory</strong>&#8216; field logs all the modifications for each build. With <strong>onlyLogWhenChangesFound</strong> you can choose to log info only for builds happened when changes take place (not for forced builds). You can see the modification history by clicking: <strong>View Modification History</strong> on the left side of the Web Dashboard.</p>
<p>I then added an &#8216;<strong>artifactcleanup</strong>&#8216; field in order to keep memory of the last 20 builds only.<br />
This task allows us to choose between two clean up modes of the past build logs:<br />
- deleting logs older than a specified number of days<br />
- keeping only a specified number of logs: the more recent ones (cleanUpMethod=&#8221;KeepLastXBuilds&#8221;)</p>
<p>In the sample above we typed the second choice specifying 20 as cleanUpValue thus telling CruiseControl.NET to keep the log files for the last 20 builds only.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutpublishersblock"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutprebuildblock" name="ccnettutprebuildblock"></a><span style="font-size:small;color:#993300;">13. PreBuild Block</span></h3>
<p>There&#8217;s another issue to solve when integrating Nunit using either an <strong>Exec Task</strong> or the <strong>Nunit Task</strong>: the Nunit log file is not deleted after the build succeeds or fails.<br />
So upon the next build we&#8217;ll still have the old Nunit log file until the Task running Nunit is executed.<br />
To understand what I&#8217;m going to explain now, keep in mind that if a task in the <strong>Tasks Block</strong> fails all the subsequent tasks in the block will be skipped while the tasks in the <strong>Publishers Block</strong> will be executed.</p>
<p>If, during the next build, the <strong>MSBuild Task</strong> fails, the <strong>Exec Task (Nunit Task)</strong> launching Nunit isn&#8217;t executed at all so the <strong>File Merge Task</strong> will merge the previous Nunit log file with the current <strong>Xml Log Publisher</strong> output, thus leading to an incorrect report: still displaying the Nunit results relative to the previous build.<br />
We would obtain the <span style="text-decoration:underline;">current</span> MSBuild report but the <span style="text-decoration:underline;">old</span> Nunit report.<br />
This behavior can lead to misunderstanding of the results so it is a good practice to delete the old Nunit log file before every new build takes place.</p>
<p>The place to accomplish this task is the <strong>PreBuild Block</strong>.<br />
I used a <strong>Nant</strong> build file to drive the steps needed to obtain the desired result (simply delete a file if it exists).</p>
<h4><a title="ccnettutinstallnant" name="ccnettutinstallnant"></a><span style="font-size:x-small;color:#993300;">13.1. Install Nant</span></h4>
<p>You need to install the <a title="nant homepage" href="http://nant.sourceforge.net/" target="_blank">Nant</a> Build tool on the server machine.<br />
Just download the zip package: nant-0.85-bin.zip from <a title="nant download" href="http://downloads.sourceforge.net/nant/nant-0.85-bin.zip?modtime=1160813010&#38;big_mirror=0" target="_blank">here</a> and unzip it into the folder: <span style="color:#808080;">C:\Program Files\Nant</span>.</p>
<h4><a title="ccnettutnantfundamentals" name="ccnettutnantfundamentals"></a><span style="font-size:x-small;color:#993300;">13.2. Nant Fundamentals</span></h4>
<p><strong>Nant</strong> is a build tool driven by xml configuration files (Nant build files).<br />
When you call nant.exe from the command line and you don&#8217;t specify a build file (you can specify one passing as argument: <span style="color:#ff6600;">-buildfile:pathToDir\FileName.build</span>) NAnt looks for a file ending with .build (e.g.: NAnt.build) in the current directory. If it finds such file, it uses it as the reference for the tasks to execute.</p>
<p>The file structure is shown in the following sample xml file:</p>
<pre class="brush: xml;">
&lt; ?xml version=&quot;1.0&quot;?&gt;
&lt;project name=&quot;dummy&quot; default=&quot;target1&quot; basedir=&quot;.&quot;&gt;
	&lt;description&gt;dummy project&lt;/description&gt;
	&lt;target name=&quot;target1&quot; description=&quot;target1 description&quot;&gt;
	    ... (a list of Nant tasks will be placed here)
	&lt;/target&gt;
	&lt;target name=&quot;target2&quot; description=&quot;target2 description&quot;&gt;
		&lt;delete file=&quot;pathToFile\FileName&quot;
                failonerror=&quot;false&quot; /&gt;
		... (a list of other Nant tasks will be placed here)
	&lt;/target&gt;
&lt;/project&gt;
</pre>
<p>A build file contains one <strong>&#60;project&#62;</strong> field with one or more children <strong>&#60;target&#62;</strong> fields each containing different Nant tasks (e.g.: the <strong>&#60;delete&#62;</strong> task).<br />
When invoking <strong>nant.exe</strong> you can specify the name of the target to be executed and Nant will execute all the tasks contained in that target. If you don&#8217;t provide a target, the default one will be executed (i.e. the one specified in the &#8216;<span style="color:#ff6600;">default</span>&#8216; attribute of the <strong>&#60;project&#62;</strong> field).</p>
<p><span style="font-size:x-small;color:#993300;">end of paragraph 13.2</span><br />
<span style="font-size:x-small;color:#993300;">continues paragraph 13. PreBuild Block</span></p>
<p>Once you&#8217;ve got Nant installed on the server machine you have to create a file named nant.build and place it, for convenience, in the directory in which you placed all the CruiseControl.NET related stuff (in this example: <span style="color:#808080;">C:\develop\CCnet</span>).</p>
<p>At the moment we need just one target to delete Nunit log files. Later we will add another target.<br />
The actual file content is the following:</p>
<pre class="brush: xml;">
&lt; ?xml version=&quot;1.0&quot;?&gt;
&lt;project name=&quot;Dummy&quot; default=&quot;cleanNunit&quot; basedir=&quot;.&quot;&gt;
  &lt;description&gt;CCNET Tasks&lt;/description&gt;
  &lt;target name=&quot;cleanNunit&quot;
         description=&quot;removes nunit log file&quot;&gt;
    &lt;delete file=&quot;${CCNetArtifactDirectory}\nunit-results.xml&quot;
          failonerror=&quot;false&quot; /&gt;
  &lt;/target&gt;
&lt;/project&gt;
</pre>
<p>When we tell Nant to execute the &#8216;<span style="color:#ff6600;">cleanNunit</span>&#8216; target, the delete task will be executed and the <strong>nunit-results.xml</strong> file will be deleted.<br />
We use one of the environment variables provided by CCNET to retrieve the path to the artifact directory: <span style="color:#ff6600;">${CCNetArtifactDirectory}</span> so this Nant build file will only work when run from CruiseControl.NET.</p>
<p>In the <strong>Prebuild Block</strong> we will instruct CruiseControl.NET to run a Nant task by adding a CruiseControl.NET <strong>Nant Task Block</strong>.<br />
Such block lets us instruct CruiseControl.NET to execute Nant and lets us specify a Nant build file and the list of Nant targets to execute.<br />
Remember that we named the build file: <strong>nant.build</strong> and we placed it in the directory: <span style="color:#808080;">C:\develop\CCnet</span>.<br />
Now we provide this information to the CruiseControl.NET <strong>Nant Task Block</strong> as shown in the following example:</p>
<pre class="brush: xml;">
&lt;prebuild&gt;
&lt;!-- clean nunit output to avoid CCNET reporting
       about previous build tests if current build fails --&gt;
  &lt;nant&gt;
    &lt;executable&gt;C:\Program Filse\Nant\bin\nant.exe
    &lt;/executable&gt;
    &lt;baseDirectory&gt;C:\develop\CCnet&lt;/baseDirectory&gt;
    &lt;nologo&gt;false&lt;/nologo&gt;
    &lt;buildFile&gt;nant.build&lt;/buildFile&gt;
    &lt;targetList&gt;
      &lt;target&gt;cleanNunit&lt;/target&gt;
    &lt;/targetList&gt;
  &lt;/nant&gt;
&lt;/prebuild&gt;
</pre>
<p>the <strong>&#60;executable&#62;</strong> field specifies the path to the version of nant.exe you want to run,<br />
the <strong>&#60;baseDirectory&#62;</strong> specifies the directory to run the NAnt process in,<br />
<strong>&#60;nologo&#62;</strong> passes the -nologo argument to the Nant command line,<br />
<strong>&#60;buildFile&#62;</strong> specifies the path to the build file to use (relative to the <strong>&#60;baseDirectory&#62;</strong>),<br />
<strong>&#60;targetList&#62;</strong> is used to specify a list of targets, each one in a <strong>&#60;target&#62;</strong> field.</p>
<p>Now we can be sure that each build has the Nunit log file deleted before being executed.</p>
<p><a href="#ccnettut2top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutprebuildblock"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<p><a title="tutorial part 1" href="http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/" target="_self">&#60;&#60; CruiseControl.Net Tutorial &#8211; Part 1</a></p>
<h2><span style="color:#ff0000;"><br />
As soon as possible I will post the third and last part of this tutorial<br />
</span></h2>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2filmatte.wordpress.com%2f2008%2f06%2f15%2fcruisecontrolnet-tutorial-part-2%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2filmatte.wordpress.com%2f2008%2f06%2f15%2fcruisecontrolnet-tutorial-part-2%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Configuring Projects on Multiple Instances of Cruise Control .Net]]></title>
<link>http://karlagius.com/2008/06/08/configuring-projects-on-multiple-instances-of-cruise-control-net/</link>
<pubDate>Sun, 08 Jun 2008 21:31:17 +0000</pubDate>
<dc:creator>karlagius</dc:creator>
<guid>http://karlagius.com/2008/06/08/configuring-projects-on-multiple-instances-of-cruise-control-net/</guid>
<description><![CDATA[A continuous integration server is an essential tool in the box of any team &#8211; even a one man t]]></description>
<content:encoded><![CDATA[A continuous integration server is an essential tool in the box of any team &#8211; even a one man t]]></content:encoded>
</item>
<item>
<title><![CDATA[CruiseControl.Net Tutorial - Part 1]]></title>
<link>http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/</link>
<pubDate>Sun, 01 Jun 2008 22:15:59 +0000</pubDate>
<dc:creator>ilmatte</dc:creator>
<guid>http://ilmatte.wordpress.com/2008/06/01/cruisecontrolnet-tutorial-part-1/</guid>
<description><![CDATA[1. Introduction 2. Resources 3. Installation 3.1. Install CruiseControl.NET 3.2. Create a CCNet Webs]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a title="ccnettut1top" name="ccnettut1top"></a><br />
<a href="#ccnettutintro">1. Introduction</a><br />
<a href="#ccnettutresources">2. Resources</a><br />
<a href="#ccnettutinstallation">3. Installation</a><br />
<span style="position:relative;left:10px;"><a href="#ccnettutinstallccnet">3.1. Install CruiseControl.NET</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutiiscreatesite">3.2. Create a CCNet Website in IIS</a></span><br />
<span style="position:relative;left:10px;"><a href="#ccnettutinstallnunit">3.3. Install Nunit</a></span><br />
<a href="#ccnettutconfiguration">4. CruiseControl.NET Server Configuration &#8211; General</a><br />
<a href="#ccnettutprojectconfiguration">5. Structure of a &#8216;Project&#8217; Configuration File</a><br />
<a href="#ccnettutsourcecontrolblock">6. Source Control Block</a><br />
<a href="#ccnettuttriggerblock">7. Trigger Block</a><br />
<a href="#ccnettutlabellerblock">8. Labeller Block</a><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettuttasksblock">9. Tasks Block (part 2)</a><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutmsbuildtask">10. MsBuild Task (part 2)</a><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutreferencepath">10.1. MSBuild and ReferencePath &#8211; CruiseControl.NET not resolving reference to Nunit (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutrodemeyer">10.2. An Alternative MSBuild Logger &#8211; Christian Rodemeyer&#8217;s MsBuildToCCNet (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2#ccnettutwebdashboardimages">10.3. CruiseControl.NET Webdashboard fails in finding images if not installed in virtual directory (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2#ccnettutnumberofprojects">10.4. MSBuildToCCNET reports wrong number of compiled projects (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2#ccnettutassemblylinker">10.5. CruiseControl.NET, MsBuild Task and Resources &#8211; Assembly Linker (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2#ccnettutwebappprojects">10.6. CruiseControl.NET, MsBuild Task and Web Application projects (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutnunittask">11. Nunit Task (part 2)</a><br />
<span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutnunittask1">11.1. Nunit Task (part 2)</a></span><br />
<span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutnunittask2">11.2. Executable Task (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutpublishersblock">12. Publishers Block (part 2)</a><br />
<span style="background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutprebuildblock">13. PreBuild Block (part 2)</a><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2#ccnettutinstallnant">13.1. Install Nant (part 2)</a></span><br />
<span style="background-color:#ce9d84;"><span style="position:relative;left:10px;background-color:#ce9d84;"><a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2#ccnettutnantfundamentals">13.2. Nant Fundamentals (part 2)</a></span></span></p>
<h3><a title="ccnettutintro" name="ccnettutintro"></a><span style="font-size:small;color:#993300;">1. Introduction</span></h3>
<p>In this article series I will review the various steps needed to setup and configure a working CruiseControl.Net server.<br />
The goal is to set up a Continuous Integration process for a sample project as close as possible to a real-life project.<br />
I will point out several issues that might arise and I will provide solutions as well.<br />
I will try to underline all the details that you need to be aware of.</p>
<p>Thanks to Frank Geerlings for making me aware of a casing problem with the xml samples.<br />
By talking with WordPress support it came out that there was a little bug and they suggested me<br />
how to fix the problem.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a></p>
<h3><a title="ccnettutresources" name="ccnettutresources"></a><span style="font-size:small;color:#993300;">2. Resources</span></h3>
<p>During the article I will guide you through the installation process of the following software:</p>
<p><a title="Subversion" href="http://subversion.tigris.org/" target="_blank">Subversion</a><br />
<a title="CCNET" href="http://ccnet.thoughtworks.com" target="_blank"> CruiseControl.NET</a><br />
<a title="Nunit" href="http://www.nunit.org/index.php" target="_blank">Nunit</a></p>
<p><a title="Nant" href="http://nant.sourceforge.net/" target="_blank">Nant</a><br />
<a title="Fxcop" href="http://blogs.msdn.com/fxcop/" target="_blank">FxCop</a><br />
<a title="nantcontrib" href="http://nantcontrib.sourceforge.net/" target="_blank">NantContrib</a></p>
<p>The following are optional:</p>
<p><a title="TortoiseSVN" href="http://tortoisesvn.tigris.org/" target="_blank">TortoiseSVN</a><br />
<a title="AnkhSVN" href="http://ankhsvn.open.collab.net/" target="_blank">AnkhSVN</a></p>
<p>You can find information about how to install: <a title="Subversion" href="http://subversion.tigris.org/" target="_blank">Subversion</a>, <a title="TortoiseSVN" href="http://tortoisesvn.tigris.org/" target="_blank">TortoiseSVN</a> and <a title="AnkhSVN" href="http://ankhsvn.open.collab.net/" target="_blank">AnkhSVN</a> in the article: <a title="subversion tutorial" href="http://ilmatte.wordpress.com/2008/04/27/guide-to-versioning-a-visual-studio-solution-with-subversion-tortoisesvn-and-ankhsvn/" target="_blank">Guide to Versioning a Visual Studio Solution with Subversion, TortoiseSVN and AnkhSVN</a>.<br />
There you can also find a quick guide about how to create a Subversion repository and how to add a Visual Studio solution to source control.</p>
<p>This tutorial assumes that you have Subversion 1.4.6 installed and that you have configured a Subversion repository at the url: <span style="color:#808080;">svn://localhost/trunk</span> as shown in the article: <a title="subversion tutorial" href="http://ilmatte.wordpress.com/2008/04/27/guide-to-versioning-a-visual-studio-solution-with-subversion-tortoisesvn-and-ankhsvn/" target="_blank">Guide to Versioning a Visual Studio Solution with Subversion, TortoiseSVN and AnkhSVN</a>.</p>
<p>If you already have a working environment with a repository and versioned files, you can go on reading and replace the paths and names in the examples with the paths and names in your environment.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutresources"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutinstallation" name="ccnettutinstallation"></a><span style="font-size:small;color:#993300;">3. Installation</span></h3>
<ul>
<li><a href="#ccnettutinstallccnet">3.1. Install CruiseControl.NET</a></li>
<li><a href="#ccnettutiiscreatesite">3.2. Create a CCNet Website in IIS</a></li>
<li><a href="#ccnettutinstallnunit">3.3. Install Nunit</a></li>
</ul>
<p>This tutorial will assume that you install CruiseControl.NET on the same machine on which you had installed the Subversion repository. So, first of all, let&#8217;s go through the steps needed to install CruiseControl.NET on your server machine.</p>
<h4><a title="ccnettutinstallccnet" name="ccnettutinstallccnet"></a><span style="font-size:x-small;color:#993300;">3.1. Install CruiseControl.NET</span></h4>
<p>Download the latest <a title="CCNET" href="http://ccnet.thoughtworks.com" target="_blank">CruiseControl.NET</a> release from: <a title="ccnet download" href="http://sourceforge.net/project/showfiles.php?group_id=71179&#38;package_id=83198" target="_blank">SourceForge</a> or the latest build from <a title="ccnet last build" href="http://ccnetlive.thoughtworks.com/CCNet-builds/" target="_blank">CCNetLive</a>.<br />
You can find release notes <a title="ccnet release notes" href="http://confluence.public.thoughtworks.org/display/CCNET/Download" target="_blank">here</a>. For this article I used the installer for version 1.4 (CruiseControl.NET-1.4-Setup.exe), downloaded from the CCNetLive website.</p>
<p>Run the setup executable file and, when prompted, you must specify your choices for a couple of actions:<br />
<span style="color:#808080;">&#8216;Install CC.Net server as windows service&#8217;</span> must be checked so that the setup will install CruiseControl as a Windows service.<br />
In the Services management console the CruiseControl service will be displayed with the name: <em>CruiseControl.NET</em>.<br />
<span style="color:#808080;">&#8216;Create virtual directory in IIS for Web dashboard&#8217;</span> will create a virtual directory named <em>ccnet</em> in the machine&#8217;s IIS web server. If you have an IIS server installation supporting multiple web sites (this is not the case for Windows XP Professional) and prefer to have a separate web site for the CCNet web dashboard you should uncheck this option. This is my choice. In the next paragraph I will show you how to create an IIS web site for the CruiseControl.NET web dashboard.</p>
<p>When the install process is finished all the content will be installed in the folder:<br />
<span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET</span> (e.g. <span style="color:#808080;">C:\Program Files\CruiseControl.NET</span>).<br />
Under this path you will find a directory called <em>server</em>, containing all the CCNet binary files and executables, and a directory called <em>webdashboard</em>, containing the CruiseControl.NET web interface.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutinstallation"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h4><a title="ccnettutiiscreatesite" name="ccnettutiiscreatesite"></a><span style="font-size:x-small;color:#993300;">3.2. Create a CCNet Website in IIS</span></h4>
<p>Here I will add and configure a Website in IIS for the CruiseControl.NET Webdashboard: the administrative interface of CruiseControl.NET.<br />
Open <strong>IIS Manager</strong> in <strong>Administrative Tools</strong>, right-click on the <strong>Web Sites</strong> node and select <strong>New Web Site</strong>.<br />
The Web site creation wizard will start.<br />
Click Next and you will be prompted for a Web Site Description.<br />
Type CCNet and click Next, leave Unassigned the IPAddress, choose a port number (say: 222) and leave empty the &#8216;Host Header for this site&#8217; field, then click Next.<br />
Choose <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\webdashboard</span> as the path for the Website and click Next.<br />
Allow &#8216;Read&#8217; and &#8216;Run scripts&#8217;, the default, and click Next. The wizard is finished and the new Website created.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutiiscreatesite"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h4><a title="ccnettutinstallnunit" name="ccnettutinstallnunit"></a><span style="font-size:x-small;color:#993300;">3.3. Install Nunit</span></h4>
<p>For the sake of our example we will need <strong>Nunit</strong> so, if you haven&#8217;t already done, install it on the same machine on which you have installed CruiseControl.NET.</p>
<p>You can find the latest <a title="nunit home" href="http://www.nunit.org/" target="_blank">Nunit</a> release <a title="nunit download" href="http://sourceforge.net/project/showfiles.php?group_id=10749&#38;package_id=89482" target="_blank">here</a> at SourceForge.<br />
This article is based on the release 2.4.6, currently the latest. You can install it by downloading: <a title="nunit 2.4.6 msi" href="http://prdownloads.sourceforge.net/nunit/NUnit-2.4.6-net-2.0.msi?download" target="_blank">NUnit-2.4.6-net-2.0.msi</a>.</p>
<p>After the installation you will have a new directory under <em>%ProgramFiles% </em>: <span style="color:#808080;">C:\%ProgramFiles%\NUnit 2.4.6</span>.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutinstallnunit"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutconfiguration" name="ccnettutconfiguration"></a><span style="font-size:small;color:#993300;">4. CruiseControl.NET Server Configuration &#8211; General</span></h3>
<p>All the configuration files we&#8217;re going to talk about are placed or are to be placed in:<br />
<span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\server</span>.</p>
<p>CruiseControl.NET comes with two server executables: <strong>ccservice.exe</strong> which is the windows service installed by the installation setup and <strong>ccnet.exe</strong> which is a console application included for testing purposes.<br />
It is much easier to debug a console application that a service so I strongly suggest to make your initial tests with ccnet.exe and carefully read the console output to get familiar with CCNet behavior.</p>
<p>Each of the two executables comes with a default configuration file (i.e.: <em>ccservice.exe.config</em> and <em>ccnet.exe.config</em>) that you don&#8217;t need to change at the moment.<br />
Moreover both the server processes (windows service or console application) look for a file named <strong>ccnet.config</strong> in which you will place all the actual information needed by CCNet to learn what it is supposed to do and how it is supposed to do it.</p>
<p><strong>ccnet.config</strong> is an xml file with a root element named <strong>&#60;cruisecontrol&#62;</strong> and a child element, named <strong>&#60;project&#62;</strong>, for each set of activities that we want CruiseControl.NET to execute, as shown in the following example:</p>
<pre class="brush: xml;">
&lt;cruisecontrol&gt;
&lt;project name=&quot;project1&quot;&gt;
    ...
  &lt;/project&gt;
&lt;project name=&quot;project2&quot;&gt;
    ...
  &lt;/project&gt;
&lt;/cruisecontrol&gt;
</pre>
<p>In this tutorial we will setup our CruiseControl.NET configuration with two logical sets of activities.<br />
For the sake of clarity we will benefit of the usage of xml entities.<br />
We&#8217;ll define each &#8216;project&#8217; configuration in a separate file and import all the files in &#8216;ccnet.config&#8217; by means of entity definitions and entity declarations:</p>
<pre class="brush: xml;">
&lt; !DOCTYPE cruisecontrol [
	&lt; !ENTITY project1 SYSTEM &quot;file:project1.xml.config&quot;&gt;
	&lt; !ENTITY project2 SYSTEM &quot;file:project2.xml.config&quot;&gt;
]&gt;
&lt;cruisecontrol&gt;
  &amp;project1;
  &amp;project2;
&lt;/cruisecontrol&gt;
</pre>
<p>Let&#8217;s focus, at first, only on the first project, so delete the second entity reference (i.e.: &#38;project2; ) thus obtaining:</p>
<pre class="brush: xml;">
&lt; !DOCTYPE cruisecontrol [
	&lt; !ENTITY project1 SYSTEM &quot;file:project1.xml.config&quot;&gt;
	&lt; !ENTITY project2 SYSTEM &quot;file:project2.xml.config&quot;&gt;
]&gt;
&lt;cruisecontrol&gt;
  &amp;project1;
&lt;/cruisecontrol&gt;
</pre>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutconfiguration"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutprojectconfiguration" name="ccnettutprojectconfiguration"></a><span style="font-size:small;color:#993300;">5. Structure of a &#8216;Project&#8217; Configuration File</span></h3>
<p>What we need to do now is creating a file named: <strong>project1.xml.config</strong> in <span style="color:#808080;">C:\%ProgramFiles%\CruiseControl.NET\server</span><br />
and use it to setup CruiseControl.NET main activities.<br />
This file will contain what is called the &#8216;Project Configuration Block&#8217; for the first CCNet activity that we want to configure.<br />
First of all we need to assign a unique name to the root of the Project Configuration Block: the <strong>&#60;project&#62;</strong> tag.  We then write:</p>
<pre class="brush: xml;">
&lt;project name=&quot;1 - testProject&quot;&gt;
  &lt;webURL&gt;http://192.168.15.2:222&lt;/weburl&gt;
  &lt;workingDirectory&gt;C:\develop\CCnet\project1WorkingDir
  &lt;/workingDirectory&gt;
  &lt;artifactDirectory&gt;C:\develop\CCnet\project1CCnetArtifacts
  &lt;/artifactDirectory&gt;
  ...
&lt;/project&gt;
</pre>
<p>Let&#8217;s talk about the first three children nodes:</p>
<p><strong></strong> represents the URL at which the current project is available through the web interface. We will see later why it is useful.<br />
For now just make sure to set it to the IP of the server machine (in which you installed CCNet) and to the port that you chose for the WebDashboard website when you configured the web site in IIS (see: <a href="#ccnettutiiscreatesite">3.2. Create a CCNet Website in IIS</a>).</p>
<p><strong></strong> is the path to the main directory of this project and is meant to contain the checked out version of the project under integration<span style="color:#ff8433;">.</span><br />
This path will be accessible as an environment variable: <span style="color:#ff6600;">%CCNetWorkingDirectory%</span>, available to external scripts (we will see it later).<br />
I use to place all the projects managed with CCNET in folders under a common directory named: <span style="color:#808080;">C:\develop\CCnet</span>.<br />
For this test project I chose: <span style="color:#808080;">C:\develop\CCnet\project1WorkingDir</span>.</p>
<p>It is convenient to choose a directory in which to place all the stuff that will be used by CCNet (script files or executable files that you may want CruiseControl.NET to execute) as well as the <em>workingDirectory</em> in which CCNET will checkout the versioned files and the <em>artifactDirectory</em> in which it will output log files.<br />
In the example above I chose the directory: <span style="color:#808080;">C:\develop\CCnet</span> as the container of all CCNet related stuff.</p>
<p><strong></strong> is the path to the directory where all the build logs for this project will be placed.</p>
<p>Apart from the three tags described above, the main blocks that we&#8217;re going to add to the project configuration file are:</p>
<ul>
<li> <a href="#ccnettutsourcecontrolblock">Source Control Block</a></li>
<li> <a href="#ccnettuttriggerblock">Trigger Block</a></li>
<li> <a href="#ccnettutlabellerblock">Labeller Block</a></li>
<li> <a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettuttasksblock">9. Tasks Block</a></li>
<li> <a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutprebuildblock">13. PreBuild Block</a></li>
<li> <a href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/#ccnettutpublishersblock">12. Publishers Block</a></li>
</ul>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutprojectconfiguration"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutsourcecontrolblock" name="ccnettutsourcecontrolblock"></a><span style="font-size:small;color:#993300;">6. Source Control Block</span></h3>
<p>Source Control configuration block tells CruiseControl.NET that the project named &#8216;1 &#8211; testProject&#8217; is bound to a Subversion repository.<br />
This means that the task performed when executing this project depends on the status of that particular Subversion repository.<br />
As soon as CruiseControl.NET detects a new revision in the repository it updates its working copy and executes the tasks related to the current project.<br />
Here is the xml excerpt:</p>
<pre class="brush: xml;">
&lt;sourcecontrol type=&quot;svn&quot;&gt;
&lt;trunkUrl&gt;svn://localhost/trunk&lt;/trunkUrl&gt;
  &lt;workingDirectory&gt;C:\develop\CCnet\project1WorkingDir
  &lt;/workingDirectory&gt;
  &lt;username&gt;ccnet &lt;/username&gt;
&lt;password&gt; ccnet &lt;/password&gt;
&lt;/sourcecontrol&gt;
</pre>
<p><strong></strong> contains the url of the repository that we want to check for modifications (e.g., <span style="color:#808080;">svn://svnserver/pathToRepo</span>).<br />
As we saw in the post <a title="subversion tutorial" href="http://ilmatte.wordpress.com/2008/04/27/guide-to-versioning-a-visual-studio-solution-with-subversion-tortoisesvn-and-ankhsvn/" target="_blank">Guide to Versioning a Visual Studio Solution with Subversion, TortoiseSVN and AnkhSVN</a>, Subversion could host several repositories under a common folder, say: <span style="color:#808080;">C:\develop\TestRepo</span>.<br />
But in that article, as well as in the current example, we set up only one repository and run svnserve with the command line: <strong>svnserve -d -r &#8220;C:\develop\test\repo&#8221;</strong>.<br />
So, specifying the server name (<em>localhost</em>) and the path to the particular repository we&#8217;re interested in, turns out to be simply: <span style="color:#808080;">svn://localhost/trunk</span> (instead of: <span style="color:#808080;">svn://localhost/SpecificRepositoryFolder/trunk</span>);<br />
<strong></strong> is the directory that will contain the working copy checked out by CCNET;<br />
<strong></strong> sets the timeout for the source control operation. It defaults to 10 minutes and you can set it to a different amount of time in milliseconds (default) or specifying units (&#8220;millis&#8221;, &#8220;seconds&#8221;, &#8220;minutes&#8221;, &#8220;hours&#8221;); I left it out thus accepting the default.<br />
If you want to set it to a different value remember to <strong><span style="text-decoration:underline;">not</span> choose a too short timeout value</strong> because if the timeout is exceeded the build will fail without providing information about the reason.<br />
In that case the only way you can retrieve the actual reason of the build failing is by analyzing CCNET log file in the <span style="color:#808080;">CruiseControl.NET\server</span> folder (if you set log4net to the debug log level)<br />
<strong></strong> and <strong></strong> must be set to a valid svn account that CCNET can use to access Subversion repository.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutsourcecontrolblock"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettuttriggerblock" name="ccnettuttriggerblock"></a><span style="font-size:small;color:#993300;">7. Trigger Block</span></h3>
<p>A trigger block is needed to specify when CruiseControl.NET will start a new integration cycle.<br />
We want to check for the repository status continuously so we need an &#8216;Interval Trigger&#8217; to tell CruiseControl.NET to perform integration periodically after a specified amount of time:</p>
<pre class="brush: xml;">
&lt;triggers&gt;
  &lt;intervalTrigger name=&quot;Subversion&quot; seconds=&quot;10&quot; /&gt;
&lt;/triggers&gt;
</pre>
<p>CruiseControl.NET, as far as project &#8216;1 &#8211; TestProject&#8217; is concerned, polls the repository every 10 seconds to see if any changes has been committed.<br />
The <span style="color:#ff9900;"><em>name</em> </span>attribute is used by CruiseControl.NET GUI to identify the trigger that requested the build;<br />
The <span style="color:#ff9900;"><em>seconds</em> </span>attribute is the amount of time before triggering the next integration cycle.</p>
<p>Each time the time interval elapses, CCNET checks for modifications and, by default, runs integration only if changes are detected.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettuttriggerblock"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<h3><a title="ccnettutlabellerblock" name="ccnettutlabellerblock"></a><span style="font-size:small;color:#993300;">8. Labeller Block</span></h3>
<p>A label is created, at each integration cycle, to identify the specific build occurred.<br />
Different labellers can be used to generate the label that CCNet will use to track the builds.</p>
<p>Other than the <em>Labeller Blocks</em> that come with the CruiseControl.NET distribution, many people provided plugin <em>Labeller Blocks</em> to target the generation of labels with specific formats.</p>
<p>A very good one, IMHO, is SvnRevisionLabeller by David Keaveny (much important to me because I recently contributed to the project).<br />
This plugin allows labelling CruiseControl.NET builds with Subversion&#8217;s repository revision numbers and I think this is a really useful feature.<br />
So this example will use SvnRevisionLabeller as the Labeller Block.<br />
For detailed information about this plugin see my post: <a title="svn revision labeller" href="http://ilmatte.wordpress.com/2008/03/05/cruisecontrolnet-and-subversion-svnrevisionlabeller/" target="_blank">CruiseControl.NET and Subversion &#8211; SvnRevisionLabeller</a>.</p>
<p>To use the SvnRevisionLabeller plugin in your installation of CruiseControl.NET you need to unzip the downloaded package and copy the assembly: <strong>ccnet.SvnRevisionLabeller.plugin.dll</strong> in the <em>server</em> folder directory under the CruiseControl.NET install path (e.g.: &#8216;C:\Program Files\CruiseControl.NET\server&#8217;).</p>
<p>Next you need to configure the <strong>Labeller Block</strong> in your project:</p>
<pre class="brush: xml;">
&lt;labeller type=&quot;svnRevisionLabeller&quot;&gt;
	&lt;major&gt;7&lt;/major&gt;
	&lt;minor&gt;11&lt;/minor&gt;
	&lt;url&gt;svn://localhost/trunk&lt;/url&gt;
&lt;/labeller&gt;
</pre>
<p>SvnRevisionLabeller will produce build labels in the format:</p>
<p><strong>major.minor.svnRevision.build</strong></p>
<p>where <strong>major</strong> and <strong>minor</strong> are the two values you set in the configuration block while <strong>svnRevision</strong> is the current version in the Subversion&#8217;s repository related to this project.<br />
The <strong>build</strong> number is automatically incremented each time a new build is forced if no further modification has been committed to the repository.</p>
<p><strong>&#60;url&#62;</strong> is the path to the repository used to retrieve the revision number (e.g. <span style="color:#808080;">svn://svnserver/pathToRepo/trunk</span>). Actually it should be filled with the same path used in the <strong>&#60;trunkUrl&#62;</strong> field of the Subversion <strong>Source Control Block</strong>.<br />
In our example it is:</p>
<pre class="brush: xml;">
&lt;url&gt;svn://localhost/trunk&lt;/url&gt;
</pre>
<p>Following is a configuration for <strong>SvnRevisionLabeller</strong> with the complete set of fields:</p>
<pre class="brush: xml;">
&lt;labeller type=&quot;svnRevisionLabeller&quot;&gt;
&lt;prefix&gt;Test-&lt;/prefix&gt;
  &lt;major&gt;7&lt;/major&gt;
  &lt;minor&gt;11&lt;/minor&gt;
  &lt;url&gt;svn://localhost/trunk&lt;/url&gt;
  &lt;username&gt;ccnet&lt;/username&gt;
&lt;password&gt;ccnet&lt;/password&gt;
&lt;/labeller&gt;
</pre>
<p>Such a configuration will produce a label with the following format: <strong>Test-major.minor.svnRevision.build</strong>.<br />
<strong>&#60;username&#62;</strong> and <strong>&#60;password&#62;</strong> are the username and password of a valid Subversion account for the repository specified in the <strong>&#60;url&#62;</strong> field.</p>
<p>You can use in an external script the build label produced, which is stored in an environment variable.<br />
It can be useful to flag release version of output dlls.<br />
You can access the build number from a script with the syntax: <span style="color:#ff6600;">%CCNetLabel%</span> or from a C# application with the following row:</p>
<pre class="brush: csharp;">
Environment.GetEnvironmentVariable(&quot;ccnetlabel&quot;);
</pre>
<p>If you used the SolutionInfo approach in your Visual Studio solution (see my post: <a title="solutioninfo" href="http://ilmatte.wordpress.com/2008/02/10/solutioninfo-and-partitioned-single-solution/#introductionsolutioninfo1" target="_blank">SolutionInfo and Partitioned Single Solution</a>) you can use the build label produced by <strong>SvnRevisionLabeller</strong> to update the <strong>AssemblyFileVersion</strong> attribute in the SolutionInfo.cs file.<br />
In this way you can provide consistent versioning of the released assemblies together with easy trackability of the corresponding source code&#8217;s revision.</p>
<p>Be careful not to use the &#60;prefix&#62; tag in this case because you need to set <strong>AssemblyFileVersion</strong> to a string in the format:<br />
<strong>major.minor.svnRevision.build</strong><br />
with all of the 4 fields being numerical values.</p>
<p><a href="#ccnettut1top"><span style="font-size:80%;color:red;">→ top of post</span></a><br />
<a href="#ccnettutlabellerblock"><span style="font-size:80%;color:red;">→ top of paragraph</span></a></p>
<p><span style="position:relative;left:50px;"><a title="tutorial part 2" href="http://ilmatte.wordpress.com/2008/06/15/cruisecontrolnet-tutorial-part-2/" target="_self">CruiseControl.Net Tutorial &#8211; Part 2 &#62;&#62;</a></span></p>
<p><a href="#ccnettutlabellerblock"></a><br />
<a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2filmatte.wordpress.com%2f2008%2f06%2f01%2fcruisecontrolnet-tutorial-part-1%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2filmatte.wordpress.com%2f2008%2f06%2f01%2fcruisecontrolnet-tutorial-part-1%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Build Automation System using Cruise Control .NET (CCNET)]]></title>
<link>http://sushantp.wordpress.com/2008/04/30/build-automation-system-using-cruise-control-net-ccnet/</link>
<pubDate>Wed, 30 Apr 2008 06:49:23 +0000</pubDate>
<dc:creator>sushantp</dc:creator>
<guid>http://sushantp.wordpress.com/2008/04/30/build-automation-system-using-cruise-control-net-ccnet/</guid>
<description><![CDATA[In a Team development environment where parallel development and testing goes we find a requirement ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div>In a Team development environment where parallel development and testing goes we find a requirement of getting most recent build to test as well as some specific build to give the QA to do testing on. This post describes what all are needed to set up an automated source code integration and build system for an environment where we use Visual Studio for development, Some source control (VSS, Vault Gear etc) for source depot.</div>
<p>Why do we need a continuous source code integration and build system? well, this helps the QA team by allowing then to not spend more time in syncing the source and doing a build everytime or even working on a relatively older build. This works as a perfect backup for your Source Control and also your deployment server build. This also allows to align the builds numbers to be same as your assembly\file version and also to the source control label there by making a particular build to be a complete unit in itself in terms of readiness for deployment or using the same for development.</p>
<p>Now coming back to build server where we can use cruise control .NET for source integration along with a couple of batch scripts to control the build number and assembly version. CCNET pings the source control (VSS or Vault etc) after every 30 mins (this is a default value and can be changed) to see if there are any modifications. If there are then it triggers a build and publishes it on the Build Server. Once done sleeps again for 30 mins unless it is Forced for a build in between i.e. you can manually force a build in between sleeps.</p>
<p>Let me explain the two components of build server in details below:</p>
<p>1) <strong>Cruise Control .NET:</strong><br />
Its an open source build and integration engine which can be downloaded freely from <a href="http://confluence.public.thoughtworks.org/display/CCNET/Download" target="_blank">http://confluence.public.thoughtworks.org/display/CCNET/Download</a>Once installation is done CCNET (CruiseControl.NET) needs to be configured according to your requirements. the config file can be found at &#8220;%SYSTEMDRIVE%\Program Files\CruiseControl.NET\Server\ccnet.config&#8221;.<br />
A Sample configuration looks like below (using Sample Project and Source Gear Vault as source control provider):</p>
<p><a href="http://bp2.blogger.com/_mDuWqJiJyXE/SBgTP1yBRbI/AAAAAAAAAS8/POojVaHoK_I/s1600-h/Code1.jpg"><img style="cursor:hand;" src="http://bp2.blogger.com/_mDuWqJiJyXE/SBgTP1yBRbI/AAAAAAAAAS8/POojVaHoK_I/s320/Code1.jpg" border="0" alt="" /></a><br />
<a href="http://bp3.blogger.com/_mDuWqJiJyXE/SBgTQFyBRcI/AAAAAAAAATE/XPa5EEK9EA4/s1600-h/Code2.jpg"><img style="cursor:hand;" src="http://bp3.blogger.com/_mDuWqJiJyXE/SBgTQFyBRcI/AAAAAAAAATE/XPa5EEK9EA4/s320/Code2.jpg" border="0" alt="" /></a></p>
<p>2) <strong>Batch Scripts (Same Build and Assembly Version)</strong>:<br />
There are two batch scripts used to control the assembly version. For any executable or dll assembly version is generated based on AssemblyVersion attribute defined in AsseblyInfo.cs file. In order to have same Label and assembly version we can use batch script to change the attribute at runtime and then revert the same at the end of build process again during runtime.</p>
<p>Once the source integration is done by CCNET and is ready for build we change the file attributes of AssemblyInfo files (more in case of multi project solution) to -R so that AssemblyVersion attribute can be changed to build label thereby making the version of generated dll&#8217;s and exe&#8217;s with the same version. Now to revert back we use another script which changes the AssemblyVersion attribute back to 1.0.0.0 and change the file attribute back to +R there by dodging the source control to not treat this as a modification otherwise it will consider this as a modification and trigger the build again and go to an infinite loop of build <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>For mutli project systems where you need many assemblyinfo files to be changed you can use some utilities like replace.exe <a href="http://www.bestcode.com/assets/downloads/replace/replace.exe">http://www.bestcode.com/assets/downloads/replace/replace.exe</a><br />
Below is an example of how a batch script would look like:<br />
#Test1.bat<br />
attrib /S -R AssemblyInfo.cs replace.exe -find &#8220;1.0.0.0&#8243; -replace &#8220;%CCNetLabel%&#8221; -fname AssemblyInfo.cs</p>
<p>Complete reference on the configuration blocks can be found at <a href="http://ccnet.sourceforge.net/CCNET/" target="_blank">http://ccnet.sourceforge.net/CCNET/</a> One of the useful publisher which is missing in the above config is Email publisher where-in you can send mails for build success\failure to single\set of people. This help in tracking the build failures and also QA team notification in case of build succeeds.</p>
<p>This can very well be integrated with NUnit for executing test cases ones the build succeeds. This post doesnt cover this though more information on this can be found at CCNET link provided above.</p>
<p>There is a UI support too for CCNET to control the build trigger and view build results\logs. it can be found at <a href="http://[BuildServer]/ccnet">http://[BuildServer]/ccnet</a> . The web dashboard for ccnet looks like:</p>
<p><a href="http://bp2.blogger.com/_mDuWqJiJyXE/SBgBo1yBRaI/AAAAAAAAAS0/wIxzY8ElgcM/s1600-h/CCNET.png"><img style="cursor:hand;" src="http://bp2.blogger.com/_mDuWqJiJyXE/SBgBo1yBRaI/AAAAAAAAAS0/wIxzY8ElgcM/s320/CCNET.png" border="0" alt="" /></a></p>
<p>Hope this post will help in case you are planning to set up an automated build and integration system or you are looking for a solution to have same build and assembly version for you current systems builds.</p>
<p>bye for now.</p>
<p><a href="http://www.blogged.com"><br />
<img src="http://www.blogged.com/icons/vn_sushantp_1014976.gif" border="0" alt="Blog Directory - Blogged" /></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Continuous Integration with VS 2008]]></title>
<link>http://brightsparc.wordpress.com/2008/04/22/continuous-integration-with-vs-2008/</link>
<pubDate>Tue, 22 Apr 2008 09:30:43 +0000</pubDate>
<dc:creator>brightsparc</dc:creator>
<guid>http://brightsparc.wordpress.com/2008/04/22/continuous-integration-with-vs-2008/</guid>
<description><![CDATA[TFS 2008 introduced Team Build which enables continuous integration.  But if you come from a traditi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>TFS 2008 introduced <a href="http://blogs.msdn.com/buckh/archive/2007/08/14/tfs-2008-a-basic-guide-to-team-build-2008.aspx">Team Build</a> which enables continuous integration.  But if you come from a traditional SVN/CruiseControl background, you will be please to know that there is also a <a href="http://confluence.public.thoughtworks.org/x/zRE">CC.NET plugin</a> available.</p>
<p>And with preview release of the <a href="http://blogs.iis.net/thomad/archive/2008/04/14/iis-7-0-powershell-provider-tech-preview-1.aspx">powershell provider</a> for IIS 7, it is possible to easily creating the websites, setting permissions etc without the scripting pain of the past.</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
