<?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>Julian Higman&#039;s Blog</title>
	<atom:link href="http://julianhigman.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://julianhigman.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 14 May 2013 16:27:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Serving a website from Amazon S3</title>
		<link>http://julianhigman.com/blog/2013/04/03/serving-a-website-from-amazon-s3/</link>
		<comments>http://julianhigman.com/blog/2013/04/03/serving-a-website-from-amazon-s3/#comments</comments>
		<pubDate>Wed, 03 Apr 2013 15:25:08 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=467</guid>
		<description><![CDATA[Amazon S3 can be used to serve static content, with all the advantages of scaling and redundancy that you get from Amazon. There are comprehensive guides to setting up a site in S3 &#8211; this is a shortened version to highlight a couple of things. In my case, I wanted to set up a website [...]]]></description>
				<content:encoded><![CDATA[<p>Amazon S3 can be used to serve static content, with all the advantages of scaling and redundancy that you get from Amazon.</p>

<p>There are <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/HostingWebsiteOnS3Setup.html">comprehensive guides</a> to setting up a site in S3 &#8211; this is a shortened version to highlight a couple of things.</p>

<p>In my case, I wanted to set up a website to serve some static content at a subdomain of an existing domain which was being managed in Route53.</p>

<p>First, set up a bucket which will hold the website. Note, if you&#8217;re planning to use an alias for the domain, then the bucket needs to be named as a subdomain of one that you&#8217;re managing in Route53 &#8211; eg. static.julianhigman.com.</p>

<p>Next, set up the bucket to be a website, using the properties pane to select &#8220;Enable website hosting&#8221;. Give it an index filename of index.html (remember, S3 isn&#8217;t really serving content the same way as say Apache, which has directory listing built in, so you need to give it a default file to serve at the root URL).</p>

<p><a href="http://julianhigman.com/blog/wp-content/uploads/2013/04/bucket-properties.png"><img src="http://julianhigman.com/blog/wp-content/uploads/2013/04/bucket-properties.png" alt="bucket-properties" width="834" height="614" class="aligncenter size-full wp-image-468" /></a></p>

<p>Now, you need to allow anonymous visitors to read the contents of the bucket. The simplest way is to add a bucket policy. In the Permissions section of the properties, click the &#8220;Edit bucket policy&#8221; button, and add this (but replacing &#8220;static.julianhigman.com&#8221; with the name of your bucket):</p>

<pre><code>{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::static.julianhigman.com/*"
        }
    ]
}
</code></pre>

<p>You should now be able to access your bucket in a web browser, at a URL like http://static.julianhigman.com.s3-website-eu-west-1.amazonaws.com (again, replace static.julianhigman.com with your bucket).</p>

<p>You can create folders in the bucket, and upload content. Folders can have their own index.html file, which will be served by default if the URL path doesn&#8217;t include a filename. (And remember, objects in S3 actually all live in the bucket, the hierarchy of folders is being faked by S3 based on the path that you specify for an object when storing or retrieving it).</p>

<p>Finally, set up the alias for your subdomain in Route53 &#8211; create a new Record Set for the subdomain, specifying an &#8220;A&#8221; record, but selecting the &#8220;Alias&#8221; radio button, and choosing your new S3 website from the Alias Target dropdown (the available S3 websites should appear at the top of the list).</p>

<p>Save the records, and you&#8217;re done.</p>

<p>You should now be able serve static content from your S3 bucket.</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2013/04/03/serving-a-website-from-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using xargs and curl to request URLs from a list</title>
		<link>http://julianhigman.com/blog/2013/03/28/requesting-urls-from-a-list-in-a-file/</link>
		<comments>http://julianhigman.com/blog/2013/03/28/requesting-urls-from-a-list-in-a-file/#comments</comments>
		<pubDate>Thu, 28 Mar 2013 09:29:36 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[work bash]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/2013/03/28/requesting-urls-from-a-list-in-a-file/</guid>
		<description><![CDATA[Just some simple bash stuff that I keep forgetting cat list-of-urls-without-hostnames.txt &#124; xargs -i curl -v -L http://example.com{} where &#8220;list-of-urls-without-hostnames.txt&#8221; contains a list of URL paths, like: /resources/one /resources/two]]></description>
				<content:encoded><![CDATA[<p>Just some simple bash stuff that I keep forgetting</p>

<pre><code>cat list-of-urls-without-hostnames.txt | xargs -i curl -v -L http://example.com{}
</code></pre>

<p>where &#8220;list-of-urls-without-hostnames.txt&#8221; contains a list of URL paths, like:</p>

<pre><code>/resources/one
/resources/two
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2013/03/28/requesting-urls-from-a-list-in-a-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XDebug, PHP and Sublime Text 2 on Ubuntu 12.04</title>
		<link>http://julianhigman.com/blog/2012/11/06/xdebug-php-and-sublime-text-2-on-ubuntu-12-04/</link>
		<comments>http://julianhigman.com/blog/2012/11/06/xdebug-php-and-sublime-text-2-on-ubuntu-12-04/#comments</comments>
		<pubDate>Tue, 06 Nov 2012 12:01:10 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SublimeText]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=415</guid>
		<description><![CDATA[Getting Xdebug for PHP working with Sublime Text 2 is slightly tricky. Most of the instructions are at https://github.com/Kindari/SublimeXdebug - these notes are just a bit extra as a reminder to myself. After installing Xdebug with &#8220;sudo apt-get install php5-xdebug&#8221;, you have to add some xdebug  settings in /etc/php5/conf.d/xdebug.ini: zend_extension = /usr/lib/php5/20090626+lfs/xdebug.so xdebug.remote_enable=On xdebug.remote_host="localhost" xdebug.remote_port=9000 xdebug.remote_handler="dbgp" xdebug.remote_autostart=1 [...]]]></description>
				<content:encoded><![CDATA[<p>Getting Xdebug for PHP working with Sublime Text 2 is slightly tricky.</p>

<p>Most of the instructions are at <a href="https://github.com/Kindari/SublimeXdebug">https://github.com/Kindari/SublimeXdebug</a> - these notes are just a bit extra as a reminder to myself.</p>

<p>After installing Xdebug with &#8220;sudo apt-get install php5-xdebug&#8221;, you have to add some xdebug  settings in /etc/php5/conf.d/xdebug.ini:</p>

<pre><code>zend_extension = /usr/lib/php5/20090626+lfs/xdebug.so
xdebug.remote_enable=On
xdebug.remote_host="localhost"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.remote_autostart=1
</code></pre>

<p>In ST2, you use SHIFT+F8 to get the Xdebug menu, and select &#8220;Start debugging&#8221;. In your browser session, add a url parameter like this:</p>

<pre><code>?XDEBUG_SESSION_START=sublime.xdebug
</code></pre>

<p>The page request should hang while the debugger has control &#8211; if nothing&#8217;s happening in ST2, you&#8217;ll need to check the console window by using &#8221;CTRL`&#8221;.</p>

<p>You may get this output:</p>

<pre><code>Traceback (most recent call last):
File "./sublime_plugin.py", line 362, in run_
File "./Xdebug.py", line 553, in run
File "./Xdebug.py", line 97, in read
File ".\xml\dom\minidom.py", line 1927, in parseString
File ".\xml\dom\expatbuilder.py", line 32, in &amp;lt;module&amp;gt;
File ".\xml\parsers\expat.py", line 4, in &amp;lt;module&amp;gt;
ImportError: No module named pyexpat
</code></pre>

<p>In which case you&#8217;ve got the problem with Python versions &#8211; 2.7 is the default on Ubuntu 12.04, and ST2 and the Xdebug plugin are using Python 2.6.</p>

<p>So follow the instructions at the bottom of the README at <a href="https://github.com/Kindari/SublimeXdebug">https://github.com/Kindari/SublimeXdebug</a></p>

<pre><code>On Ubuntu 12.04, Python 2.6 isn't available, so here's what worked for me:

    * Download python2.6 files from &lt;a href="http://packages.ubuntu.com/lucid/python2.6"&gt;Ubuntu Archives&lt;/a&gt;
    * Extract the files: dpkg-deb -x python2.6_2.6.5-1ubuntu6_i386.deb python2.6
    * Copy the extracted usr/lib/python2.6 folder to {Sublime Text directory}/lib
</code></pre>

<p>(I actually copied the usr/lib/python2.6 directory to /usr/lib/python2.6, and symlinked to there from {Sublime Text directory}/lib)</p>

<p>Then restart ST2 and try again. Once you hit a breakpoint, it should look like this, with the Xdebug Context and Xdebug Stack windows showing content:</p>

<p style="text-align: center;"><a href="http://julianhigman.com/blog/wp-content/uploads/2012/11/st2-xdebug.png"><img class="aligncenter  wp-image-425" title="st2-xdebug" src="http://julianhigman.com/blog/wp-content/uploads/2012/11/st2-xdebug-300x171.png" alt="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/11/06/xdebug-php-and-sublime-text-2-on-ubuntu-12-04/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ikea Hack : Standing Desk</title>
		<link>http://julianhigman.com/blog/2012/11/02/standing-desk-with-ikea-bits/</link>
		<comments>http://julianhigman.com/blog/2012/11/02/standing-desk-with-ikea-bits/#comments</comments>
		<pubDate>Fri, 02 Nov 2012 23:46:17 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=409</guid>
		<description><![CDATA[I often get a bad back from sitting at a computer all day, so I thought I&#8217;d try a standing desk. After 3 weeks of standing, I think I&#8217;d find it hard to go back to sitting down all day &#8211; I really enjoy working standing up. Here what I&#8217;m using now: 4 x Vika [...]]]></description>
				<content:encoded><![CDATA[<p>I often get a bad back from sitting at a computer all day, so I thought I&#8217;d try a standing desk. After 3 weeks of standing, I think I&#8217;d find it hard to go back to sitting down all day &#8211; I really enjoy working standing up.</p>

<p>Here what I&#8217;m using now:</p>

<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-234939.jpg"><img class="  alignleft" src="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-234939.jpg" alt="20121102-234939.jpg" width="225" height="300" /></a></p>

<p>4 x <a title="Vika Kaj legs" href="http://www.ikea.com/gb/en/catalog/products/60105301/" target="_blank">Vika Kaj legs</a>
4 x <a title="Capita legs" href="http://www.ikea.com/gb/en/catalog/products/20049538/#/20049538" target="_blank">Capita legs</a> (the 21cm ones)
2 x <a title="Vika Amon table tops" href="http://www.ikea.com/gb/en/catalog/products/80071164/" target="_blank">Vika Amon table tops</a></p>

<p>It works pretty well, but with the main legs at about 85 cm, it needs to be braced against the wall to make it a bit more solid when typing.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<hr />

<p>Here are some other test versions I tried while figuring out what would work.</p>

<p>&nbsp;</p>

<div>

<a href="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-233507.jpg"><img src="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-233507-150x150.jpg" alt="20121102-233507.jpg" width="150" height="150" class="alignleft size-thumbnail wp-image-405" /></a>

<a href="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-233540.jpg"><img src="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-233540-150x150.jpg" alt="20121102-233540.jpg" width="150" height="150" class="alignleft size-thumbnail wp-image-407" /></a>

<a href="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-233531.jpg"><img src="http://julianhigman.com/blog/wp-content/uploads/2012/11/20121102-233531-150x150.jpg" alt="20121102-233531.jpg" width="150" height="150" class="alignleft size-thumbnail wp-image-406" /></a>

</div>

<p>&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;</p>

<p><br />
<br />
<br />
<br />
<br />
<br /></p>

<hr />

<p>Other standing desks for inspiration</p>

<p><a href="http://spacekat.github.com/blog/2012/07/26/diy-standing-desk/">http://spacekat.github.com/blog/2012/07/26/diy-standing-desk/</a></p>

<p><a href="http://www.ikeahackers.net/2012/02/big-red-standing-desk.html">http://www.ikeahackers.net/2012/02/big-red-standing-desk.html</a></p>

<p><a href="http://lifehacker.com/5934906/standing-desks-on-the-cheap-the-ikea-guide">http://lifehacker.com/5934906/standing-desks-on-the-cheap-the-ikea-guide</a></p>

<p><a href="http://woodhowto.blogspot.co.uk/p/wood-how-to-standing-desk-design-kit.html">http://woodhowto.blogspot.co.uk/p/wood-how-to-standing-desk-design-kit.html</a></p>

<p><a href="http://theironyard.com/2012/11/its-time-to-take-a-stand-cowork-standing-desks/">http://theironyard.com/2012/11/its-time-to-take-a-stand-cowork-standing-desks/</a></p>

<p>&nbsp;</p>

<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/11/02/standing-desk-with-ikea-bits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why two machines are still essential for web development (hint: stupid IE6)</title>
		<link>http://julianhigman.com/blog/2012/10/29/why-two-machines-are-still-essential-for-web-development-hint-stupid-ie6/</link>
		<comments>http://julianhigman.com/blog/2012/10/29/why-two-machines-are-still-essential-for-web-development-hint-stupid-ie6/#comments</comments>
		<pubDate>Mon, 29 Oct 2012 15:59:15 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=389</guid>
		<description><![CDATA[Here&#8217;s a modern web development setup: The machine on the left runs: a web server, multiple databases, Eclipse IDE, Sublime Text 2, test suites, source code control, Chrome, Firefox, terminal sessions, Skype, IRC, Spotify.. The machine on the right runs: IE6 &#160; ..because IE6 just WILL NOT DIE, EVER. And every time you release some [...]]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a modern web development setup:</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/10/one-nice-one-not.jpg"><img class="size-medium wp-image-390 alignleft" title="one-nice-one-not" src="http://julianhigman.com/blog/wp-content/uploads/2012/10/one-nice-one-not-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>The machine on the left runs:</p>
<p>a web server, multiple databases, Eclipse IDE, Sublime Text 2, test suites, source code control, Chrome, Firefox, terminal sessions, Skype, IRC, Spotify..</p>
<p>The machine on the right runs:</p>
<p>IE6</p>
<p>&nbsp;</p>
<p>..because IE6 just WILL NOT DIE, EVER.</p>
<p>And every time you release some web software (assuming you want it to be used within one of the  benighted organisations that still use IE6 &#8211; local government, big-but-slow companies who are paralysed by fear and cost) you&#8217;ll have to test every bit of every page all over again JUST ON IE6.</p>
<p>AND &#8211; the rest of us are all paying for it, in wasted development effort, longer development timescales, increased bug-fix cycles, and lost hair.</p>
<p>Rant ends.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/10/29/why-two-machines-are-still-essential-for-web-development-hint-stupid-ie6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running SauceLabs Selenium test suite locally with PHPUnit</title>
		<link>http://julianhigman.com/blog/2012/08/09/running-saucelabs-selenium-test-suite-locally-with-phpunit/</link>
		<comments>http://julianhigman.com/blog/2012/08/09/running-saucelabs-selenium-test-suite-locally-with-phpunit/#comments</comments>
		<pubDate>Thu, 09 Aug 2012 09:52:29 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[saucelabs]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=336</guid>
		<description><![CDATA[SauceLabs provide a great hosted Selenium service for cross-browser testing in the cloud, which allows you to run a Selenium test suite against multiple browsers using the SauceLabs API and SauceConnect. They also provide integration with PHPUnit, so that you can plug your SauceLabs Selenium tests directly into your PHPUnit test suite. Sometimes, though, you [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://saucelabs.com/" target="_blank">SauceLabs</a> provide a great hosted Selenium service for cross-browser testing in the cloud, which allows you to run a Selenium test suite against multiple browsers using the SauceLabs API and <a href="http://saucelabs.com/connect" target="_blank">SauceConnect</a>.</p>
<p>They also provide <a href="http://saucelabs.github.com/pear/" target="_blank">integration with PHPUnit</a>, so that you can plug your SauceLabs Selenium tests directly into your PHPUnit test suite.</p>
<p>Sometimes, though, you want to run the same Selenium test suite against a single browser on your local machine, before you run the full thing against all the browsers on SauceLabs.</p>
<p>However, the SauceLabs PHPUnit integration requires you to extend their special base class, which they&#8217;ve added to their custom PHPUnit library (which you need to have installed instead of the standard PHPUnit). That base class assumes that the test suite is <em>always</em> going to run against the remote SauceLabs API.</p>
<p>To run a Selenium test suite locally, you need to be extending the standard PHPUnit Selenium base class instead of the custom SauceLabs one &#8211; but you don&#8217;t want to duplicate all your tests in two class hierarchies. </p>
<p>How can you have a class where the parent class can be one of two different things, depending on some config setting?</p>
<p>The answer is by using  PHPs &#8220;class_alias&#8221; and a custom autoloader (note, &#8220;class_alias&#8221; is only available in PHP from 5.3.0 onwards). It works something like this..</p>
<p>Instead of extending either the special SauceLabs base class or the PHPUnit selenium base class directly, you define two different intermediate base classes &#8211; called RemoteSeleniumTestCase and LocalSeleniumTestCase &#8211; which each extend one of the base classes:</p>
<pre>
// RemoteSeleniumTestCase.php
class RemoteSeleniumTestCase extends <strong>PHPUnit_Extensions_SeleniumTestCase_SauceOnDemandTestCase</strong> 
{
    function setUp() {..}    // special setup for SauceLabs 
}
</pre>
<pre>
// LocalSeleniumTestCase.php
class LocalSeleniumTestCase extends <strong>PHPUnit_Extensions_SeleniumTestCase</strong>
{
    function setUp() {..}    // standard setup for local Selenium
}
</pre>
<p>The your actual test suite extends a (virtual) class &#8211; called DynamicSeleniumTestCase:</p>
<pre>
// your selenium test cases
class HomeTest extends <strong>DynamicSeleniumTestCase</strong>
{
    function testHomePage()
    {
        // check home page is there
        $this-&gt;open('/');
        $this-&gt;assertTextPresent('Welcome to BigCo');
   } 
}
</pre>
<p>So, where does DynamicSeleniumTestCase come from?</p>
<p>That&#8217;s where class_alias and the autoloader come in &#8211; you define a custom autoloader, which will alias DynamicSeleniumTestCase to one or other of your intermediate base classes, based on the value of an environment variable (I&#8217;ve used RUN_SELENIUM_REMOTE):</p>
<pre>
spl_autoload_register(function($class) {
    if (strcasecmp($class, 'DynamicSeleniumTestCase') === 0) {
        $remote = getenv('RUN_SELENIUM_REMOTE');
        if ($remote) {
            require_once 'RemoteSeleniumTestCase.php';
            <strong>class_alias('RemoteSeleniumTestCase', 'DynamicSeleniumTestCase');</strong>
        } else {
            require_once 'LocalSeleniumTestCase.php';
            <strong>class_alias('LocalSeleniumTestCase', 'DynamicSeleniumTestCase');</strong>
        }
    }
}, true, true);
</pre>
<p>Then, to make your test suite run against your local Selenium setup and local browser, just do</p>
<p style="padding-left: 30px;">export RUN_SELENIUM_REMOTE=0</p>
<p>before firing off the build, and to run the same thing against the SauceLabs server, do</p>
<p style="padding-left: 30px;">export RUN_SELENIUM_REMOTE=1</p>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div>Genius or insanity?! You decide.</div>
<div></div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/08/09/running-saucelabs-selenium-test-suite-locally-with-phpunit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>BCS Meeting 26th July 2012 on the Isle of Man</title>
		<link>http://julianhigman.com/blog/2012/07/23/bcs-meeting-26th-july-2012-on-the-isle-of-man/</link>
		<comments>http://julianhigman.com/blog/2012/07/23/bcs-meeting-26th-july-2012-on-the-isle-of-man/#comments</comments>
		<pubDate>Mon, 23 Jul 2012 13:00:41 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[scrum]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=330</guid>
		<description><![CDATA[I&#8217;ll be giving a talk about agile development on the 26th July 2012, in Douglas on the Isle of Man &#8211; more details here: http://www.bcs.org.im/2012/07/agile-masterclass-xp-scrum-and-lean-startups-july-26th/ &#160;]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ll be giving a talk about agile development on the 26th July 2012, in Douglas on the Isle of Man &#8211; more details here: <a href="http://www.bcs.org.im/2012/07/agile-masterclass-xp-scrum-and-lean-startups-july-26th/" target="_blank">http://www.bcs.org.im/2012/07/<wbr>agile-masterclass-xp-scrum-<wbr>and-lean-startups-july-26th/</wbr></wbr></a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/07/23/bcs-meeting-26th-july-2012-on-the-isle-of-man/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading PEAR if Guzzle install fails</title>
		<link>http://julianhigman.com/blog/2012/02/27/upgrading-pear-if-guzzle-install-fails/</link>
		<comments>http://julianhigman.com/blog/2012/02/27/upgrading-pear-if-guzzle-install-fails/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 22:11:21 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[guzzle]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=322</guid>
		<description><![CDATA[I had a problem with the PEAR installer with the Guzzle package (a generally excellent PHP HTTP framework). A channel discover would give the following error: root@ip-10-56-47-23:~# pear channel-discover guzzlephp.org/pear Discovering channel guzzlephp.org/pear over http:// failed with message: channel-add: Cannot open "http://guzzlephp.org/pear/channel.xml" (File http://guzzlephp.org:80/pear/channel.xml not valid (received: HTTP/1.1 404 Not Found )) Trying to discover [...]]]></description>
				<content:encoded><![CDATA[<p>I had a problem with the PEAR installer with the <a href="http://guzzlephp.org/" target="_blank">Guzzle</a> package (a generally excellent PHP HTTP framework).</p>
<p>A channel discover would give the following error:</p>
<pre>root@ip-10-56-47-23:~# pear channel-discover guzzlephp.org/pear
 Discovering channel guzzlephp.org/pear over http:// failed with message: channel-add: Cannot open "http://guzzlephp.org/pear/channel.xml" (File http://guzzlephp.org:80/pear/channel.xml not valid (received: HTTP/1.1 404 Not Found
 ))
 Trying to discover channel guzzlephp.org/pear over https:// instead
 Discovery of channel "guzzlephp.org/pear" failed (channel-add: Cannot open "https://guzzlephp.org/pear/channel.xml" (Connection to `guzzlephp.org:443' failed: Connection refused))</pre>
<p>Strangely, I could fetch the channel.xml file manually and add the channel. But even then, the install would fail (with similar messages about 404 errors).</p>
<p>The solution seemed to be upgrading PEAR &#8211; I was running version 1.9.0 (check it with &#8220;pear -V&#8221;), so I upgraded it:</p>
<pre>root@ip-10-56-47-23:~# pear upgrade pear</pre>
<p>after which I had version 1.9.4. Then I tried the channel discover again, with much better results:</p>
<pre>root@ip-10-56-47-23:~# pear channel-discover guzzlephp.org/pearAdding Channel "guzzlephp.org/pear" succeeded
 Discovery of channel "guzzlephp.org/pear" succeeded</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/02/27/upgrading-pear-if-guzzle-install-fails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Jenkins to run remote deployment scripts over SSH</title>
		<link>http://julianhigman.com/blog/2012/02/25/using-jenkins-to-run-remote-deployment-scripts-over-ssh/</link>
		<comments>http://julianhigman.com/blog/2012/02/25/using-jenkins-to-run-remote-deployment-scripts-over-ssh/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 21:58:29 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[jenkins]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=294</guid>
		<description><![CDATA[We use Jenkins to deploy code to multiple servers, so that we can manage builds and deployments from the same (even better if you&#8217;re using the Jenkins IRC plugin). The deployment is done by a parameterized build job, where the parameter is the version of the project that we want to deploy. The job will [...]]]></description>
				<content:encoded><![CDATA[<p>We use Jenkins to deploy code to multiple servers, so that we can manage builds and deployments from the same (even better if you&#8217;re using the <a title="Jenkins IRC Plugin" href="https://wiki.jenkins-ci.org/display/JENKINS/IRC+Plugin" target="_blank">Jenkins IRC plugin</a>).</p>
<p>The deployment is done by a parameterized build job, where the parameter is the version of the project that we want to deploy. The job will run remote commands over ssh on servers that you&#8217;ve defined in the Jenkins configuration. Those commands will pull down a version of our code, unpack it, and run the rest of the install steps.</p>
<p>&nbsp;</p>
<p>First you&#8217;ll need to install the <a title="Publish over SSH Plugin" href="https://wiki.jenkins-ci.org/display/JENKINS/Publish+Over+SSH+Plugin" target="_blank">Publish over SSH Plugin</a>, which will allow files to be transferred to your servers and remote commands to be run.</p>
<p>Set up the SSH key for remote access of your target servers, in the Manage Jenkins page:</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/ssh-key.png"><img class="aligncenter size-full wp-image-295" title="ssh-key" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/ssh-key.png" alt="" width="1176" height="453" /></a></p>
<p>and setup the definitions for each of the servers that you want to deploy to:</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/ssh-server.png"><img class="aligncenter size-full wp-image-298" title="ssh-server" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/ssh-server.png" alt="" width="1079" height="173" /></a></p>
<p>Then in the configuration for the new deployment job you&#8217;ve set up, you&#8217;ll use the &#8220;Send files or execute commands over SSH before the build starts&#8221; settings in the &#8220;Build Environment&#8221; section to remotely execute a script to carry out the install steps on each remote server:</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/remote-exec.png"><img class="aligncenter size-full wp-image-300" title="remote-exec" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/remote-exec.png" alt="" width="919" height="401" /></a></p>
<p>Notice that the build parameter &#8220;$version&#8221; is available to the Exec command that gets remotely executed &#8211; other Jenkins environment variables will also be available (e.g. $BUILD_NUMBER, $JOB_NAME etc).</p>
<p>Use the &#8220;Add Server&#8221; button to add more target servers, with the same Exec command.</p>
<p>Now you can deploy your project (or run any other remote scripts) by running the build job and specifying a version number.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/02/25/using-jenkins-to-run-remote-deployment-scripts-over-ssh/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Building github branches with Jenkins</title>
		<link>http://julianhigman.com/blog/2012/02/22/building-github-branches-with-jenkins/</link>
		<comments>http://julianhigman.com/blog/2012/02/22/building-github-branches-with-jenkins/#comments</comments>
		<pubDate>Wed, 22 Feb 2012 21:47:32 +0000</pubDate>
		<dc:creator>jhigman</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[jenkins]]></category>

		<guid isPermaLink="false">http://julianhigman.com/blog/?p=278</guid>
		<description><![CDATA[We usually work on several parallel branches of a repo on github, and we wanted to be able to build and test any branch on demand. So we set up a parameterised job in Jenkins that will take the name of a branch and run the build process. As for all github builds, you need [...]]]></description>
				<content:encoded><![CDATA[<p>We usually work on several parallel branches of a repo on github, and we wanted to be able to build and test any branch on demand.</p>
<p>So we set up a parameterised job in Jenkins that will take the name of a branch and run the build process.</p>
<p>As for all github builds, you need to have installed the git plugin first (<a href="https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin">https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin</a>) and set up your github globals in the Jenkins settings:</p>
<p>&nbsp;</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/jenkins-git-setup-1.png"><img class="aligncenter size-full wp-image-280" title="jenkins-git-setup-1" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/jenkins-git-setup-1.png" alt="" width="919" height="215" /></a></p>
<p>&nbsp;</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/jenkins-git-setup-2.png"><img class="aligncenter size-full wp-image-279" title="jenkins-git-setup-2" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/jenkins-git-setup-2.png" alt="" width="838" height="99" /></a></p>
<p>&nbsp;</p>
<p>Then set up a parameterized build job with the repo as the GitHub project and with &#8220;branch&#8221; as the parameter to be specified:</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/build-param.png"><img class="aligncenter size-full wp-image-289" title="build-param" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/build-param.png" alt="" width="825" height="130" /></a></p>
<p>and in the Source Code Management section, add the parameter to the &#8220;Branches to build&#8221;:</p>
<p><a href="http://julianhigman.com/blog/wp-content/uploads/2012/02/source-code.png"><img class="aligncenter size-full wp-image-290" title="source-code" src="http://julianhigman.com/blog/wp-content/uploads/2012/02/source-code.png" alt="" width="822" height="243" /></a>Don&#8217;t specify any build triggers &#8211; you&#8217;ll probably just want to run this on-demand against specific branches, rather than every time there&#8217;s a push to the repo (which is what happens by default).</p>
<p>Now you can build any branch just by giving the branch name as the required parameter when the job is started.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://julianhigman.com/blog/2012/02/22/building-github-branches-with-jenkins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
