If your version of continuous integration is just daily builds, ignoring failed tests, or not testing at all, you're doing it wrong.
(I’d like to start with a thank you to Jimmy Buffett, as I listen to “A pirate looks at forty” while I write this post…)
I visit a lot of different development teams, and at some point the subject of continuous integration comes up. Shortly after that comes the conversation around continuous integration tools. That usually gets kind of religious, but it is absolutely worth talking about. The conversation tends to follow a similar track. Usually it is something to the effect of “Well, we have a CI server, and we use it for our daily builds, but that’s about it. Then when I ask what else they want to get from their CI tools, I usually get either a blank stare or a long story about what would be awesome if they:
- Had more time.
- Had someone whose entire job was to manage the continuous integration environment.
- Were at a different company.
So this got me thinking, as a Craftsman, how do I feel about this, and how do I feel about continuous integration in the first place? I came up with a few thoughts.
Daily builds are NOT continuous integration
It is often said in Extreme Programming circles that Daily Builds are for Wimps. I don’t know if I’d go that far, but I will say that daily builds are nowhere near frequent enough. One of the primary values we gain from CI is the ability to have very short feedback loops. If I only find out once a day whether or not the work I did fits with the rest of the code base, then I am adding at least eight hours of latency to my system. In most cases, more than that, since “daily builds” are actually nightly builds, leaving us open to walking in each morning to an ugly mess. And don’t even get me started on weekends!
It’s much easier to find and fix a small changeset, say a few lines and a couple tests, than to have to go back through an entire day’s work to find the error or errors. And this problem is compounded if you have a larger team, or worse, a couple of teams using the same code base. Now you have many levers to pull and dials to turn before you can find what really broke.
Or yet worse, you will have committed a day’s worth of work and then found out the next day that someone else committed something that completely nullified your work.
A continuous integration process is more than just the build
I actually am surprised that in this day and age there are teams that believe their job is done if the code compiles, without running any tests. Every continuous integration tool out there provides for automated unit testing at a minimum, usually far more than just that. A good CI process includes continuous Unit Test, and ideally continuous Acceptance Test as well.
I know, you are thinking “Here we go again, another push for test-driven development and automated acceptance tests.” You’re right. Any true Craftsman uses all the tools and modern techniques available to them. That means unit tests that run every time you check in. And automated acceptance tests that run after that. A good CI process includes all of the appropriate elements.
It’s not enough to just push to your GitLab repo and have the server run a build. The days of “If it compiles it ships” are long gone. And that’s a good thing. We have a responsibility to be better than that, and modern tools and techniques make that possible. I would much prefer a CI process that includes:
- Kickoff on every check-in. This is especially easy with modern repos like GitLab that provide hooks and integrations with all of the major Continuous Integration tools.
- Build all of the code and libraries.
- Run all of the unit and acceptance tests.
- Report on any errors, preferably failing the build if they occur.
We can talk about going further into continuous delivery and deployment later, but those can be managed in the same way.
Listen to your continuous integration server
The proper response to a notification from your CI environment that the build or one of the tests failed is not to find the offending test and #ignore it. A failed build notification means “Everybody stop! The build is failing so our environment is technologically unsafe until this gets fixed!” Take that message seriously. Everybody stop. Find out what went wrong, and fix it. And only then do you continue with business as usual.
If we as Craftsmen see our job as to create the best software possible for our customers, we need to take these things seriously. We can either have a “CI Server” that does daily or even less frequent builds, and check the box, or we can be serious about what we do. We have a lot of tools available, and if we choose the best tools we need to use them to their fullest extent. That is how we become truly great at our Craft.
About the guest author
Steve Ropa is a Co-founder and Master Craftsman at the Rocky Mountain Programmers Guild in Denver Colorado, where he brings his long career of successful software delivery to bring developers and teams to new levels of performance and Craftsmanship.