Showing posts with label deployment. Show all posts
Showing posts with label deployment. Show all posts

Wednesday, May 11, 2011

Displaying Build Numbers in Grails Apps

Being a fan of Continuous Delivery, identifiable builds, and Continuous Integration: I like to deploy web apps with a visible build number, or some other way of identifying the version. For example, having the build number on the login screen for example. In the Maven/Java world, this is straightforward. Or at least I know the idioms. I struggled with this a bit while working on a Grails app,  and wanted to share my solution. There may be other, better, solutions, but the ones I found approaches that didn't quite work they way that I'd hoped.

My requirements were:
  • To display a build number from my CI tool, where the number was passed in on the command line. In Bamboo, for example you might configure a grails build as
    -Dbuild.number=${bamboo.buildNumber} war
  • To only change build artifacts and not any source files.
  • To not misuse the app version, or change the names of any artifacts.
  • To be simple and idiomatic.
I realized that that Grails itself changes the application metadata (application.properties) when it does a build. So I modeled this approach after code in one the gant scripts in the Grails distribution.
The steps are:
  • Hook into a build event to add a property in to application.properties.
  • Access the property using the gsp tag.
  • Pass the value into the the grails war command using a Java property.
To create the event hook, create a file in your project/scripts directory called _Events.groovy that contains a method like:

eventCreateWarStart = { warName, stagingDir ->
    def buildNumber = System.getProperty("build.number", "CUSTOM")
    println("Setting BUILD_NUMBER to "\+ buildNumber)
    ant.propertyfile(
       file:"${stagingDir}/WEB-INF/classes/application.properties") {
         entry(key:"build.number", value:buildNumber)
   }
}

Then you can access the property with a GSP tag like this

<g:meta name="build.number">


And you can now display build numbers (or any other properties that you want to pass in from you CI system) in your Grails app. This worked for me with Grails 1.3.7. The only down sides are:

  •  This works on a per-project basis (That is probably easily fixable)
  • The properties that we set are hard coded. (this could be fixed with a convention  that iterates through all of the system properties that start with "build" for example).
I welcome any suggestions for improving this, or alerts that I'm using the entirely wrong idiom :)

Thursday, December 23, 2010

Continuous Delivery

Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation (Addison-Wesley Signature Series (Fowler)) If you didn't already know that the key to reliably deploy quality software is to take a cross-functional, full-lifecycle approach, Jez Humble and David Farley's book Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation will help you to understand. Much like Jim Coplien describes in  Lean Architecture: for Agile Software Development the "secret" to successful lean projects is to work with "Everyone, All Together, from Early On."

While the authors have experience in, an a pre-disposition for, agile techniques, the principles described in  this book apply to any organization, whatever the process,  though if you take the approach to heart, you will find yourself becoming more agile, which is to say, more responsive to customer needs.

The book  covers the full lifecycle from requirements, and design, and coding, to acceptance testing, deployment and operations. There are even discussions on test design, data migration and performance optimization and capacity planning. All of this underscores the point that the goal of building software is delivering it to users, a point which some other books understate. Continuous Delivery develops the concept of a Deployment Pipeline, showing you the impact development and testing practices have on deployment and operations, and emphasizing the value of involving the operations team early in the development process.

There is a lot of material here, but there are also pointers to other resources. In the SCM and release management are, the authors build on works including Software Configuration Management Patterns: Effective Teamwork, Practical IntegrationRelease It!: Design and Deploy Production-Ready Software (Pragmatic Programmers) and Configuration Management Best Practices: Practical Methods that Work in the Real World.

Not only do you walk away from  this book with an understanding of how to start implementing a continuous deployment pipeline, you may also find yourself writing down a list of things to try, and tools to use. While not a tool-centric book, the authors provide many examples of tools to help you implement each phase of the process.

Having written about the version and release management process before, and how it relates to architecture and organization, I was excited get a review copy and see the authors give a thorough discussion of how the SCM and Release Management practices relate to the rest of the software development ecosystem.

While having a lot of material, the book is well organized and written. It's not a quick read, and you'll want to have a notebook or post-its handy to capture the idea it helps you to generate, but if you are interested in improving your deployment process you will find this book very valuable, whether you are a developer, tester, release engineer, or someone who manages people in those roles. When you finish this book you will not only have knowledge about how to implement a deployment pipeline, but  also the encouragement to know that it is possible, no matter how complex your project might seem.

Sunday, April 11, 2010

Things about Release Management Every Programmer Should Know

As I mentioned earlier I was privileged to contribute to the book 97 Things Every Programmer Should Know: Collective Wisdom from the Experts. In addition to the contributions about coding and design, I was pleasantly surprised to see the number of items that relate to release management. While I've long been interested in how to build architectures and processes that make deploying and releasing software easy, I sometimes get the impression that these items were often though of necessary evils that could be done at the end, often by the someone who isn't doing "more valuable work." Much like awareness of agile software development made it obvious that testing and quality assurance activities work best when they are integrated throughout the development lifecycle, agile has also made it more obvious why build and release engineering is something to work on as you go. This makes a lot of sense, as ease of release is closely tied to the physical architecture of the system, and your build process defines the physical architecture.

Some of the posts of interest are the following, though I could have added others than related to testing as well.
  1. Deploy Early and Often by Steve Berczuk
  2. Install Me by Marcus Baker 
  3. Keep the Build Clean by Johannes Brodwall
  4. One Binary by Steve Freeman
  5. Own (and Refactor) the Build by Steve Berczuk
  6. Put Everything Under Version Control by Diomidis Spinellis
  7. Step Back and Automate, Automate, Automate by Cay Horstmann
Aside from being excited that programming experts understand the importance of build, release, and installation mechanisms, I was also excited to see that one topic that people associate with SCM wasn't mentioned: Branching.

Branching is a useful tool when used in the right context, but more often than not, branching is used as a way to avoid issue rather than to address them. Rather than branching because there is a true divergence in the code, we branch to avoid breaking existing code. The problem is that doing so simply defers a cost. Sometimes deferring the cost makes sense. Often it's better to invest in the techniques you need to enable incremental change while keeping the codeline working.

97 Things Every Programmer Should Know is about much more than just coding, or just release management. And that's the point: programming is a multi-faceted skill and to write good code, you need to know about more than just writing code.

Sunday, July 12, 2009

Begin with the End in Mind: Deploy Early

In many projects I've worked on the task of developing a deployment process is deferred until close to the release date. This is a bad idea. Deferring deployment-related decisions adds risk to a project as deployment to a target environment exposes development time assumptions and operational requirements that may need to be addressed by the engineering team before an application is released.

I suggest that a project develop (and use) a process to deploy the software to the target platform in the first iteration. Starting on deployment early gets you closer to the agile goal of shippable code at the end of each iteration.

Deployment is important, and something for which there should be a story in your process early on because:
  • Deployment is the first thing a customer sees, but it's only an enabler, it doesn't directly deliver value, so you'd like for the process to be efficient. Incremental improvement of the process is a great way to make it work well.
  • Design decisions can have an impact on the deployment and configuration process, and deployment models may suggest a different design
  • Thinking about deployment early means that you'll have an identifiable, repeatable process. this will make your testing process more valuable.
By a deployment process I mean the mechanism for delivering your software to, and making it usable by a customer (or intially to a QA Team), including any required configuration steps. This process can be as manual or as automated as you like, ranging from a zip file and a README, to a fully automated installer. You can start simple and automate more as you get feedback.

Developing a deployment process early can look like Big Design Up Front if you start out with too detailed of a process that involve guesses about things you just don't know at the beginning of a project. But remember: you can change the process as you learn. Start with a simple process and change and refactor the process as you go to make it more suitable to the target user's needs. You may discover that a manual process works well enough, or you may find that adding some automation make the process simpler and lower risk with little added cost. If you have a test team that is using the deployed artifact, you may find that you can leverage automation developed to support test related deployments and use it in your customer process.

Deploying early and often can also improve your architecture too, as deployment exposes issues about the system architecture that are easy to overlook in an development environment. How the application is designed affects how it can (and should) be packaged (and the reverse is also true). While another groups may be responsible for the operational aspects of deployment, the engineering team is responsible for making the process work in a real environment. Consider configuration as just one example. Using a build tool like Maven or Ant, it's a simple matter to keep a number of configuration files in synch by using filtering, and passing a property in to the build. Once you deploy a package that needs to be configured at a customer site, the fact that there are now many configuration files that need to be edited in the same way becomes an obvious source of wasted effort and possible error.

Even seemingly trivial issues such as how to configure logging in production to debug a problem can influence, the choice of logging framework. The sooner you see the problem, the easier it is to fix with less risk. Michael Nygard 's book Release It, covers some of these issues and is an excellent resource for information about how to build software that can be deployed into production effectively.

Like all things agile, you can start small, and take small steps towards the end result. They key things to consider are:
  • Packaging: have the build generate a deploy-able package. This can be used for Integration Testing, demo environments, and the like.
  • Configuration: understand what parameters need to configured and how to configure them. The first pass could be build properties that are filtered into configuration files. Move towards understanding what needs to be configured at deploy time at a customer site.
  • Requirements of the target platform and operations teams: How automated does the process need to be?
Even if you don't know all of the details of the production deployment, frequent early developments help you to understand what issues you need to decide, and which you can defer. And if you really do understand what you need to do, you may as well give it a try sooner rather than later. At best you'll be validated. At worst, you'll have lots of time to address issues.

Lessons in Change from the Classroom

This is adapted from a story I shared at the Fearless Change Campfire on 22 Sep 2023 I’ve always been someone to ask questions about id...