Continuous Integration and Deployment
Having just discussed version control, it's time to announce which VCS mistake I see more often than any other - the mistake that's made by everyone (myself included), regardless of their experience or expertise. And the winner is…
Adding new files to a project but forgetting to add them to the repository.
I don't do this very often - maybe less than once per month. But whenever I do, when the other developers on the team synchronize their repositories, we're left in a situation where everything works for me, but they can't build.
If we're lucky, the error will report that the file wasn't found, and we can quickly resolve the problem. If not, there'll be some other error about a missing symbol or something that will take time to track down before discovering the root cause.
If only we had some form of robot that would see every check-in, grab the source code, and try to build the product. If it couldn't do that, it'd be great if it came over and complained to the person who made the change that broke the build.
It turns out that we've been living in the future for quite a while now, and that robot already exists. It goes by the name of Continuous Integration, or CI.
Why Use CI?
Finding those missing files isn't the only thing CI is good for. If you have automated tests (see the Chapter 5, Coding Practices), a CI system can run the tests on every change and report any problems. My team's CI server is configured to run the analysis tool (discussed in this chapter) and consider a build failed if that tool discovers any problems. Some projects automatically generate API documentation and publish it to a web server.
It can even make the build available for people to install once it's passed all of the tests. This is related to the idea of Continuous Deployment: if a version of the software seems good enough to use (that is, it doesn't fail any test you put it through), then start using it. You may still find problems that weren't exposed by the automated tests, but you'll do so earlier than if you didn't deploy right away.
A final benefit to CI - one that's quite subtle but very useful – is that it forces you to set your project up so that it can be checked out of version control and built automatically. This means that even when a human programmer is working with the project, it's easy for them to get set up with the source and start being productive. That person could be you, when you get a new laptop. It could be a contractor or a new employee joining the team. Either way, if there's a single step to fetch the project and build it, then they'll be up to speed quickly, rather than asking you how to fetch some library or configure some plugin.
CI On Real Teams
Some teams I've worked on have been so heavily invested in using CI that they've employed someone to maintain the CI infrastructure (it's not a full-time occupation, so they usually look after other supporting tools and consult on their use). In other teams, it's been up to the developers to keep it running.
The difficulty in that second case is in knowing when to look after the CI versus doing project work. As an example, in the month before this section was written, I had to migrate my team's CI system onto different hardware. Despite trying to ensure that the configuration of the system didn't change between the two environments, the tests in one of the projects would no longer run.
The thing is, the tests worked fine in the IDEs on all of the developer machines. Is it really important to take more time away from adding value to the products our clients are paying for to handhold some confused robot?
I consider running without CI to be proceeding at risk these days. Yes, I could avoid all problems without it. Yes, it's possible that nothing will go wrong. But why take the chance? Why not spend that little extra to ensure I discover problems as early as possible? It's spending a little now to potentially save a lot in the future. I therefore try to find the time to maintain the CI service when it's necessary.