The Implementation Breakthrough: Continuous Deployment, Microservices, and Containers 12
Continuous integration (CI) usually refers to integrating, building, and testing code within the
development environment. It requires developers to integrate code into a shared repository often.
How often is often can be interpreted in many ways and it depends on the size of the team, the size of
the project and the number of hours we dedicate to coding. In most cases it means that coders either
push directly to the shared repository or merge their code with it. No matter whether we’re pushing
or merging, those actions should, in most cases, be done at least a couple of times a day. Getting
code to the shared repository is not enough and we need to have a pipeline that, as a minimum,
checks out the code and runs all the tests related, directly or indirectly, to the code corresponding
to the repository. The result of the execution of the pipeline can be either red or green. Something
failed, or everything was run without any problems. In the former case, minimum action would be
to notify the person who committed the code.
The continuous integration pipeline should run on every commit or push. Unlike continuous
delivery, continuous integration does not have a clearly defined goal of that pipeline. Saying that
one application integrates with others does not tell us a lot about its production readiness. We do
not know how much more work is required to get to the stage when the code can be delivered to
production. All we are truly striving for is the knowledge that a commit did not break any of the
existing tests. Never the less, CI is a huge improvement when done right. In many cases, it is a
very hard practice to implement, but once everyone is comfortable with it, the results are often very
impressive.
Integration tests need to be committed together with the implementation code, if not before. To gain
maximum benefits, we should write tests in test-driven development (TDD) fashion. That way, not
only that tests are ready for commit together with implementation, but we know that they are not
faulty and would not pass no matter what we do. There are many other benefits TDD brings to the
table and, if you haven’t already, I strongly recommend to adopt it. You might want to consult the
Test-Driven Development⁴ section of the Technology Conversations⁵ blog.
Tests are not the only CI prerequisite. One of the most important rules is that when the pipeline
fails, fixing the problem has higher priority than any other task. If this action is postponed, next
executions of the pipeline will fail as well. People will start ignoring the failure notifications and,
slowly, CI process will begin losing its purpose. The sooner we fix the problem discovered during the
execution of the CI pipeline, the better we are. If corrective action is taken immediately, knowledge
about the potential cause of the problem is still fresh (after all, it’s been only a few minutes between
the commit and the failure notification) and fixing it should be trivial.
So how does it work? Details depend on tools, programming language, project, and many other
factors. The most common flow is the following.
• Pushing to the code repository
• Static analysis
• Pre-deployment testing
⁴http://technologyconversations.com/category/test-driven-development/
⁵http://technologyconversations.com/