Continuous Integration
Continuous Integration (CI) is a development approach using software that monitors your version control system and initiates an automated build after any change to your project. Once the build is complete, all automated tests are run and notifications are triggered.
CI also implies the workflow of constant integration to the version control trunk. That is, there are no long-running branches that will need to be merged at some point. Check-ins are done to the development trunk, which may also be known as “main”, or (historically) “master.” Small, frequent check-ins are critical in order to enable Continuous Delivery/Continuous Deployment (CI/CD).
Pain Points
- Every morning, the team wastes time fixing the nightly build
- The same few people always break the builds, and others clean up behind them
- Mysterious faults frequently creep into the product
- Developers resist updating their local code base because they don’t want to deal with the inevitable problems they’ll encounter
- Integrating code is difficult, and nearly impossible to do quickly
- Marketing needs a demo of the latest features right now, but the code under development is lying in pieces and can’t run
- You find out that the new features you delivered are no longer needed
Benefits
- The code is continuously integrated and tested so any regression or new bugs are visible immediately
- Progress is visible immediately
- Code is always in a known and deliverable state
- Problems are detected almost as quickly as they occur, allowing developers to learn and correct almost immediately
- The team becomes accustomed to having a working system and becomes intolerant of “Broken Windows” (see Software Entropy in The Pragmatic Programmer (Thomas & Hunt, 2020))
Assessment
- The team is practicing Continuous Integration, and all of the following are true: (Major Boost)
- Every developer commits several times a day (hourly is better) to the shared, mainline branch
- Every commit triggers an automated build and all unit tests are run
- If build and/or test fails, the build is repaired within ten minutes
- The team does not consistently check multiple times per day (Significant Setback)
- The team is not practicing Continuous Integration (cannot answer ‘yes’ to the three questions above) (Significant Setback)
- The “CI” build does not actually run continuously—nightly or once a week does not count (Significant Setback)
- You have no automated unit tests (Disaster)
- There are long-running feature branches (Disaster). Consider the use of Feature Switches instead
Application
✓ Critical ❑ Helpful ❑ Experimental
Adoption Experiment
Steps to first adopt this habit:
Setup
- Create a scripted build for your product
- Set up a clean environment and install your build tools and a version control
client, for example, using the native pipeline facilities from your hosted provider (e.g., gitlab.com, github.com, etc.)
- Discuss with your team. Ask them to agree that all breaking builds will be repaired or backed out within ten minutes during this experiment
Trial
- Add your product to the continuous integration system
- Enable email notifications
- Make sure participants are checking in frequent, small changes
- Intentionally break the build to verify the system
- Add a basic unit test to the system
- Create a failing test to verify the system
Evaluate Feedback
- How often did the build break? Why?
- How long did it take to fix an average problem?
- How has the team’s work habit changed?
What Does it Look like?
The build machine, usually running in the cloud, runs constantly, 24x7x365, looking for changes in version control and then building the latest, most authoritative version of your product. QA, testers, managers, and the users you are working with can always access the latest build for casual evaluation.
A developer commits their code no later than the usual build time before they plan to go home, then they wait for the continuous integration to complete, and notify them that the build is good. Then they go home for the day. Or, if the build was bad, they jump back in and get things fixed. But they don’t go home and leave a broken build for someone else to fix.
Jenkins is a popular continuous integration system. It has a vibrant plugin ecosystem that integrates with most existing systems and tools. It’s written in Java, but plays well with multiple technologies. It’s also a well-vetted open-source tool, so the price fits every budget. VC hosting providers such as gitlab.com or github.com provide cloud-based pipeline build environments at both free and paid tiers.
Martin Fowler’s blog (Fowler, 2017) suggests the following test to evaluate whether you’re really doing Continuous Integration correctly:
- Every developer commits at least daily to the shared mainline branch
- Every commit triggers an automated build and test
- If build and test fails, it’s repaired within ten minutes
It sounds simple, and it is, yet the vast majority of teams who think they’re doing CI can’t pass this test. According to some surveys, 90% of survey participants who said they were practicing CI did not integrate to the mainline daily (see #1 above).
Warning Signs
- Your team only commits code every other week (or even every few days)
- You have no automated unit tests
- You have automated tests, but you disable them so they won’t break the builds
- You disable your CI builds until the end of an iteration
- You schedule your “continuous” builds to run once a day. Or once a week.
Growth Path
Once the build is in place, try to improve the state of the build with each commit. For instance, add a code coverage tool to expose how much of the product is exercised (or missed) by the unit tests. Focus on increasing that number with every code commit.
Remember, it’s okay to break the build, but it’s not okay to leave it broken. The only team member who never breaks the build is the one who isn’t writing code.
How To Fail Spectacularly
- Committing code and going home before seeing the result of the CI build.
- Committing code and going on vacation before seeing the result of the CI build. (Sadly, this is a real example)
- Disabling the tests because “they always break and that slows down the team” (Again, an actual quote).
- Turning off the CI system entirely because developers frequently break the build. Bonus demerits if you continue to brag about having a CI system while it’s turned off.
- Providing an annual bonus pool and deduct money from it every time a build is broken (the manager involved didn’t understand why developers stopped sharing their code frequently)
- Writing your own continuous integration software. There are too many excellent products available already. If you think it’s trivial, then you don’t understand the system yet. (Again, a real-life example)
←Prev (Version Control)(StorySlicing.txt) Next→