The real meaning of CI (Continuous Integration)

CI stands for Continuous Integration: the term usually refers to a series of tools that execute jobs whenever a developer pushes code.

The real meaning of the term is in the actual words: Continuous Integration means to integrate continuously

Continuous Integration is the practice of merging all developers working copies to the main branch several times a day.

If you are working on a legacy software project, this definition seems complete madness: “Merging to the main branch several times a day? I’m lucky if my feature branch will arrive in the main branch in 2 months!"

This is why Continuous Integration can’t be applied without a suitable branching methodology and automated tools that ensure the quality of the work.

Branching methodologies

A branching methodology defines a set of rules developers use to create and merge branches on a version control system. If we want to Continuously Integrate, we must choose an appropriate branching methodology.

GitFlow

GitFlow is a successful branching methodology introduced in 2010. This methodology is based on two always-present branches:

  • main - Production-ready code.
  • develop - The integration branch where all the development code is merged.

There are also other supporting branches:

  • feature branches
  • release branches
  • hotfix branches

The lifecycle of a feature could be something like that:

  • A feature branch is created from develop.
  • A developer works on the feature branch for several days.
  • When the work is completed, the feature branch is merged back into develop.
  • Meanwhile, the develop branch received other commits.
  • Before merging into main, the work has to be thoroughly tested and verified. A release branch is created from develop to finalise the work.
  • The release branch is thoroughly tested and fixed with other commits.
  • When the release branch is ready, it’s finally merged into main.

As you can see, this is the opposite of Continuos Integration. A developer’s work is not integrated continuously into the main branch, but it’s only integrated at the end of a release. This could mean it will be integrated after weeks (if you are lucky) or months.

GitHub Flow

A branching methodology that better supports Continuous Integration is the GitHub Flow.

This methodology is based on one main branch containing the production-ready code. From this branch, all the feature branches are created and merged directly into the main branch when they respect the Definition of Done.

This branching methodology allows us to continuously integrate into the main branch without all the ceremonies of the GitFlow model.

Automated Tools

Using a suitable branching methodology is only the first step: continuously merging the work on the main branch without safeguards will result in continuous disaster.

Those safeguards can be implemented using automated tools:

  • Build
  • Test (Unit, Integration, End-to-End)
  • Code Quality
  • Automatic Deploy

A fundamental aspect of CI is that those automated tools are executed for every commit, and only the commits that succeed to all the automated jobs can be merged to the main branch: This way, we can avoid continuous disaster and only merge things that don’t break the main branch.

This is why the term CI is usually associated with those automated tools: without them is nearly impossible to integrate into the main branch continuously.

Transition to CI

Legacy projects without all those automated integrations usually use the GitFlow branching methodology: the redundant branches give a buffer to test and stabilise releases while the development work is continued on other branches.

If we want to transition to a Continuous Integration model, the first step is to add automated tools to every commit to guarantee the quality of the main branch:

  • The first tool to integrate is always the build to guarantee that we don’t disrupt the work of the developers by having a main branch that doesn’t compile.
  • Then, we can start adding unit tests on the core part of the projects.
  • Finally, we can add automatic deploys to remove all the manual procedures used for deploys.

After integrating those tools, migrating to a better branching model will be painless, reducing the Lead Time of all the work.