Automated builds have become a cornerstone of agile development. Every time a developer checks in a change, a tool like Cruise Control checks out all the sources, builds everything, runs all the unit tests and reports back with immediate feedback. This cycle has become known as Continuous Integration, due to the seminal paper by Martin Fowler and Matt Foemmel, but this is something of a misnomer. It is better described as Continuous Build. (Their use of “integration” was about integrating all the bits of software that the various programmers in a team would traditionally be working on in isolation from one another, only to bring together and spend days or weeks getting to work. Practices such as pairing and automated builds have all but eliminated this form of integration hell, at least on agile projects.)
However, delivering an application is more than just writing and testing software. The code lives in a container or application server, which runs in an operating system, on hardware, on a network, behind a firewall, connected to other machines, services and components, which may themselves be inside containers or application servers, and so on across your application, across your enterprise and maybe out into the wide world to other enterprises and other servers.
Application-level integration is a complex beast. It involves gluing together all the components of an application such as databases, messaging infrastructure, external services, upstream and downstream feeds and third party dependencies.
Integration testing can be automated too
This is where most of the risk and most of the surprises are as you move from development towards deployment into production. If you can test this integration early in your project and revisit it incrementally as your requirements and system evolve you will be in a much better position later on. Firstly you have proven that the pieces all fit together. Additionally you have now practiced integration and deployment a number of times, and automated the boring/repetitive/error-prone parts so you will be less fearful of it.
It is a testament to the success of automated builds that we even get to consider automatically verifying these infrastructure pieces. Of course there is independent value in having a continuous, automated build that assembles your code and tests it in isolation, as countless agile projects will attest. But don’t let the term “continuous integration” blind you to the fact that you can also automate integration proper and address one of the biggest risk areas in a software project early and incrementally.
Deploy to production like you deploy to development
A nice corollary to automating integration and deployment of your application into a development environment is that it suddenly becomes much easier to deploy it into any environment. So why not share the love? My experiences in putting an application live and verifying that it is correctly deployed and working have traditionally been high-risk, high-stress, fingers-crossed occasions with heroic Ops guys working late into the night to fix the firewall / server / permissions / JDK version / DNS / user account / port numbers / router / you-name-it.
Imagine the quality of life and subsequent showering of small gifts that would accompany a fully-automated, fully-tested deployment process. To be fair, it does make release day something of an anticlimax, and you feel that you hardly deserve the curry or pizza for pitching up on a Saturday. (Let’s face it, you could have pressed the button from home; you know it’s going to work because you already validated the environment and you’ve deployed the app literally hundreds of times before.)