<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Code in the hole (Entries tagged as continuous integration)</title>
    <link>http://codeinthehole.com/</link>
    <description>David Winterbottom</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.3.1 - http://www.s9y.org/</generator>
    
    

<item>
    <title>Phing, Xinc and Nabaztags</title>
    <link>http://codeinthehole.com/archives/27-Phing,-Xinc-and-Nabaztags.html</link>
            <category>Development</category>
    
    <comments>http://codeinthehole.com/archives/27-Phing,-Xinc-and-Nabaztags.html#comments</comments>
    <wfw:comment>http://codeinthehole.com/wfwcomment.php?cid=27</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://codeinthehole.com/rss.php?version=2.0&amp;type=comments&amp;cid=27</wfw:commentRss>
    

    <author>nospam@example.com (David Winterbottom)</author>
    <content:encoded>
    &lt;p&gt;
Finally got around to setting up continuous integration for some of the projects that comprise the day-job.  We&#039;re using the PEAR package &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/code.google.com/p/xinc/&#039;);&quot;  href=&quot;http://code.google.com/p/xinc/&quot;&gt;Xinc&lt;/a&gt;, which has proved to be excellent thus far - especially as it integrates so well with my deployment tool of choice: &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/phing.info/trac/&#039;);&quot;  href=&quot;http://phing.info/trac/&quot;&gt;Phing&lt;/a&gt;.  Part of the fun in setting it up was looking for suitable feedback mechanisms or devices.  Email notifications are a given but there are a range of more interesting feedback mechanisms available such as toolbar notifications, remote-controlled lava lamps, or plain humiliation tactics (such as making the person who broke the build wear the dunce&#039;s hat till it is fixed).  By a strange twist of fate there happened to be an unused &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.nabaztag.com/en/index.html&#039;);&quot;  href=&quot;http://www.nabaztag.com/en/index.html&quot;&gt;Nabaztag&lt;/a&gt; in the office: a strange Rabbit-like fellow able to play sounds, move its ears and activate a selection of brightly colours LEDs contained in its body.  Nabaztags are controlled through a simple HTTP web-service, with the various actions been specified by GET requests using &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/doc.nabaztag.com/api/home.html&#039;);&quot;  href=&quot;http://doc.nabaztag.com/api/home.html&quot;&gt;a simple API&lt;/a&gt;.   
&lt;/p&gt;
&lt;p&gt;
Out of the box, Xinc only provides email notifications for feedback but its design is such that plugins are easy to create.  Indeed, Raphael Stolt has written recently on creating a publisher that uses the Growl notifications native to Macs.  A natural extension to this would be to create an Linux version, given the inclusion of libnotify in the latest Ubuntu release.  That&#039;s not for today though.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
The true flexibility in Xinc comes from the &lt;code&gt;phingpublisher&lt;/code&gt; publisher, which allows an arbitrary target to be called from a phing script.  Rather than create a Xinc plugin for the Nabaztag, writing a Phing task seemed to offer more flexibility as it could then be used in deployment scripts elsewhere. 
&lt;/p&gt;
&lt;p&gt;
I&#039;ve previously created a couple of simple phing tasks for &lt;a href=&quot;http://codeinthehole.com/archives/14-Phing-task-to-update-Twitter-status.html&quot;&gt;updating a Twitter status&lt;/a&gt;, and &lt;a href=&quot;http://codeinthehole.com/archives/15-Phing-task-to-create-an-Unfuddle-message.html&quot;&gt;interacting with the Unfuddle API&lt;/a&gt;.  Creating a Nabaztag task was just a simple extension of these cURL-based tasks.  The various attributes mirror those from the API docs.  
&lt;/p&gt;
&lt;table&gt;
&lt;caption&gt;NabaztagTask.php attributes&lt;/caption&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;th&gt;Default&lt;/th&gt;&lt;th&gt;Required&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;serialNum&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;Serial number&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;token&lt;/td&gt;&lt;td&gt;Integer&lt;/td&gt;&lt;td&gt;Token number&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;leftEarPosition&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;Position of the left ear (0-16)&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rightEarPosition&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;Position of the right ear (0-16)&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;message&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;Message.&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;messageId&lt;/td&gt;&lt;td&gt;Integer&lt;/td&gt;&lt;td&gt;Message id.&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;voice&lt;/td&gt;&lt;td&gt;Integer&lt;/td&gt;&lt;td&gt;Voice to use (use the API to fetch the full list)&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;choreography&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;A string which prescribes the choreography to use (see API docs)&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;choreographyTitle&lt;/td&gt;&lt;td&gt;Boolean&lt;/td&gt;&lt;td&gt;Choreography title&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;urlList&lt;/td&gt;&lt;td&gt;Boolean&lt;/td&gt;&lt;td&gt;List of URLs to pass to the Nabaztag (can be used for playing audio files)&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;checkReturn&lt;/td&gt;&lt;td&gt;Boolean&lt;/td&gt;&lt;td&gt;Whether to check the return code of the request, throws a BuildException if the update fails&lt;/td&gt;&lt;td&gt;false&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;The code for this task can be found in &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/github.com/codeinthehole/phing-tasks/tree/master&#039;);&quot;  href=&quot;http://github.com/codeinthehole/phing-tasks/tree/master&quot;&gt;my github repo&lt;/a&gt; - to install locally, export the file to a local phing tasks folder (I use &lt;code&gt;/usr/share/php/phing/tasks/my&lt;/code&gt; on my Ubuntu machine).  Having done that, a simple example build.xml file to exercise the task would be:
&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; ?&gt;
&amp;lt;project name=&quot;Example Nabaztag update&quot; basedir=&quot;.&quot;&gt;
    &amp;lt;taskdef name=&quot;nabaztag&quot; classname=&quot;phing.tasks.my.NabaztagTask&quot; /&gt;
    &amp;lt;target name=&quot;build-failure&quot;&gt;
        &amp;lt;nabaztag serialNum=&quot;${nabaztag.serialNum}&quot; token=&quot;${nabaztag.token}&quot; message=&quot;The build failed!&quot; voice=&quot;US-Liberty&quot; /&gt;
    &amp;lt;/target&gt;
&amp;lt;/project&gt;&lt;/code&gt;
&lt;p&gt;
To use this with Xinc, you simply need to called the appropriate target from your project configuration file.  Another toy example:
&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot;?&gt;
&amp;lt;xinc&gt;
    &amp;lt;project name=&quot;Toy example&quot;&gt;
        &amp;lt;configuration&gt;
		&amp;lt;setting name=&quot;loglevel&quot; value=&quot;1&quot;/&gt;
		&amp;lt;setting name=&quot;timezone&quot; value=&quot;Europe/London&quot;/&gt;
	&amp;lt;/configuration&gt;
	&amp;lt;property name=&quot;dir&quot; value=&quot;/var/xinc/projects/sample&quot;/&gt;
    	&amp;lt;cron timer=&quot;*/15 * * * *&quot;/&gt;
        &amp;lt;modificationset&gt;
            &amp;lt;svn directory=&quot;${dir}&quot; update=&quot;true&quot; /&gt;
        &amp;lt;/modificationset&gt;		
        &amp;lt;builders&gt;
        	&amp;lt;phingBuilder buildfile=&quot;${dir}/build.xml&quot; target=&quot;build-project&quot;/&gt;
        &amp;lt;/builders&gt;
        &amp;lt;publishers&gt;
            &amp;lt;onfailure&gt;
	        &amp;lt;phingpublisher buildfile=&quot;${dir}/build.xml&quot; target=&quot;build-failure&quot; /&gt;
            &amp;lt;/onfailure&gt;
        &amp;lt;/publishers&gt;
    &amp;lt;/project&gt;
&amp;lt;/xinc&gt;&lt;/code&gt;
&lt;p&gt;Some of the options for controlling the Nabaztag are only available with the V2 version.   The one on my desk is V1 and so I haven&#039;t tested every action, I&#039;ve just followed the instructions in the API docs.  Unfortunately, the Nabaztag webservice isn&#039;t as RESTful as would be desired - it returns a 200 response code for every request, whether it fails or not.  This makes it a touch tricky to handle failed updates.

&lt;p&gt;Nabaztags are also useful for general reminders - I have the following line in my crontab:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;15 18 * * 5 curl &quot;http://api.nabaztag.com/vl/FR/api.jsp?sn=$SERIAL&amp;token=$TOKEN&amp;tts=It+is+now+time+to+go+to+the+pub&quot;&lt;/code&gt;




 
    </content:encoded>

    <pubDate>Wed, 06 May 2009 21:57:13 +0000</pubDate>
    <guid isPermaLink="false">http://codeinthehole.com/archives/27-guid.html</guid>
    <category>continuous integration</category>
<category>phing</category>
<category>php</category>
<category>xinc</category>

</item>

</channel>
</rss>