<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Development Blog &#187; CruiseControl.NET</title>
	<atom:link href="http://blog.yeticode.co.uk/tag/cruisecontrolnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.yeticode.co.uk</link>
	<description>John Tindell's Blog For Development Related Things</description>
	<lastBuildDate>Wed, 23 Jun 2010 18:17:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>NAnt.ToDo a NAnt Plugin</title>
		<link>http://blog.yeticode.co.uk/2010/01/nant-todo-a-nant-plugin/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=nant-todo-a-nant-plugin</link>
		<comments>http://blog.yeticode.co.uk/2010/01/nant-todo-a-nant-plugin/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 19:02:25 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development Log]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CruiseControl.NET]]></category>
		<category><![CDATA[NAnt]]></category>

		<guid isPermaLink="false">http://blog.yeticode.co.uk/?p=611</guid>
		<description><![CDATA[This simple plugin for NAnt parses your source code and creates a report of all the TODO and comment tags in your source code. The code is hosted over at google code. Comments The task automatically identify comments in the following style //TODO: First Test to do Item //FIXME: First Fix me Item //HACK: First [...]]]></description>
			<content:encoded><![CDATA[<p>This simple plugin for NAnt parses your source code and creates a report of all the TODO and comment tags in your source code. The code is hosted over at <a href="http://code.google.com/p/nant-todo/">google code</a>.</p>
<h2>Comments</h2>
<p>The task automatically identify comments in the following style</p>
<pre name="code" class="c-sharp">
//TODO: First Test to do Item
//FIXME: First Fix me Item
//HACK: First Hack Item
</pre>
<p>Additional matches can be made by adding in Token elements to the NAnt task. </p>
<h2>Sample</h2>
<pre name="code" class="xml">
&lt;ToDo source="path/to/source" output="report.xml" searchpattern="*.cs;*.txt"&gt;
 &lt;Tokens&gt;
 &lt;Tokens Value="BUGFIX" /&gt;
 &lt;/Tokens&gt;
&lt;/ToDo&gt;
</pre>
<h2>Output</h2>
<pre name="code" class="xml">
&lt;ToDo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
 &lt;Items&gt;
 &lt;Item&gt;
 &lt;Message&gt;First Test to do Item&lt;/Message&gt;
 &lt;File&gt;NAnt.ToDo\ToDoTask.cs&lt;/File&gt;
 &lt;Line&gt;0&lt;/Line&gt;
 &lt;Type&gt;TODO&lt;/Type&gt;
 &lt;/Item&gt;
 &lt;Item&gt;
 &lt;Message&gt;First Hack Item&lt;/Message&gt;
 &lt;File&gt;NAnt.ToDo\ToDoTask.cs&lt;/File&gt;
 &lt;Line&gt;0&lt;/Line&gt;
 &lt;Type&gt;HACK&lt;/Type&gt;
 &lt;/Item&gt;
 &lt;Item&gt;
 &lt;Message&gt;First Fix me Item&lt;/Message&gt;
 &lt;File&gt;NAnt.ToDo\ToDoTask.cs&lt;/File&gt;
 &lt;Line&gt;0&lt;/Line&gt;
 &lt;Type&gt;FIXME&lt;/Type&gt;
 &lt;/Item&gt;
 &lt;/Items&gt;
&lt;/ToDo&gt;
</pre>
<h2>Cruise Control Xsl</h2>
<p>Below is a basic xsl style sheet that can be used with CruiseControl.NET to display the output from NAnt.ToDo.</p>
<pre name="code" class="xml">
&lt;?xml version="1.0"?&gt;
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
 &lt;xsl:output method="html"/&gt;
 &lt;xsl:param name="applicationPath"/&gt;
 &lt;xsl:template match="/"&gt;
 &lt;div id="ToDo"&gt;
 &lt;h1&gt;ToDo List&lt;/h1&gt;
 &lt;div id="Summary"&gt;
 &lt;h3&gt;To Do&lt;/h3&gt;
 &lt;table&gt;
 &lt;tbody&gt;
 &lt;xsl:for-each select="//ToDo/Items/Item"&gt;
 &lt;tr&gt;
 &lt;td&gt;
 &lt;xsl:value-of select="Type/text()"/&gt;
 &lt;/td&gt;
 &lt;td&gt;
 &lt;xsl:value-of select="Message/text()"/&gt;
 &lt;/td&gt;
 &lt;td&gt;
 &lt;xsl:value-of select="File/text()"/&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;/xsl:for-each&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
 &lt;/div&gt;    
 &lt;/div&gt;
 &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.yeticode.co.uk/2010/01/nant-todo-a-nant-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jqRunner Snapshot &#8211; Running Javascript Unit test with NUnit</title>
		<link>http://blog.yeticode.co.uk/2009/09/jqrunner-snapshot-running-javascript-unit-test-with-nunit/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=jqrunner-snapshot-running-javascript-unit-test-with-nunit</link>
		<comments>http://blog.yeticode.co.uk/2009/09/jqrunner-snapshot-running-javascript-unit-test-with-nunit/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 21:06:47 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development Log]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CruiseControl.NET]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqunit]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://blog.yeticode.co.uk/?p=592</guid>
		<description><![CDATA[One of the nice things about unit tests is that you can use continuous integration so that you don&#8217;t have to run them yourself. At work we use CruiseControl.NET to automate our builds and run our unit tests. Now as a number of our projects are web based we use a fair amount of javascript, [...]]]></description>
			<content:encoded><![CDATA[<p>One of the nice things about unit tests is that you can use continuous integration so that you don&#8217;t have to run them yourself. At work we use <a href="http://ccnet.thoughtworks.com">CruiseControl.NET</a> to automate our builds and run our unit tests. Now as a number of our projects are web based we use a fair amount of javascript, mainly jQuery, though in-house plugins. In order to test these we use <a href="http://code.google.com/p/jqunit/">jqunit</a>, this works great and allows us to use TDD when writing javascript. However as development goes on the unit tests get forgotten about as they are not automatically ran.</p>
<p>In order so solve this I decided to experiment to find a method of getting cruise control to run our jqunit tests for me. To run the tests I looked at wrapping the jqunit tests with nunit tests.</p>
<p><a href="http://static.yeticode.co.uk/blog/images/posts/jqRunner_nunit.png" rel="lightbox"><img src="http://static.yeticode.co.uk/blog/images/posts/jqRunner_nunit_thumb.png" alt="jqRunner"/></a></p>
<p>jqRunner is designed so that you can us your existing jqunit tests in their existing location without changing them. jqRunner required that all the scripts that are needed to run are registered. The full path to the file is required. jqRunner then executes the tests and returns the results, which are then parsed by nunit as tests using the TestCaseSource attribute.</p>
<pre class="javascript" name="code">
var sampleTestCase = new jqUnit.TestCase('Sample Test Case', function() {
    /*setup*/
    // this.yep(1);
}, function() {
    /*teardown*/
    // this.ok(1)
});
sampleTestCase.test('Sample Test 1', function() {
    this.ok(1);
});
sampleTestCase.test('Sample Test 2', function() {
    this.ok(0);
});
</pre>
<pre class="c-sharp" name="code">
using System;
using System.Collections.Generic;
using NUnit.Framework;
using jqRunner;
using System.IO;
using System.Reflection;

namespace jqRunner.Tests
{
    [TestFixture,RequiresSTA]
    public class TestCaseSourceTests
    {
        [Test, TestCaseSource("GetTestResults"), RequiresSTA]
        public void CheckTest(ITestResult result)
        {
            Assert.IsTrue(result.Pass, result.Name);
        }

        private static ITestResult[] GetTestResults()
        {
            string jsFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase) + @"\jqUnitTests\SampleUnitTest.js";
            TestBed target = new TestBed();
            target.RegisterScript(jsFile);
            return target.Execute().ToArray();
        }
    }
}
</pre>
<p>This is an initial development snapshot and is bound to have plenty of problems.</p>
<p><b>Download</b><br />
<a href="http://static.yeticode.co.uk/blog/downloads/jqRunner-snapshot.zip">http://static.yeticode.co.uk/blog/downloads/jqRunner-snapshot.zip</a></p>
<h2>Related Reading</h2>
<table>
<tr>
<td>
<a href="http://www.amazon.co.uk/gp/product/0596007396?ie=UTF8&#038;tag=worldoverride-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0596007396"><img border="0" src="http://static.yeticode.co.uk/blog/images/nunit.jpg"></a><img src="http://www.assoc-amazon.co.uk/e/ir?t=worldoverride-21&#038;l=as2&#038;o=2&#038;a=0596007396" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</td>
<td>
<a style="display:inline-block;" href="http://www.amazon.co.uk/gp/product/0321228103?ie=UTF8&#038;tag=worldoverride-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0321228103"><img border="0" src="http://static.yeticode.co.uk/blog/images/open_source_dot_net.jpg"></a><img src="http://www.assoc-amazon.co.uk/e/ir?t=worldoverride-21&#038;l=as2&#038;o=2&#038;a=0321228103" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;display:inline-block;" />
</td>
</tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.yeticode.co.uk/2009/09/jqrunner-snapshot-running-javascript-unit-test-with-nunit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python and CCTray Again</title>
		<link>http://blog.yeticode.co.uk/2009/07/python-and-cctray-again/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=python-and-cctray-again</link>
		<comments>http://blog.yeticode.co.uk/2009/07/python-and-cctray-again/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 19:56:53 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development Log]]></category>
		<category><![CDATA[cctray]]></category>
		<category><![CDATA[CruiseControl.NET]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.yeticode.co.uk/?p=336</guid>
		<description><![CDATA[So after creating a python script that would use my tux droid to notify me when a build failed I decided to extend the script a little further. I decoupled it from the tux droid code and added in a status menu. It still requires that CruiseControl.NET has the webdashboard installed. This is my first [...]]]></description>
			<content:encoded><![CDATA[<p>So after creating a python script that would use my tux droid to notify me when a build failed I decided to extend the script a little further. I decoupled it from the tux droid code and added in a status menu. It still requires that CruiseControl.NET has the webdashboard installed. This is my first venture into using GTK with python, as well as threads.</p>
<p>One of the problems that I encountered when trying to use thread was that they were not behaving correctly. The Thread would appear to start however it would not run. This was easy to fix but adding the following line to initialize the threading.</p>
<pre name="code" class="python">
gtk.gdk.threads_init()
</pre>
<p> In addition to this the class that was running the thread not only had to inherit from the threading.Thread object but had to explicitly call the init on the threads base class</p>
<pre name="code" class="python">
class ccnetworker(threading.Thread):

	# init
	def __init__(self,xmlPath,pycctray):
		threading.Thread.__init__(self)
		self.xmlPath = xmlPath
		self.pycctray = pycctray
</pre>
<p>Below is a screen shot of the system tray menu, listing the projects that are available to be force built.</p>
<p><img src="http://static.yeticode.co.uk/blog/images/posts/pycctray_force_build_menu.png" alt="pycctray screenshot"/></p>
<pre>
# example usage
python pycctray.py <a href="http://localhost/ccnet/XmlServerReport.aspx" rel="nofollow">http://localhost/ccnet/XmlServerReport.aspx</a>
</pre>
<p>You can get the latest source from the bazaar repository</p>
<pre>
bzr branch <a href="http://bzr.yeticode.co.uk/pycctray" rel="nofollow">http://bzr.yeticode.co.uk/pycctray</a>
</pre>
<p>Alternatively you can download the source files on their own: <a href="http://static.yeticode.co.uk/blog/downloads/pycctray.tar.gz">pycctray.tar.gz</a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.yeticode.co.uk/2009/07/python-and-cctray-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tux Droid with Cruise Control .NET</title>
		<link>http://blog.yeticode.co.uk/2009/07/tux-droid-with-cruise-control-net/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tux-droid-with-cruise-control-net</link>
		<comments>http://blog.yeticode.co.uk/2009/07/tux-droid-with-cruise-control-net/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 08:25:34 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development Log]]></category>
		<category><![CDATA[CruiseControl.NET]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tux droid]]></category>

		<guid isPermaLink="false">http://blog.yeticode.co.uk/?p=303</guid>
		<description><![CDATA[So after having my tux droid for a while I decided to put it to good use, opposed to making it swear at my housemates, which no matter how entertaining it was did not seem very productive. I decided to write a small script that would notify me when a build from Cruise Control.NET failed, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://static.yeticode.co.uk/blog/images/posts/tux_droid.jpg" alt="Tux Droid" title="Tux Droid" style="float: left"/></p>
<p>So after having my <a href="http://www.tuxisalive.com/">tux droid</a> for a while I decided to put it to good use, opposed to making it swear at my housemates, which no matter how entertaining it was did not seem very productive.<br />
I decided to write a small script that would notify me when a build from <a href="http://ccnetlive.thoughtworks.com/">Cruise Control.NET</a> failed, or when a broken build has successfully been built. At the moment the tux droid speaks a simple message and flaps it wings a little.</p>
<p>The script uses the tux droid python API to make the noises and pulls down an Xml file, via CruiseControl.NET, using urllib and xml.dom, fairly simple stuff.</p>
<p>You can get a copy of the source, which might be more up-to-date, frm the bzr repository.</p>
<pre>
# bzr branch <a href="http://bzr.yeticode.co.uk/ccnet-tuxbot" rel="nofollow">http://bzr.yeticode.co.uk/ccnet-tuxbot</a>
</pre>
<p><br/></p>
<pre>
Usage:
# python ccnet.py <a href="http://localhost/ccnet/XmlServerReport.aspx" rel="nofollow">http://localhost/ccnet/XmlServerReport.aspx</a>
</pre>
<p><a href="http://static.yeticode.co.uk/blog/downloads/ccnet.py">download ccnet.py</a><br />
<b>Update 11-07-2009 12:00AM:</b> update notifcations in ccnet.py script.</p>
<pre name="code" class="python">
#!/usr/bin/python
import sys
import urllib
import time
from xml.dom import minidom
from tuxisalive.api import *

def main(xmlPath):
	# load the inital settings that we will use to compare against
	projects = []

	dom = minidom.parse(urllib.urlopen(xmlPath))
	for node in dom.getElementsByTagName('Project'):
		projects.append({
			'name': node.getAttribute('name'),
			'lastBuildStatus': node.getAttribute('lastBuildStatus'),
			'lastBuildTime': node.getAttribute('lastBuildTime')
		})

	# start a loop that will check for a build event every 10 seconds
	while True:
		try:
			dom = minidom.parse(urllib.urlopen(xmlPath))
			new_projects = []
			for node in dom.getElementsByTagName('Project'):
				new_projects.append({
					'name': node.getAttribute('name'),
					'lastBuildStatus': node.getAttribute('lastBuildStatus'),
					'lastBuildTime': node.getAttribute('lastBuildTime')
				})
				for project in new_projects:
					# check to see if the project is in the current list
					projectFound = False
					for p in projects:
						if p['name'] == project['name']:
							projectFound = True
							# check the status of the project against the old status
							# ignore if the old status is failed
							if (p['lastBuildStatus'] != 'Failure') and (project['lastBuildStatus'] == 'Failure'):
								display_message_fail(project)
							if (p['lastBuildStatus'] == 'Failure') and (project['lastBuildStatus'] == 'Success'):
								display_message_success(project)
							if (project['lastBuildStatus'] == 'Success') and (project['lastBuildTime']  != p['lastBuildTime'] ):
								display_message_success_build_again(project)

							# reset the project status
							p['lastBuildStatus'] = project['lastBuildStatus']
							p['lastBuildTime'] = project['lastBuildTime']
					if not projectFound:
						projects.append(project)
						display_message_newproject(project)
			time.sleep(10)
		except KeyboardInterrupt:
			# exit time
			break

def display_message_fail(project):
	msg = 'Someone has broken the %s build' % (project['name'])
	speakPhrase(msg)

def display_message_success(project):
	msg = '%s is now fixed' % (project['name'])
	speakPhrase(msg)

def display_message_new(project):
	msg = '%s has been added to cruise control' % (project['name'])
	speakPhrase(msg)

def display_message_success_build_again(project):
	msg = '%s has successfuly been built' % (project['name'])
	speakPhrase(msg)

def speakPhrase(msg):
	tux.mouth.open()

	tux.tts.setLocutor("Lucy")
	tux.tts.speak(msg.encode('utf-8'));
	print msg
	tux.flippers.on(4)

	tux.mouth.close()

def tuxConnect():
    """ Wait connected """
    tux.server.autoConnect(CLIENT_LEVEL_RESTRICTED, 'TuxPidgin', 'NONE')
    if tux.server.waitConnected(10.0):
        if tux.dongle.waitConnected(10.0):
            if tux.radio.waitConnected(10.0):
                return True
            else:
                print "radio not connected"
                return False
        else:
            print "radio not connected"
            return False
    else:
        print "server not connected"
        return False

def printUsage():
	print "ccnet.py [url]"
	print "\turl - Url of CruiseControl.NET"
	print "\t\t eg. <a href="http://localhost/ccnet/XmlServerReport.aspx" rel="nofollow">http://localhost/ccnet/XmlServerReport.aspx</a>"

if __name__ == "__main__":
	if len(sys.argv) == 2:

		tgp_ip = "127.0.0.1"
		tgp_port = 270
		tux = TuxAPI(tgp_ip, tgp_port)
		if not tuxConnect():
		    sys.exit(1)
		tux.tts.setEncoding("utf-8")

		speakPhrase("Starting Build Bot")
		main(sys.argv[1])
		speakPhrase("Stopping Build Bot")
		tux.server.disconnect()
		tux.destroy()
		sys.exit(0)
	else:
		printUsage()
</pre>
<p><iframe src="http://rcm-uk.amazon.co.uk/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=yetiblog-21&#038;o=2&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=0M5A6TN3AXP2JHJBWT02&#038;asins=B001Q7YIPE" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>]]></content:encoded>
			<wfw:commentRss>http://blog.yeticode.co.uk/2009/07/tux-droid-with-cruise-control-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cruise Control Tray For Linux Update</title>
		<link>http://blog.yeticode.co.uk/2009/03/cruise-control-tray-for-linux-update/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cruise-control-tray-for-linux-update</link>
		<comments>http://blog.yeticode.co.uk/2009/03/cruise-control-tray-for-linux-update/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 03:01:33 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[cctray]]></category>
		<category><![CDATA[CruiseControl.NET]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[mono]]></category>

		<guid isPermaLink="false">http://blog.yeticode.co.uk/?p=79</guid>
		<description><![CDATA[Basic functionality has been implemented with the ability to add project to monitor and receive notifications of the build as and when they occur. At the moment there is not the ability to delete a project that is being monitor this will be implemented next. There is also the ability to force a build of [...]]]></description>
			<content:encoded><![CDATA[<p>Basic functionality has been implemented with the ability to add project to monitor and receive notifications of the build as and when they occur. At the moment there is not the ability to delete a project that is being monitor this will be implemented next. There is also the ability to force a build of a project, however there is not the ability to abort the build, this will also been implemented in the next couple of days hopefully.  Here are some more screen shots of what it currently looks like. The build notification have also been attached to the tray icon.</p>
<p><img src="http://dev.yeticode.co.uk/jt/dev/cctray/cctray-4.png"/><br />
<img src="http://dev.yeticode.co.uk/jt/dev/cctray/cctray-5.png"/><br />
<img src="http://dev.yeticode.co.uk/jt/dev/cctray/cctray-6.png"/></p>]]></content:encoded>
			<wfw:commentRss>http://blog.yeticode.co.uk/2009/03/cruise-control-tray-for-linux-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cruise Control.NET Tray Tool on linux</title>
		<link>http://blog.yeticode.co.uk/2009/03/cruise-controlnet-tray-tool-on-linux/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cruise-controlnet-tray-tool-on-linux</link>
		<comments>http://blog.yeticode.co.uk/2009/03/cruise-controlnet-tray-tool-on-linux/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 02:47:39 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[cctray]]></category>
		<category><![CDATA[CruiseControl.NET]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[LaunchPad]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[mono]]></category>

		<guid isPermaLink="false">http://blog.yeticode.co.uk/?p=69</guid>
		<description><![CDATA[I started looking at creating a port of the cctray tool for CruiseControl.NET but after looking at how it was implemented i decided that it might be easier, and more fun, to implement one myself using mono and GTK#. At the moment the application has the ability to display notification when a build event occurs [...]]]></description>
			<content:encoded><![CDATA[<p>I started looking at creating a port of the cctray tool for CruiseControl.NET but after looking at how it was implemented i decided that it might be easier, and more fun, to implement one myself using mono and GTK#. At the moment the application has the ability to display notification when a build event occurs and to display the list of projects that are being watched. The source code will be available on Launch Pad when I figure out how to use bzr.</p>
<p><a href="https://code.launchpad.net/~john-yeticode/cctray-gtk/trunk">https://code.launchpad.net/~john-yeticode/cctray-gtk/trunk</a></p>
<p>here are some screen shots of how it currently looks.</p>
<p><img src="http://dev.yeticode.co.uk/jt/dev/cctray/cctray-1.png"/><br />
<img src="http://dev.yeticode.co.uk/jt/dev/cctray/cctray-2.png"/><br />
<img src="http://dev.yeticode.co.uk/jt/dev/cctray/cctray-3.png"/></p>
<p><a href="http://confluence.public.thoughtworks.org/display/CCNET">Cruise Control.NET home page</a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.yeticode.co.uk/2009/03/cruise-controlnet-tray-tool-on-linux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
