Posts Tagged ‘Hudson’

h1

Deployments should be non-events

May 15, 2010

The problem with “traditional” release management

I say “traditional” release management for the lack of a better categorisation. What I mean by that is having separate phases (and teams) for development, system test, user acceptance test (UAT) and finally production. The problem is that it just takes too long after the developer commits his code until it gets eventually deployed to production. In my experience, this is mostly due to delays in hand offs from one phase to another. And as we all know, thanks to Lean Thinking this is waste.

Why you (as a developer) should care

The deployments to these different environments are usually stressful, because they bare some amount of risk of taking down the system you are deploying to. And the closer you get to production, the higher the penalty for doing so becomes. Because of this risk, deployments usually take place when potential problems would have the least impact on the users of these environments, which in general happens to be out of business hours. And last but not least, deployments tend to be boring and tedious tasks. Or did you ever get excited about doing a release? Yeah, that’s what I thought.

Why you (as a manager) should care

Of course, you also care about the factors mentioned above, because you want your developers to be as happy as possible, right? But furthermore, you especially dislike the risks associated with deployments, because you have to factor them into all sorts of calculations. Additionally, all these delays between phases mean that your time to market for new features and bug fixes is way higher than it needs to be, which means you are loosing money. Constantly.

The obvious solution

It’s easy, right? The answer is continuous deployment. You fully automate your testing and deployment and you deploy straight to production after every commit. Sounds great. The problem is: Most organisations are not ready for full test automation or just not willing to give up manual testing. This may be for security or legal reasons, potential loss of revenue and/or reputation or something else. Bottom line is: Pure continuous deployment into production without any manual testing is not widely accepted. Period. I am not saying this goal is not worth aiming for. Trust me, I am all for it. I just don’t see it happening in the near future in most companies. In my opinion, the only way to practice continuous deployment into production is by having sophisticated real-time alerting combined with a system with built- in resilience. This would allow you to automatically detect and back out a failed deployment without an interruption of the system as a whole. Have a read of this blog post about how the guys at kaChing managed to achieve this.

A step in the right direction

Don’t worry, not all is lost. Even if continuous deployment is not achievable for you right now, that doesn’t mean you can’t improve your situation at all. You can take the first steps towards continuous deployment by decreasing the batch size of deployments and automating the deployment and hand-offs between the environments.

  • Decreasing the batch size should be easily achieved by just allowing automatic deployments into your first test environment. Only, of course, after a successful build that runs all your automated tests.
  • Automating the deployment may require some tailored scripts to suit your system. However, if you are using Hudson and your deployment artifact is a war or ear file you can use the deploy plugin, which is based on Cargo.
  • Automating the hand-offs could be achieved by using a central release management dashboard that is used by developers, testers and managers.

So far I haven’t found any Hudson plugin that would provide this. What I have in mind is something like the following:

  • Deployments can be configured to happen automatically or to require manual approval.
  • When deployment to an environment finishes, a configured set of people gets notified
  • The different environments where the application is running can be accessed directly from the dashboard
  • When approving a build, and all previous builds have been approved as well (there might be dependencies), deploy to next environment.
  • When rejecting a build
    1. A tester raises one or more issues for the build. The issue tracking system is tightly integrated in the dashboard and can be reached via a link, which pre-fills relevant fields about the current build and project. This automatically rejects the build.
    2. The developer that committed the change that triggered the rejected build gets notified.
    3. The developer fixes the issue (after creating a failing test to expose it, of course).
    4. The developer commits the fix with reference to the issue in the commit comment. This triggers a new automatic build, plus an automatic update of the issue and a notification to the tester who raised it (like the Trac SVN Policies Plugin).
    5. When the tester approves the new build the old build gets automatically approved as well, if this was the last outstanding issue for the old build.

In my mind it looks somewhat like this (click image to enlarge):

Release Management Dashboard

In order to do pure continuous deployment you could then configure the dashboard with only one environment (=production) with automatic deployment. You can, however, choose to set up as many intermediate environments as you like and also require manual approval of deployments to any of them.

Does anyone know if a Hudson plugin with this functionality exists or is in the making?

With this in place I believe deployments can be non-events, in the meaning of being effortless and stress free. This does not mean you should stop celebrating your releases, though.

h1

Java Build Server

January 23, 2010

Update [15.05.2010]: I finally had a chance to try out SecureCI, which is pretty much exactly what I described in this post. The guys from Coveros did a great job, so I suggest after reading this post you head over to their website, download SecureCI and give it a go. Thanks John for pointing this out to me.

In my last Java project, I set up a build server with Continuous Integration (CI) capability. I am a big fan of Test Driven Development (TDD) and I quite enjoyed Hudson telling us right away when someone checked in code that broke the build. It just gives you so much more confidence in your code and keeps it releasable at all times. In addition, we used Sonar to measure the quality of our code. I found it quite interesting to study how the different metrics changed over the course of the project. We paid particular attention to code coverage and tried to keep it as close to 100% as possible. This should happen naturally anyway if you are practicing TDD.

Setting all this up was a good experience to learn how it all fits together – But I learned my lesson and I don’t really want to do it over and over again. So, I started looking for a Virtual Appliance that had most, if not all, of these capabilities. Setting up a build server must have been done by other developers a million times before. Surely, someone along the way stuck it all on a Virtual Machine (VM) and made it open source, right? Well, that’s what I thought, but I couldn’t find any. So, I decided to create one myself. Unfortunately, I am lacking the hardware to do so at the moment. I have even already created a project for it on https://launchpad.net/java-build-server. Although, I haven’t come around to create the VM yet, I still wanted to share my idea here to maybe animate someone else to go ahead and give it a go. So here it is: my idea of a Java build server.

I planned to start with what I think of as a good enough build server: A VM based on Ubuntu Server JeOS with pre-configured installations of Subversion (Source Control), Hudson (Continuous Integration), Sonar (Quality Metrics), MySQL (to store Quality Metrics), Maven (Build) and Nexus (Enterprise Maven Repository). Once this is all working I am going to also install Trac (Wiki and issue tracking system). You might of course have your own preferences for tools to use for the tasks listed above. Feel free to swap out whatever tool you wish. You might already have an enterprise Maven repository. Fine, just use your existing one. All I am saying is, these tools will be on my build server VM; pre-configured as much as possible with standards found in the tools’ documentation, following the convention over configuration paradigm.

Creating the VM

Here is how I am planning to create my Java build server VM. I am using VMware Studio to create the VM. VMware Studio is a Virtual Appliance itself and I deployed it in VMware Server 2.0. First I created a basic VM based on Ubuntu 8.04.1. Studio automatically installs VMware tools and embeds an in-guest management component called Virtual Appliance Management Infrastructure (VAMI), which lets you configure the network settings of your VM after it has been built. This is essential, since you want your development team to be able to connect to your copy of the build server VM. Here is a list of the essential settings I used to create the base VM:

  • ubuntu-8.04.1-dvd-i386
  • 1 CPU
  • 512 MB RAM
  • 8 GB
  • Network settings: DHCP (to automatically find an IP address)
  • Target format: zip

After the build finished, I downloaded the zipped VM and deployed it on my VMware Server instance. I started the VM and assigned it a static IP address on the boot screen. I logged in and carried out the following steps:

Using the VM

Of course there are some project and company specific configurations that cannot be set in advance. Here is what is left to do:

  • Install a VM container on a server (e.g. VMware Server)
  • Download and start the VM in your container
  • Set the network details on the boot screen
  • Add your developers as users to Subversion (in /usr/local/svn/passwd-team)
  • Create a project
  • Create Hudson jobs to monitor your project

What’s next?

To make using this Java build server even easier I am also planning to create the following:

  • a Maven archetype that only needs the IP address of the build server to be configured
  • a script to create a new project on the build server (create SVN project, create Hudson jobs, etc.)
Image by indigoprime via Flickr