<?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>Sysbliss Blog &#187; Uncategorized</title>
	<atom:link href="http://blog.sysbliss.com/category/uncategorized/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.sysbliss.com</link>
	<description>On the never-ending quest for systems bliss</description>
	<lastBuildDate>Wed, 20 Jan 2010 20:44:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Release Management with Atlassian Bamboo and Jira</title>
		<link>http://blog.sysbliss.com/uncategorized/release-management-with-atlassian-bamboo-and-jira.html</link>
		<comments>http://blog.sysbliss.com/uncategorized/release-management-with-atlassian-bamboo-and-jira.html#comments</comments>
		<pubDate>Mon, 04 Aug 2008 16:48:15 +0000</pubDate>
		<dc:creator>jdoklovic</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development process]]></category>

		<guid isPermaLink="false">http://blog.sysbliss.com/?p=9</guid>
		<description><![CDATA[I recently released a new plugin for <a title="Atlassian Bamboo" href="http://www.atlassian.com/software/bamboo/">Atlassian Bamboo</a> called <a title="Jira Versions Bamboo Plugin" href="http://confluence.atlassian.com/display/BAMEXT/JiraVersions+Plugin">Jira Versions</a>.
In combination with <a title="Jira - Bug Tracking Software" href="http://www.atlassian.com/software/jira/">Jira</a>, the <a title="Bamboo Tagger Plugin" href="http://confluence.atlassian.com/display/BAMEXT/Bamboo+Tagger+plugin">Bamboo Tagger Plugin</a> and the <a title="Pre-Post Build Command Plugin" href="http://confluence.atlassian.com/display/BAMEXT/Pre-Post+Build+Command+Plugin">Pre/Post Build Command Plugin</a> it can be used as a complete release management system. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently released a new plugin for <a title="Atlassian Bamboo" href="http://www.atlassian.com/software/bamboo/">Atlassian Bamboo</a> called <a title="Jira Versions Bamboo Plugin" href="http://confluence.atlassian.com/display/BAMEXT/JiraVersions+Plugin">Jira Versions</a>.<br />
In combination with <a title="Jira - Bug Tracking Software" href="http://www.atlassian.com/software/jira/">Jira</a>, the <a title="Bamboo Tagger Plugin" href="http://confluence.atlassian.com/display/BAMEXT/Bamboo+Tagger+plugin">Bamboo Tagger Plugin</a> and the <a title="Pre-Post Build Command Plugin" href="http://confluence.atlassian.com/display/BAMEXT/Pre-Post+Build+Command+Plugin">Pre/Post Build Command Plugin</a> it can be used as a complete release management system.</p>
<p>This post serves both as a quick tutorial on setting up bamboo as a release management system as well as a scenario that illustrates how the plugins can be used within a release workflow.</p>
<h2>Scenario</h2>
<h3>Project Information</h3>
<p>In our scenario, we will be building a fictitious web app project.<br />
This project will be using an iterative/agile development process.<br />
We will have:</p>
<ul>
<li>3 development iterations</li>
<li>2 release candidates</li>
<li>1 production release</li>
<li>1 emergency bugfix release.</li>
</ul>
<p><strong>Bamboo Project Information:</strong></p>
<table border="1" cellpadding="2">
<tbody>
<tr>
<td><strong><span style="color: #000000;">Project Name</span></strong></td>
<td>Web Apps</td>
</tr>
<tr>
<td><strong>Project Key</strong></td>
<td>WEB</td>
</tr>
<tr>
<td><strong>Plan Name</strong></td>
<td>My Web App</td>
</tr>
<tr>
<td><strong>Plan Key</strong></td>
<td>MYAPP</td>
</tr>
</tbody>
</table>
<h3>Deployment</h3>
<p>Since we&#8217;re building a webapp, we need to deployment workflow for when and where different builds get deployed.<br />
Figure A. shows our <em>logical</em> deployment workflow. The actual physical deployment all happens from the Bamboo server via shell scripts.</p>
<dl id="attachment_10" class="wp-caption alignnone" style="width: 244px;">
<dt class="wp-caption-dt"><a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/logical_release_deploy.png"><img class="size-medium wp-image-10" title="logical_release_deploy" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/logical_release_deploy-234x300.png" alt="Figure A: Logical Release Deployment" width="234" height="300" /></a></dt>
</dl>
<dl id="attachment_10" class="wp-caption alignnone" style="width: 244px;">
<dt class="wp-caption-dt"> <em>Figure A. Logical Release Deployment </em></dt>
</dl>
<h3>Versioning</h3>
<p>Our project will use the following version number scheme:</p>
<p>[Major].[Minor].[Bugfix]-[type][iteration]-[build]</p>
<table border="1">
<tbody>
<tr>
<td><strong>Major</strong></td>
<td>the major release number</td>
</tr>
<tr>
<td><strong>Minor</strong></td>
<td>new features backwards compatible</td>
</tr>
<tr>
<td><strong>Bugfix</strong></td>
<td>maintenance fixes / emergency</td>
</tr>
<tr>
<td><strong>type</strong></td>
<td>release level i.e. dev, rc, prod</td>
</tr>
<tr>
<td><strong>iteration</strong></td>
<td>iteration number</td>
</tr>
<tr>
<td><strong>build</strong></td>
<td>bamboo build key / number</td>
</tr>
</tbody>
</table>
<p>Using this scheme, our project will produce the following final version numbers (with multiple build versions in-between)</p>
<ul>
<li>1.0.0-dev1 &#8211; development iteration 1</li>
<li>1.0.0-dev2 &#8211; development iteration 2</li>
<li>1.0.0-dev3 &#8211; development iteration 3</li>
<li>1.0.0-rc1 &#8211; release candidate 1</li>
<li>1.0.0-rc2 &#8211; release candidate 2</li>
<li>1.0.0 &#8211; first production release</li>
<li>1.0.1 &#8211; emergency production bugfix release</li>
</ul>
<h2>Installation</h2>
<p>Installation is simple&#8230;.<br />
Assuming you already have Jira and Bamboo installed and running:</p>
<p>Just download the 3 distrubution jars from the respective plugin pages and drop them into your ${BAMBOO_INSTALL}/webapp/WEB-INF/lib folder.</p>
<ul>
<li><a title="Jira Versions Bamboo Plugin" href="http://confluence.atlassian.com/display/BAMEXT/JiraVersions+Plugin">Jira Versions Plugin</a></li>
<li><a title="Bamboo Tagger Plugin" href="http://confluence.atlassian.com/display/BAMEXT/Bamboo+Tagger+plugin">Bamboo Tagger Plugin</a></li>
<li><a title="Pre-Post Build Command Plugin" href="http://confluence.atlassian.com/display/BAMEXT/Pre-Post+Build+Command+Plugin">Pre-Post Build Command Plugin</a></li>
</ul>
<p>now just restart bamboo.</p>
<h2>Project Setup</h2>
<h3>Version Your Package</h3>
<p>Most software built today is compiled and packaged with some sort of automated tool. I&#8217;m sure there are a few die-hards that are still using vi and javac on the command-line but for the rest of us not living in the eighties, we&#8217;re using something like ant, maven, etc.</p>
<p>To that end, the jiraversions plugin was written to be compatible with almost every automated builder known today. This is accomplished by the use of parameters that can be passed to the builder of choice via the command-line. (how that gets done will be discussed shortly).</p>
<p>So the first thing we need to do is setup our build script to figure out which version it&#8217;s building and use it as part of the package name.</p>
<p><span style="color: #808080;"><em>note: for simplicity&#8217;s sake, I&#8217;m going to use Ant in the examples, but the same method can be applied to anything that can run via a command line. I&#8217;m also going to use java as the language of choice, but again, bamboo and the plugins mentioned in this post can be used to build anything.</em></span></p>
<p>Assuming you already have targets that compile and jar up your project, we just need to add a target that gets the current version for the build and sets it as a property that can be used to append to the name of your jar file.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;get-version&quot;</span> <span style="color: #000066;">unless</span>=<span style="color: #ff0000;">&quot;version.name&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tstamp<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;format</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;build.time&quot;</span> <span style="color: #000066;">pattern</span>=<span style="color: #ff0000;">&quot;yyyyMMdd_HHmmss&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tstamp<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;version.name&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;${user.name}-${build.time}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;version.type&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;user&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;version.released&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Essentially this target is here to handle builds done on a local developer&#8217;s machine.<br />
It&#8217;s saying that if version.name was not passed on the commandline (or set some other way) then set default version properties.<br />
The most interesting property is the version.name which will be set to the user&#8217;s username and a timestamp.<br />
i.e. if I do a build on my local machine, the version will look something like: jdoklovic-2008-Aug-01_130923</p>
<p>Now we need to make sure that our final artifact is named properly. Usually you&#8217;ll have some sort of package target that handles spitting out the final artifact.<br />
In our case the packaging looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;package&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;create-war&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;create-war&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;compile,get-version&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;warfile&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;${ant.project.name}-${version.name}.war&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;warfile.path&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;${dist.dir}/${warfile}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;war</span> <span style="color: #000066;">warfile</span>=<span style="color: #ff0000;">&quot;${warfile.path}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- add the rest of the war task specifics here --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/war<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;auto-build&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;checkbamboo,test,package,publish&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>So there are a few things going on here.<br />
First, we have a target called package that simply depends on a target called create-war.</p>
<p><span style="color: #808080;"><em>Although this isn&#8217;t really neccessary, it&#8217;s useful to have common target names across multiple projects. So if I had another project that creates a jar or a zip file, you would simply adjust the depends on the package target in that project. This way the lazy developers can always rely on running the package target regardless of what it actually spits out.</em></span></p>
<p>Next we have our create-war target.<br />
This target depends on a compile target (which aptly named, compiles our project) and the get-version target we defined previously.<br />
When it creates the war, it uses the ant project name and the version.name as the name of the war file. (real exciting, huh?)</p>
<p>Finally we have a target called auto-build.<br />
I include this target in any of my ant files that will be called from Bamboo. Again, this just makes it simpler to setup in bamboo since you don&#8217;t need to think about which target to run.<br />
This target can do anything you want it to and in my example I&#8217;ve included the bare minimum that I usually need a build to do&#8230;..</p>
<ul>
<li><strong>checkbamboo</strong> &#8211; this simply checks that ${user.name} is equal to the name of the user that bamboo runs as, and fails if it doesn&#8217;t.</li>
<li><strong>test</strong> &#8211; runs unit tests and generates reports</li>
<li><strong>package</strong> &#8211; runs our package target</li>
<li><strong>publish</strong> &#8211; publishes our artifact to our dependency management system (i.e. apache ivy, a maven repo, what have you)</li>
</ul>
<p>Some may wonder why the checkbamboo target exists and if it&#8217;s really useful. Although it&#8217;s very easy to get around, it&#8217;s there as a sanity check when developers are doing builds on their local machines and ensures that a developer does not accidentally publish a locally built artifact to the repository.</p>
<p>Obviously this is not a real and/or complete build file. It&#8217;s simply here to illustrate a basic outline of what&#8217;s needed for the automation to work.</p>
<h3>Got Versions?</h3>
<p>Our next order of business is to get versions setup in Jira.</p>
<p>There&#8217;s nothing special here&#8230;.  simply create a Jira Project, go into the manage versions screen and add the proper versions.<br />
Make sure all of the versions start out as Unreleased and are in the proper order. Bamboo will use the order provided by Jira to determine the latest version.</p>
<p>For our scenario, I&#8217;ve setup a Jira Project named &#8220;My Web App&#8221; with the key WEBMYAPP</p>
<p>My versions initially end up looking like this: (note: waiting to add the bugfix version till later)<br />
<img title="manage_versions" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/manage_versions-300x159.png" alt="manage versions" /></p>
<h3>On To Bamboo</h3>
<p>The last part of the setup is to configure our project in Bamboo. I&#8217;ve already setup my project with the Project Info listed at the beginning of this post, and have tied it to version control (specifically subversion).</p>
<p>Now it&#8217;s time to start configuring the JiraVersions plugin. The first screen we need is in the Configuration &gt; Builder tab. Naviagte to there and click Edit Plan.</p>
<p>In the main Builder configuration, select Ant as your builder and put build.xml in the Build File box.<br />
Now in the Target box, let&#8217;s add our build target and pass the version properties our build is expecting:</p>
<p><strong> </strong></p>
<pre><strong>autobuild -Dversion.name=${bamboo.custom.jiraversion.name} -Dversion.released=${bamboo.custom.jiraversion.released} -Dversion.type=${bamboo.custom.jiraversion.type}</strong></pre>
<p><strong></strong></p>
<p>Our builder ends up looking something like:</p>
<div class="mceTemp">
<dl id="attachment_26" class="wp-caption alignnone" style="width: 310px;">
<dt class="wp-caption-dt"><a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/builder_config.png"><img class="size-medium wp-image-26" title="builder_config" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/builder_config-300x113.png" alt="builder configuration" width="300" height="113" /></a></dt>
</dl>
</div>
<p>Scrolling down on this same screen, click the &#8220;Enable Jira Versions&#8221; checkbox and the Jira Versions options will appear.</p>
<p><strong><span style="color: #000000;">General Settings<br />
</span></strong><span style="color: #000000;">First we need to let Bamboo know where to find our Jira Project by giving it the Jira Project key. You can click the test button to see if it Bamboo can find the project in the Jira server.</span></p>
<p>Next, set the Default Version Strategy to &#8220;Current Unreleased Version&#8221;. This tells Bamboo to ask Jira for the current unreleased version during &#8220;normal&#8221; operation. We&#8217;ll see how to override this later for a single build.</p>
<p>The Null Version strategy tells Bamboo what to do if Jira either has no versions setup, or none of the versions are unreleased (resulting in a null version returned).</p>
<p>The best idea is to set this value to &#8220;Skip and Pass Build&#8221; which will mark the build as successful but not actually build anything.</p>
<p><span style="color: #808080;"><em>note: if we set it to fail the build, then builds that are fully released will fail just because there are no open/unreleased versions which might cause unwanted results in your project dependency chain.</em></span></p>
<p>In the future, you&#8217;ll have even more options&#8230;. (<a href="http://developer.atlassian.com/jira/browse/BJVER-6" target="_blank">BJVER-6</a>).</p>
<p>Now we can setup our version appenders. These let you append any string on to the version name before it gets expanded by any other fields. In our scenario, we&#8217;re going to append the full Bamboo build key (including the number) to the end of unreleased version names.</p>
<p>To do this, set the Unreleased Appender field to: <strong>-${bamboo.buildResultKey}</strong><br />
We&#8217;ll just leave the released appender field blank.</p>
<p><a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/jira_version_general_config.png"><img class="alignnone size-medium wp-image-29" title="jira_version_general_config" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/jira_version_general_config-300x116.png" alt="" width="300" height="116" /></a></p>
<p><strong>Version Types</strong></p>
<p>The version types section allows you to add keywords that will be searched for in the version name and used as the type of release.<br />
The searching uses a similar algorithm as the php version_compare function.</p>
<p>In our scenario we just need to setup dev and rc keywords.</p>
<p><a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/version_type_config.png"><img class="alignnone size-medium wp-image-32" title="version_type_config" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/version_type_config-300x108.png" alt="" width="300" height="108" /></a></p>
<p>We&#8217;re now done configuring the Builder section, so we can click the save button at the bottom of the screen and move on to the Post Actions tab.</p>
<p><strong>Post Build Commands</strong></p>
<p>Uner the Post Build Commands in the Post Actions tab, we need to add a Success Command.</p>
<p>This will be the absolute path on the Bamboo server to the shell script that will be responsible for deploying our app to the various servers.</p>
<p>We will setup the script to accept the properties set by the JiraVersions plugin as well as the Bamboo build result key so we need to pass them to the script here.</p>
<p><strong> </strong></p>
<pre><strong>/opt/bamboo/deploy-scripts/deploy-webapp.sh -n ${bamboo.custom.jiraversion.name} -r ${bamboo.custom.jiraversion.released} -t ${bamboo.custom.jiraversion.type} -k ${bamboo.buildResultKey}</strong></pre>
<p><a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/post_build_script.png"><img class="alignnone size-medium wp-image-34" title="post_build_script" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/post_build_script-300x41.png" alt="" width="300" height="41" /></a></p>
<p><strong>Tagging</strong></p>
<p>Below the Post Build Commands, we can enable the Jira Versions Tagger which will allow us to make tags in our scm system based on some parameters.</p>
<p>In our scenario, we only want to tag successful builds, and since we&#8217;re using subversion, we&#8217;ll need to tell Bamboo where the tags should be made.<br />
<a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/tag_success_builds.png"><img class="alignnone size-medium wp-image-40" title="tag_success_builds" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/tag_success_builds-300x109.png" alt="" width="300" height="109" /></a></p>
<p>Finally, we only want Bamboo to tag Released versions of each version type.<br />
<a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/tag_released_types.png"><img class="alignnone size-medium wp-image-42" title="tag_released_types" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/tag_released_types-300x85.png" alt="" width="300" height="85" /></a></p>
<p>That&#8217;s it for the configuration. Just one more thing to do before we get to the workflow:</p>
<p><strong>Create the Deploy Script</strong></p>
<p>Our deploy script will be responsible for figuring out which environment(s) to deploy to based on the input parameters. The deploy worflow image at the beginning of this post shows what gets deployed to where.</p>
<p>Create a file in the same path as we defined in the post build command. In our case, we will create: <strong>/opt/bamboo/deploy-scripts/deploy-webapp.sh</strong></p>
<p>It should contain something similar to the following code:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># parameter examples:</span>
<span style="color: #666666; font-style: italic;">#  -n 1.2.0-dev1</span>
<span style="color: #666666; font-style: italic;">#  -r false</span>
<span style="color: #666666; font-style: italic;">#  -t dev</span>
<span style="color: #666666; font-style: italic;">#  -k MY-WEBAPP-3</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-x</span>
&nbsp;
<span style="color: #007800;">version</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">release</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">version_type</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">build_key</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">release_env</span>=<span style="color: #ff0000;">&quot;&quot;</span>
&nbsp;
<span style="color: #007800;">mypath</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #ff0000;">&quot;$0&quot;</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #007800;">DEV_ENV</span>=<span style="color: #ff0000;">&quot;dev.mydomain.com&quot;</span>
<span style="color: #007800;">QA_ENV</span>=<span style="color: #ff0000;">&quot;qa.mydomain.com&quot;</span>
<span style="color: #007800;">BUG_ENV</span>=<span style="color: #ff0000;">&quot;bugfix.mydomain.com&quot;</span>
<span style="color: #007800;">STAGE_ENV</span>=<span style="color: #ff0000;">&quot;staging.mydomain.com&quot;</span>
&nbsp;
<span style="color: #007800;">BAMBOO_HOME</span>=<span style="color: #ff0000;">&quot;/opt/bamboo/bamboo-home&quot;</span>
<span style="color: #007800;">dist_dir</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$BAMBOO_HOME</span>/xml-data/build-dir/WEB-MYAPP/dist&quot;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># ~~~~~~~~~~~~~~~~</span>
<span style="color: #666666; font-style: italic;">#   Functions</span>
<span style="color: #666666; font-style: italic;">#     </span>
<span style="color: #666666; font-style: italic;"># ~~~~~~~~~~~~~~~~</span>
&nbsp;
usage<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>
&nbsp;
   <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #cc0000; font-style: italic;">&lt;&lt;EOF
    usage [-opts] deploy-webapp.sh
&nbsp;
     -n [version number] (might be blank) (ex. 1.0.1-dev1)
     -r [released] (ex. true|false )
     -t [version type] (might be blank) (ex. dev, rc, blank for prod)
     -k [build key] 
&nbsp;
EOF</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
deploy <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-x</span>
&nbsp;
   <span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">env</span></span>=$<span style="color: #000000;">1</span>
&nbsp;
   <span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$dist_dir</span>
&nbsp;
   <span style="color: #007800;">box_list</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">eval</span> <span style="color: #7a0874; font-weight: bold;">echo</span> \$<span style="color: #ff0000;">&quot;<span style="color: #007800;">${env}</span>_ENV&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$box_list</span>
   <span style="color: #000000; font-weight: bold;">do</span>
&nbsp;
    <span style="color: #666666; font-style: italic;"># Move new war file out and stop web services</span>
    <span style="color: #666666; font-style: italic;">#</span>
    <span style="color: #c20cb9; font-weight: bold;">scp</span> <span style="color: #007800;">$artifact_name</span> tomcat<span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${i}</span>:<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>
    <span style="color: #c20cb9; font-weight: bold;">ssh</span> tomcat<span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${i}</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> monit stop tomcat_8080
    <span style="color: #c20cb9; font-weight: bold;">sleep</span> 5s
&nbsp;
    <span style="color: #666666; font-style: italic;"># Clean up any leftover Java processes (that were not killed by monit)</span>
    <span style="color: #666666; font-style: italic;"># Move the new war file into the proper place</span>
    <span style="color: #666666; font-style: italic;">#</span>
    <span style="color: #c20cb9; font-weight: bold;">ssh</span> tomcat<span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${i}</span> <span style="color: #c20cb9; font-weight: bold;">killall</span> <span style="color: #660033;">-u</span> tomcat java
    <span style="color: #c20cb9; font-weight: bold;">ssh</span> tomcat<span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${i}</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${artifact_name}</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>tomcat<span style="color: #000000; font-weight: bold;">/</span>apache-tomcat-6.0.16<span style="color: #000000; font-weight: bold;">/</span>webapps<span style="color: #000000; font-weight: bold;">/</span>my-webapp.war
    <span style="color: #c20cb9; font-weight: bold;">sleep</span> 5s
&nbsp;
    <span style="color: #666666; font-style: italic;"># Start up webapp</span>
    <span style="color: #666666; font-style: italic;">#</span>
    <span style="color: #c20cb9; font-weight: bold;">ssh</span> tomcat<span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${i}</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> monit start tomcat_8080
&nbsp;
   <span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># ~~~~~~~~~~~~~~~~</span>
<span style="color: #666666; font-style: italic;">#   Main</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># ~~~~~~~~~~~~~~~~</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Get arguments (passed in from bamboo)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-ge</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">getopts</span> :r:n:t:k: zz; <span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$zz</span> <span style="color: #000000; font-weight: bold;">in</span>
        n<span style="color: #7a0874; font-weight: bold;">&#41;</span>   <span style="color: #007800;">version</span>=$<span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">;;</span>
        r<span style="color: #7a0874; font-weight: bold;">&#41;</span>   <span style="color: #007800;">release</span>=$<span style="color: #000000;">4</span>   <span style="color: #000000; font-weight: bold;">;;</span>
        t<span style="color: #7a0874; font-weight: bold;">&#41;</span>   <span style="color: #007800;">version_type</span>=$<span style="color: #000000;">6</span>  <span style="color: #000000; font-weight: bold;">;;</span>
        k<span style="color: #7a0874; font-weight: bold;">&#41;</span>   <span style="color: #007800;">build_key</span>=$<span style="color: #000000;">8</span> <span style="color: #000000; font-weight: bold;">;;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>   usage; <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">;;</span>
        <span style="color: #000000; font-weight: bold;">esac</span>
    <span style="color: #000000; font-weight: bold;">done</span>
    <span style="color: #7a0874; font-weight: bold;">shift</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #007800;">$OPTIND</span> - <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># If no version number, just exit</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #800000;">${#version}</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
&nbsp;
   <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;(<span style="color: #780078;">`date`</span>) ERROR - no version number - exiting...&quot;</span>
   <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Check if this is a release or not</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${release}</span>&quot;</span> == <span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
&nbsp;
     <span style="color: #007800;">artifact_name</span>=<span style="color: #ff0000;">&quot;my-webapp-<span style="color: #007800;">${version}</span>.war&quot;</span>
&nbsp;
     <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$version_type</span> <span style="color: #000000; font-weight: bold;">in</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#released non-production versions go to DEV and QA</span>
        dev<span style="color: #000000; font-weight: bold;">|</span>rc<span style="color: #7a0874; font-weight: bold;">&#41;</span>
              <span style="color: #007800;">release_env</span>=<span style="color: #ff0000;">&quot;DEV,QA&quot;</span>
              <span style="color: #000000; font-weight: bold;">;;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#released production versions go to STAGE</span>
        <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
            <span style="color: #007800;">release_env</span>=<span style="color: #ff0000;">&quot;STAGE&quot;</span>
              <span style="color: #000000; font-weight: bold;">;;</span>
     <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">else</span>
     <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$version_type</span> <span style="color: #000000; font-weight: bold;">in</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">#Un-Released non-production versions go to DEV</span>
        dev<span style="color: #000000; font-weight: bold;">|</span>rc<span style="color: #7a0874; font-weight: bold;">&#41;</span>
            <span style="color: #007800;">release_env</span>=<span style="color: #ff0000;">&quot;DEV&quot;</span>
            <span style="color: #000000; font-weight: bold;">;;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">#UN-Released production versions go to BUGFIX</span>
        <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
            <span style="color: #007800;">release_env</span>=<span style="color: #ff0000;">&quot;BUG&quot;</span>
            <span style="color: #000000; font-weight: bold;">;;</span>
     <span style="color: #000000; font-weight: bold;">esac</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Release code to requested environments</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$release_env</span>
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\t</span>(<span style="color: #780078;">`date`</span>) Releasing to <span style="color: #007800;">$i</span>&quot;</span>
    deploy <span style="color: #007800;">$i</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<h2>Go With The Flow</h2>
<p>Now that everything is setup, we&#8217;re ready to go through the basic development cycle workflow.</p>
<p>This is pretty straight forward with only a few things to watch out for&#8230;..</p>
<p>So let&#8217;s get started. Per our versions, we&#8217;re starting with iteration 1 of our webapp project.</p>
<p>Generally, we will be adding new features in our iterations based on User Stories that are entered into Jira.</p>
<p>As we close out Jira issues and commit code, Bamboo will build our unreleased dev1 version for us.</p>
<p>We can check the status of all version builds by going to the Jira Versions tab for our build plan. After the first checkin, the Jira Versions will look somethin like the following:<br />
<a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/jv_ur_dev1.png"><img class="alignnone size-medium wp-image-47" title="jv_ur_dev1" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/jv_ur_dev1-300x227.png" alt="" width="300" height="227" /></a></p>
<p>After our iteration is finished, it&#8217;s time to release dev1. This is a 2 step process.</p>
<p>First, go into the manage versions screen in Jira and click the release link next to the 1.0.0-dev1 version.</p>
<p>Second, go to the Jira Versions tab in Bamboo. We will now see the released dev1 version with a link that will let us do a manual build.</p>
<p>We need to kick off the build manually because Bamboo is now going to be building the un-released dev2 version when code commits happen. Thus,<strong> it is important to do this manual build as soon as you release the version in Jira to make sure that no commits happen after the release</strong>.</p>
<p><a rel="lightbox" href="http://blog.sysbliss.com/wp-content/uploads/2008/08/jv_r_dev1.png"><img class="alignnone size-medium wp-image-48" title="jv_r_dev1" src="http://blog.sysbliss.com/wp-content/uploads/2008/08/jv_r_dev1-300x58.png" alt="" width="300" height="58" /></a></p>
<p>At this point, we just follow this same process for all of our iterations. When we are ready to release the final iteration version, we need to do one extra step: merge the dev versions into the first release candidate.</p>
<p>Merging will do a couple of things for us. It will allow users to see everything that has been included in the release candidate. It will also remove the merged version from the Jira Versions tab in Bamboo.  This makes it impossible for someone to accidentally re-build an already released dev version.</p>
<p>You can still get to the old builds by going to the Completed Builds tab in bamboo.</p>
<p>To merge, you simply use the merge links in the Manage Versions section of Jira.</p>
<p>Once our iterations are complete and we move on to the first release candidate, the workflow remains the same&#8230; commit, Babmoo builds, release when ready.</p>
<p>When we reach the point of releasing the final release candidate, we again need to merge. This time we will merge all of the rc versions into the production version. From here, we just go along the workflow as normal and release the production version when ready.</p>
<p>Throughout the development cycles, you shee see the following:</p>
<ul>
<li>Builds appearing in the Jira Versions tab</li>
<li>Un-released versions being deployed to the development server.</li>
<li>Released versions being deployed to the development and QA servers</li>
<li>Released versions being tagged in subversion</li>
<li>Un-released Production builds being deployed to the bugfix server</li>
<li>Released Production build deployed to the staging server.</li>
</ul>
<p>If everything is good to go on the staging server, we can then manually deploy it to the actual production server. This is left as a manual process just to ensure that a human is watching the process and making sure it goes ok.</p>
<p>Finally, if there are emergency bugs that need to be fixed in production without a full development cycle, we can simply add a new version in Jira called 1.0.1</p>
<p>From there, we just do the normal process of committing code, releasing when ready, manually building the released version and manually deploying from staging to production.</p>
<p>And there you have it. However, there&#8217;s more&#8230;&#8230;</p>
<p><span style="color: #ff0000;"><strong>Beware of Null Versions<br />
</strong><span style="color: #000000;">We have our build set to pass with success if there are no versions returned from Jira. This is useful for dependency builds that need to complete within a larger build tree, however, this means a new development rule must be followed:</span></span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;"> <strong>No code should be committed to a project without an unreleased version.</strong></span></span></p>
<p>If code is committed, bamboo will see the change in the scm and try to run a build, but since no version will be returned by Jira, it will simply do nothing but look successful.  This is not the optimal scenario and <a href="http://developer.atlassian.com/jira/browse/BJVER-6" target="_blank">BJVER-6</a> aims to make this a little more fool proof.</p>
<p>It&#8217;s also a good idea to create a subversion commit hook that checks Jira for an unreleased version and fails the commit if it doesn&#8217;t find one.</p>
<p><span style="color: #808080;"><em>I will post a link to the subversion pre-commit hook once I get it finished.</em></span></p>
<p>I hope this post was helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sysbliss.com/uncategorized/release-management-with-atlassian-bamboo-and-jira.html/feed</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>Sysbliss wins Atlassian Codegeist for Bamboo</title>
		<link>http://blog.sysbliss.com/uncategorized/sysbliss-wins-atlassian-codegeist-for-bamboo.html</link>
		<comments>http://blog.sysbliss.com/uncategorized/sysbliss-wins-atlassian-codegeist-for-bamboo.html#comments</comments>
		<pubDate>Fri, 20 Jun 2008 14:16:55 +0000</pubDate>
		<dc:creator>jdoklovic</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.sysbliss.com/?p=7</guid>
		<description><![CDATA[My Pre/Post Build Command plugin won the Atlassian Codegeist III Contest.
From the announcement:
This is terrific plugin that enables all sorts of new possibilities for Bamboo. It&#8217;s one of those gateway plugins that opens up a whole new category of customizations.
The full announcement can be viewed on the Atlassian Blog
]]></description>
			<content:encoded><![CDATA[<p>My Pre/Post Build Command plugin won the Atlassian Codegeist III Contest.</p>
<p>From the announcement:<br />
<cite class="shutter" dir="ltr">This is terrific plugin that enables all sorts of new possibilities for Bamboo. It&#8217;s one of those gateway plugins that opens up a whole new category of customizations.</cite></p>
<p>The full announcement can be <a href="http://blogs.atlassian.com/developer/2008/06/finally_the_results_of_codegei.html">viewed on the Atlassian Blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sysbliss.com/uncategorized/sysbliss-wins-atlassian-codegeist-for-bamboo.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bamboo 2.0 Pre/Post Command Plugin</title>
		<link>http://blog.sysbliss.com/uncategorized/bamboo-20-prepost-command-plugin.html</link>
		<comments>http://blog.sysbliss.com/uncategorized/bamboo-20-prepost-command-plugin.html#comments</comments>
		<pubDate>Fri, 09 May 2008 14:42:40 +0000</pubDate>
		<dc:creator>jdoklovic</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.sysbliss.com/?p=5</guid>
		<description><![CDATA[A new version of the Bamboo command runner plugin is available:
http://confluence.atlassian.com/display/BAMEXT/Pre-Post+Build+Command+Plugin
The bamboo 1.2.4 version was updated so PRE-build commands can now be specified.

A new 2.0 version was created as well.
]]></description>
			<content:encoded><![CDATA[<p>A new version of the Bamboo command runner plugin is available:<br />
<a href="http://confluence.atlassian.com/display/BAMEXT/Pre-Post+Build+Command+Plugin">http://confluence.atlassian.com/display/BAMEXT/Pre-Post+Build+Command+Plugin</a></p>
<p>The bamboo 1.2.4 version was updated so PRE-build commands can now be specified.<br />
<br />
A new 2.0 version was created as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sysbliss.com/uncategorized/bamboo-20-prepost-command-plugin.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
