Continuous integration, often abbreviated as CI, is a process that takes benefit from automated testing and version control systems to provide a fully automatic integration environment. It can be used with centralized version control systems, but in practice, it spreads its wings only when a good DVCS tool is being used to manage the code.
Setting up a repository is the first step toward continuous integration, which is a set of software practices that have emerged from eXtremeProgramming (XP).
The first and most important requirement to implement continuous integration is to have a fully automated workflow that can test the whole application in the given revision in order to decide if it is technically correct. And technically correct means that it is free of known bugs and that all the features work as expected.
The general idea behind CI is that tests should be run always before merging to the mainstream development branch. This could be handled only through formal arrangements in the development team, but practice shows that this is not a reliable approach. The problem is that, as programmers, we tend to be overconfident and unable to look critically at our code. If continuous integration is built only on team arrangements, it will inevitably fail because some of the developers will eventually skip their testing phase and commit possibly faulty code to the mainstream development branch that should always remain stable. And, in reality, even simple changes can introduce critical issues.
The obvious solution is to utilize a dedicated build server that automatically runs all the required application tests whenever the code base changes. There are many tools that streamline this process, and they can be easily integrated with version control hosting services such as GitHub or Bitbucket, and self-hosted services such as GitLab. The benefit of using such tools is that the developer may locally run only the selected subset of tests (that, according to them, are related to their current work) and leave the potentially time-consuming suite of integration tests for the build server. This really speeds up the development, but still reduces the risk that new features will break the existing stable code found in the mainstream code branch.
Another plus of using a dedicated build server is that tests can be run in the environment that is closer to the production. Despite the fact that developers should also use environments that match the production as much as possible, and there are great tools for that (such as Vagrantand Docker), it is hard to enforce this in any organization. You can easily do that on one dedicated build server or even on a cluster of build servers. Many CI tools make that even less problematic by utilizing various virtualization and/or containerization tools that help to ensure that tests are run always in the same and completely fresh testing environment.
Having a build server is also a must if you create desktop or mobile applications that must be delivered to users in binary form. The obvious thing to do is to always perform such a building procedure in the same environment. Almost every CI system takes into account the fact that applications often need to be downloaded in binary form after testing/building is done. Such building results are commonly referred to as build artefacts.
Because CI tools originated in times where most of the applications were written in compiled languages, they mostly use the term building to describe their main activity. For languages such as C or C++, this is obvious because applications cannot be run and tested if they are not built (compiled). For Python, this makes a bit less sense because most of the programs are distributed in a source form and can be run without any additional building step. So, in the scope of our language, the building and testing terms are often used interchangeably when talking about continuous integration.