Creating a CI System

…Continuous Integration Best Practices (Part 2)

As I noted in Optimal Continuous Integration Best Practices (Part 1), there are 10 best practice principles associated with Continuous Integration.  In Part 1, we looked at the first three. For Part 2, we pick up where we left off and talk about principles four, five, and six.  We are starting to create a CI system which you will use to approach each development project.

For review, the full set of principles are outlined below:

1) Maintain a code repository

2) Automate the build

3) Make the build self-testing

4) Everyone commits to the baseline every day

5) Every commit (to baseline) should be built

6) Keep the build fast

7) Test in a clone of the production environment

8) Make it easy to get the latest deliverables

9) Everyone can see the results of the latest build

10) Automate deployment

Creating a CI System

You’re starting to see that following these 10 best practices gives you a CI system, and that’s what you want.  A system is an organized framework or method.  A system is repeatable and reliable.  You cannot approach CI with an ad-hoc attitude, but rather with a consistent methodology.

4) Everyone commits to the baseline every day.

Check it in!

There are two important points underlying this principle. The first point is that developers need to submit their code to the official, centralized repository. The purpose of this is to evaluate new submissions against the production code.  In this way, you avoid testing against outdated code or running into configuration issues. 

Check it in as soon as it’s complete.

The second point regards the frequency of code check-ins. In order to emphasize the goal of quick iteration cycles, official CI doctrine advises developers to check their code in every day. This may not reflect the reality of most situations.  Usually, we don’t want to simply check in based on a time interval.  Instead, we want to check in working code, or better yet, a completed activity. 

However, the important point is to have developers check in their work as soon as it’s complete. Don’t put off submitting the code.  Especially, don’t try to bundle multiple activities into a single commit (new feature + bugfix + refactor). This latter grouping can seem tempting, but inevitably causes confusion and technical debt. 

Both these practices should be part of your CI system.

Frequent check-ins help with bug fixing later.

In a perfect world, testing catches all the bugs and prevents them from getting into production.  But, we don’t live in a perfect world.  In reality, problems do sneak through and need to be fixed. When that happens, it is far easier to go back and check the code related to a single issue on a single commit.  You don’t want to have to parse through the spaghetti of multiple changes in one commit.

5) Every commit (to baseline) should be built.

In practice, the scale of development taking place will impact how literally this principle is followed. The goal is to validate that each submission integrates cleanly with the established code base and does not introduce errors. If there are only a handful of submissions happening during the course of a day, then each submission should trigger a build.  This is typical of a small organization.

However, we might be talking about a large organization with thousands of developers.  In this case, it is prohibitively costly to run a build every time an individual developer submits code. In that type of situation, some sort of intelligent batching or scheduling will need to be put into place.  Follow the principle of evaluating new submissions quickly. 

In the case of limited resources, builds that have multiple steps can be set to rely on other dependencies and will only kick off and utilize servers when they’re all clear to do so. Certain builds, such as PROD releases, can also be prioritized over others.

Either way, frequent and consistent builds are a critical part of your CI system.

6) Keep the build fast — a key element of your CI system.

This is a very simple principle to understand, but sometimes the implementation is tricky. Developers need rapid feedback in order to understand if their work was successful or not. Additionally, quick iteration cycles encourage experimentation because the impact on productivity is low. 

Achieving a quick build can be difficult due to many factors, including: size of the code base, network connectivity, reliance on specific shared resources, the programming languages involved, or the nature of the testing that needs to take place. In practice, some of the other principles may have to make concessions in order to keep the build fast. A fast build is one of the more important aspects to implementing a CI system and so wherever possible, optimizations for the sake of speed should be made.

Each build process needs to be evaluated differently, as speeding things up is more of a creative endeavor than a set procedure. Some of the most common ways to increase throughput are removing manual steps, creating reusable procedures, and integrating automatic triggers with other tools. 

How to Increase Build Speed for your CI system

Manual steps, while sometimes inevitable, slow everything to a crawl. Instead of waiting for the right person to check the box, an automated gate can often be created based on the data in the pipeline itself. For example, a manual approval to go from DEV to QA stages can be replaced by running code quality checks that will only pass at a certain threshold.

Reusable procedures not only have the potential to speed up build time, but also pipeline development time. It can be grueling to come up with the same shell scripts time and time again, but packing those same scripts into one procedure makes calling them during a job a breeze. These tasks can be integrated into multiple pipelines, along with predefined input and output parameters.  This makes it simple to visualize whether you’re working with a UI or codebase directly.

Finally, automatic triggers can greatly shorten the lead time for a pipeline kickoff. By default, any CI/CD software will allow pipelines to be manually triggered, but that requires the right person to know exactly what to do. Integrating a trigger with source control allows automation like “Start a release pipeline when a developer pushes to the PROD branch.”  This not only removes the time required for a developer to take the right steps, but gives everyone the confidence that code pushed to sensitive areas will be fully vetted before going out the door.

Next Steps:



Free Engineering Tech Strategy Call
Let's discuss your Engineering Ops optimization and how SPK can help.