<?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>thinking in geek &#187; deployment</title>
	<atom:link href="http://joshrobb.com/blog/category/deployment/feed/" rel="self" type="application/rss+xml" />
	<link>http://joshrobb.com/blog</link>
	<description>tagline's are so web2.0</description>
	<lastBuildDate>Fri, 11 Mar 2011 07:17:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Crappystrano</title>
		<link>http://joshrobb.com/blog/2008/01/02/crappystrano/</link>
		<comments>http://joshrobb.com/blog/2008/01/02/crappystrano/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 23:37:42 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/2008/01/02/crappystrano/</guid>
		<description><![CDATA[Note: After I started this series Jeremy Miller has posted a very relevant article about source code hygiene issues. (This is the third part in a series &#8211; you should probably read part one and two first.) Today I&#8217;ll present a sanitised copy of my deployment script. I&#8217;ve based the design of deploy.cmd on Capistrano1 [...]]]></description>
			<content:encoded><![CDATA[<p><em>Note: After I started this series <a href="http://codebetter.com/blogs/jeremy.miller/">Jeremy Miller</a> has posted a very relevant <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/12/06/do-you-really-know-where-that-code-has-been.aspx">article about source code hygiene</a> issues. </em></p>
<p>(This is the third part in a series &#8211; you should probably read <a href="/blog/2007/11/30/automated-deployment-ci-for-operations/">part one</a> and <a href="/blog/2007/12/12/a-deployment-process/">two</a> first.)</p>
<p>Today I&#8217;ll present a sanitised copy of my deployment script.  I&#8217;ve based the design of deploy.cmd on Capistrano<sup><a href="http://joshrobb.com/blog/2008/01/02/crappystrano/#footnote_0_46" id="identifier_0_46" class="footnote-link footnote-identifier-link" title="http://www.capify.org/ &amp;#8211; I know some people are going to say &amp;#8211; just use Capistrano. There are two reasons for me not to: 1. I&amp;#8217;m the only person in my team familiar with Ruby. 2. Even if you argue that they don&amp;#8217;t need to understand ruby to run a cap deployment recipe &amp;#8211; they still have to have it installed. It&amp;#8217;s just yet another dependency which I&amp;#8217;m not willing to take currently. ">1</a></sup> . The script is nicknamed &#8220;Crappystrano&#8221;. Here&#8217;s the output (pretty htmlized <a href="/blog/wp-content/uploads/2007/11/deploy.html">source is here</a>):</p>
<blockquote><p>&gt;deploy.cmd</p>
<p>Crappystrano &#8211; the shit script which (sort of) deploys stuff</p>
<p>deploy.cmd staging|live [branchpath]</p></blockquote>
<p>Here&#8217;s breakdown of the steps<sup><a href="http://joshrobb.com/blog/2008/01/02/crappystrano/#footnote_1_46" id="identifier_1_46" class="footnote-link footnote-identifier-link" title="This is all simplified as the actual script supports a SaaS product which has multiple instances &amp;#8211; one per client">2</a></sup> &#8211; skipping some error checking<sup><a href="http://joshrobb.com/blog/2008/01/02/crappystrano/#footnote_2_46" id="identifier_2_46" class="footnote-link footnote-identifier-link" title="noted with [E]">3</a></sup>. :</p>
<ol>
<li>Do we have the required dependencies<sup><a href="http://joshrobb.com/blog/2008/01/02/crappystrano/#footnote_3_46" id="identifier_3_46" class="footnote-link footnote-identifier-link" title="gnu zip.exe, svn">4</a></sup> on the path? If we don&#8217;t copy them to the path if they&#8217;re just 1 exe &#8211; otherwise exit with an error.</li>
<li>Check the command line parameters. We must have the environment we&#8217;re releasing to? Are we releasing from the trunk or from a SVN branch?</li>
<li>Construct a release time stamp. This is YYYYMMDDHHMMSSMS.</li>
<li>Perform a &#8220;svn export&#8221; from the trunk/branch to %tmp%\staging|live%timestamp%. [E]</li>
<li>Use msbuild to build the solution. [E]</li>
<li>Rearrange the folder structure so we only get the artefacts we need in the release package.</li>
<li>Zip up the release package using the environment name + time stamp.</li>
<li>move the release package back to the root directory of the project and delete the export from %tmp%.</li>
<li>Make a SVN tag (svn copy trunk/branch /tags/environment-timestamp).</li>
</ol>
<p>I&#8217;ve <a href="/blog/wp-content/uploads/2007/11/deploy.zip">uploaded a zip file </a>with the script and folder structure + a little readme. This is not the best way of doing things &#8211; it&#8217;s just a very lightweight way. Comments, questions, feedback etc&#8230; are gratefully received.</p>
<ol class="footnotes"><li id="footnote_0_46" class="footnote">http://www.capify.org/ &#8211; I know some people are going to say &#8211; just use Capistrano. There are two reasons for me not to: 1. I&#8217;m the only person in my team familiar with Ruby. 2. Even if you argue that they don&#8217;t need to understand ruby to run a cap deployment recipe &#8211; they still have to have it installed. It&#8217;s just yet another dependency which I&#8217;m not willing to take currently. </li><li id="footnote_1_46" class="footnote">This is all simplified as the actual script supports a SaaS product which has multiple instances &#8211; one per client</li><li id="footnote_2_46" class="footnote">noted with [E]</li><li id="footnote_3_46" class="footnote">gnu zip.exe, svn</li></ol>]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2008/01/02/crappystrano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A deployment process</title>
		<link>http://joshrobb.com/blog/2007/12/12/a-deployment-process/</link>
		<comments>http://joshrobb.com/blog/2007/12/12/a-deployment-process/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 11:57:51 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/2007/12/12/a-deployment-process/</guid>
		<description><![CDATA[I know I said my next post would be my deployment script but after posting &#8211; I realised that I should do a 1000 foot overview of what I&#8217;m trying to achieve. For me &#8211; a successful deployment has a number of components: Build Code successfully builds&#160; tests pass. Versioning I know exactly which revision [...]]]></description>
			<content:encoded><![CDATA[<p>I know I said my next post would be my deployment script but after posting &#8211; I realised that I should do a 1000 foot overview of what I&#8217;m trying to achieve.
<p>For me &#8211; a successful deployment has a number of components:
<ul>
<li>Build
<ol>
<li>Code successfully builds&nbsp;
<li>tests pass.</li>
</ol>
<li>Versioning
<ol>
<li>I know exactly which revision was deployed from subversion.
<li>I know what environment it was deployed to.</li>
</ol>
<li>Deployment Safety
<ol>
<li>
<p>On my server I have the ability to rollback a deployment. </p>
</li>
</ol>
<li>Support
<ol>
<li>I can compare the current deployed version to previous releases when I need to do post-deployment production debugging. </li>
</ol>
</li>
</ul>
<p>To achieve this I use a number of conventions which I&#8217;ve borrowed and adapted from Capistrano. </p>
<p>My Subversion repository is structured so that every release get&#8217;s it&#8217;s own tag &#8211; including the environment which the release was made to<sup><a href="http://joshrobb.com/blog/2007/12/12/a-deployment-process/#footnote_0_45" id="identifier_0_45" class="footnote-link footnote-identifier-link" title="The folders in /tags are client names. This is because our SaaS app is released per-client &amp;#8211; not multi tenanted. i.e. Each client is running a different version at any given time &amp;#8211; and is upgraded to the latest trunk as necessary.">1</a></sup> :</p>
<p><a href="http://joshrobb.com/blog/wp-content/uploads/2007/12/subversion-release-structure.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="subversion-release-structure" src="http://joshrobb.com/blog/wp-content/uploads/2007/12/subversion-release-structure-thumb.png" width="211" border="0"></a> </p>
<p>The tags are kind of self explanatory &#8211; the format is: </p>
<blockquote><p><font color="#333333">[environment]-YYYYMMDDHHMMSSMS</font>&nbsp;</p>
</blockquote>
<p>This is much easier than trying to remember that version 2.54.33.2 was released on Tuesday to client X. </p>
<p>In a deployment environment (staging or live) &#8211; each release is unpacked into it&#8217;s own folder.<sup><a href="http://joshrobb.com/blog/2007/12/12/a-deployment-process/#footnote_1_45" id="identifier_1_45" class="footnote-link footnote-identifier-link" title="The occluded bits are the client name &amp;#8211; this is for convenience in managing release packages (zip files) as the server has a folder for each client">2</a></sup></p>
<p><a href="http://joshrobb.com/blog/wp-content/uploads/2007/12/iis-release-folders.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="52" alt="iis-release-folders" src="http://joshrobb.com/blog/wp-content/uploads/2007/12/iis-release-folders-thumb.png" width="204" border="0"></a></p>
<p>After a deployment package has been unpacked on the server there will be a new folder for the release. Making a release active involves a couple of (currently) non-automated steps:</p>
<ol>
<li>Updating the database connection details (this is a matter of copying a database.config into the release folder<sup><a href="http://joshrobb.com/blog/2007/12/12/a-deployment-process/#footnote_2_45" id="identifier_2_45" class="footnote-link footnote-identifier-link" title="this is the only thing on the server which is not versioned in subversion. My web.config has the following: &amp;lt;connectionStrings configSource=&amp;#8221;database.config&amp;#8221;/&amp;gt; &amp;#8211; this file just contains the connection details for the application. ">3</a></sup> ).&nbsp;
<li>running a DB upgrade
<li>changing the webroot in IIS </li>
</ol>
<p>People who are paying attention will notice that this process is not necessarily atomic. Depending on the DB changes &#8211; it&#8217;s possible that the old/new code cannot run on the same database &#8211; in this case I drop a app_offline.htm &#8211; into the previous release folder before I run the DB upgrade. </p>
<ol class="footnotes"><li id="footnote_0_45" class="footnote">The folders in /tags are client names. This is because our SaaS app is released per-client &#8211; not multi tenanted. i.e. Each client is running a different version at any given time &#8211; and is upgraded to the latest trunk as necessary.</li><li id="footnote_1_45" class="footnote">The occluded bits are the client name &#8211; this is for convenience in managing release packages (zip files) as the server has a folder for each client</li><li id="footnote_2_45" class="footnote">this is the only thing on the server which is not versioned in subversion. My web.config has the following: &lt;connectionStrings configSource=&#8221;database.config&#8221;/&gt; &#8211; this file just contains the connection details for the application. </li></ol>]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2007/12/12/a-deployment-process/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automated deployment == CI for Operations</title>
		<link>http://joshrobb.com/blog/2007/11/30/automated-deployment-ci-for-operations/</link>
		<comments>http://joshrobb.com/blog/2007/11/30/automated-deployment-ci-for-operations/#comments</comments>
		<pubDate>Fri, 30 Nov 2007 17:20:00 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/2007/11/30/automated-deployment-ci-for-operations/</guid>
		<description><![CDATA[Deployment is a subject that is near and dear to my heart. I&#8217;m almost always the guy who gets to debug production problems, deployment problems and generally wears a developer + infrastructure hat.1 When it comes to web applications &#8211; most teams don&#8217;t bother automating their deployment processes. This is something that I think is [...]]]></description>
			<content:encoded><![CDATA[<p>Deployment is a subject that is near and dear to my heart. I&#8217;m almost always the guy who gets to debug production problems, deployment problems and generally wears a developer + infrastructure hat.<sup><a href="http://joshrobb.com/blog/2007/11/30/automated-deployment-ci-for-operations/#footnote_0_26" id="identifier_0_26" class="footnote-link footnote-identifier-link" title="Ten years ago &amp;#8211; part of my job was building deployment packages for desktop applications (this is pre MSI). Identifying all the dependencies of an app and scripting them into an install package and testing the deployment was at times almost a full time job.">1</a></sup></p>
<p>When it comes to web applications &#8211; most teams don&#8217;t bother automating their deployment processes. This is something that I think is in the process of changing<sup><a href="http://joshrobb.com/blog/2007/11/30/automated-deployment-ci-for-operations/#footnote_1_26" id="identifier_1_26" class="footnote-link footnote-identifier-link" title="there have been a couple of good threads about this on the altnetconf mailing list">2</a></sup> &#8211; but is not yet a generally accepted practice on a par with TDD, user stories or iterations.</p>
<p>At a minimum &#8211; it should be possible to:</p>
<ol>
<li>Issue a single command which creates a release package for your project. (i.e. built, tested, tagged in subversion and zipped up). For me &#8211; this tool/command is called: deploy.cmd and is just a batch file.</li>
<li>Issue another command in your deployment environment which will configure the new release. (i.e. update IIS root, upgrade the database, update connection strings + any other configuration required).</li>
</ol>
<p>In my current project I&#8217;ve built 1. For me 2 does not exist as a single command line (It&#8217;s currently a combination of several tools &#8211; this should be changed!).</p>
<p>In my next post I&#8217;ll outline my very simple solution for this. Just to get the conversation started.</p>
<ol class="footnotes"><li id="footnote_0_26" class="footnote">Ten years ago &#8211; part of my job was building deployment packages for desktop applications (this is pre MSI). Identifying all the dependencies of an app and scripting them into an install package and testing the deployment was at times almost a full time job.</li><li id="footnote_1_26" class="footnote">there have been a couple of good threads about this on the <a href="http://tech.groups.yahoo.com/group/altnetconf/">altnetconf mailing list</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2007/11/30/automated-deployment-ci-for-operations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

