Blind spots have a way of coming back to bite you down the road. When building software, the size of that “bite” grows exponentially with time.
What if I told you that your team doesn’t need the latest innovation in tooling or methodology, but rather a better understanding of an idea that dates back to the 1990s, to virtually eliminate blind spots? That idea is continuous integration (CI).
The Continuous Integration Blind Spot
Thinking you are doing CI, when you aren’t, means your team is more likely to be wading through mud and going in circles than achieving meaningful impacts on your business. Oh, and you can pretty much forget about moving on to CD and achieving stats like the “Elite” group in the DORA report any time soon.
There are two blind spots to deal with here: the first is of our understanding and application of CI, and the second, which directly results from the first, is the collection of hidden conflicts and bugs that lurk in our work in progress because we’ve implemented an incomplete vision of CI.
The good news is that the solution is simple, the patterns are well understood if you know where to look, and while you could pull off CI with little more than an old developer box and a rubber chicken, there are innovations in tooling and methodology that are making all of this much easier. First, let’s figure out what’s missing by having a look at two lists.
Am I Really Doing Continuous Integration?
If you identify as a shop that does CI, this first list should be pretty easy to read and reflect on. I’m betting that your team does at least the first two things on this list and possibly all three:
- Check-in code to a centralized source code repository: Git, GitHub, Bitbucket, SourceForge
- Automate build and test with a continuous integration server/service: Jenkins, Bamboo, Circle CI, TeamCity, GitLab, Azure DevOps, Travis, Team Foundation Server
- Always have a working build
Ooops. Wrong List. Try This One Instead
Warning: unless you are one of a very fortunate few, this second list won’t be as fun to read as the first. While reading it, you may suddenly have the urge to debate the merits, pick at my words, or explain why it “just can’t be done” in your environment. But you are here, and my intentions are good, so let’s give it a go shall we?
- Merge all code to a shared trunk (AKA main) at least once per day
- Build and test the shared trunk/main after every commit
- Repair broken builds of trunk/main within 10 minutes, while halting further commits until the build is fixed.
Let’s drill into the differences between this list and the first one:
- This time we said, “all code” (not just some “code”) and “shared trunk” (not a branch) and “at least once per day” (not at the end of the week, the end of the sprint or when I think I’m done).
- This time we clarified that we would build and test that shared trunk “after every commit” (not nightly, or weekly, or during a hardening sprint).
- Finally, this time we didn’t just say to have “a” working build, but that any time the shared build fails, we will focus on fixing that build before doing anything else.
This second list (without the detail about halting further commits) is precisely what Martin Fowler proposed as a tongue-in-cheek “Continuous Integration Certification Test” based on criteria from Jez Humble:
Blind Spots Removed, We Can Actually Do This
The reason so many of us have CI blind spots is that we skipped the “why” and went directly to the “how” — the reason to do CI is to never go more than a few hours between creating an integration conflict and resolving it. CI was intended to liberate us from hours/days/weeks or even months of “integration work” that made actually shipping software painful and infrequent.
Same Issue. Different Impact
Consider this pair of diagrams, again from Martin Fowler. Both show the same issue: an integration conflict arises based on assumptions the two developers make very early on.
In the first case, they aren’t doing CI. They are only integrating with the main branch when they are “done” working on their feature branches. Check out how big the “blind spot” is here:
In the second case, the conflict is discovered at the moment Scarlett prepares to merge her first commit to the main. Violet had already committed to the main and when Scarlett synced before merging, she found the issue and resolved it locally.
Look back at the yellow circles in each of these diagrams, that’s a visual representation of the time, effort, and cognitive load each developer faces in the “not quite CI” and “actual CI” worlds.
To Run, We Must First Walk
Hopefully, I’ve helped you discover any CI blindspots you have. These issues are foundational and getting them settled will unlock the velocity and cadence and impact your team (and really all of us) crave. Modern tooling and methodology make all of this much easier, but only if we see the blind spots and are motivated to cure them. Check out the links below to learn more about that.
Learn More About Continuous Integration Without Blind Spots
Many things are possible once you get past blind spots and stop wasting time on merge hassles. Here’s a shortlist to speed you on your journey:
- Safely decouple teams, freeing them to move at their own cadence, without giving up those gains in speed by ending up in “merge hell” down the road. It’s a proven practice you can adopt by rethinking the role (and duration!) of feature branches. Get started by reading Feature Flags vs. Feature Branches
- Tackle bigger problems with greater safety by looking at the problem differently. Read How to Branch by Abstraction with Feature Flags to learn how branching inside your code rather than in version control cuts down on complexity. It’s another way to reduce the chances of time wasted on painful merges.
- Wish you could more rapidly iterate on ideas, safely delivering more impact the way digital-first industry leaders do, starting from wherever you are right now? Have a look at The Path To Progressive Delivery