In centralized continuous integration, everyone contributes changes to a central trunk, master or mainline. A continuous integration system is continually running automated tests on this version. The goal is to find and fix problems as early as possible. Developers have incentives to avoid "breaking the build" and make sure that the mainline is always at release quality.
Key concepts of continuous delivery include:
- Automated tests. You need enough automated tests to tell you immediately if something is broken. You run them frequently.
- Developer responsibility. It is the responsibility of the developers to make sure that their code doesn't break anything. They can't just throw it over to QA and wait for bug reports. The centralized system enforces an extreme form of developer responsibility by sending an alarm if the system does not build, or if tests fail. This "broken build" demands attention. In some shops, it triggers sirens and flashing lights.
- Feature switches. Developers are constantly releasing code for new features, but they need to hide features that aren't ready. They put switches in the code to hide changes that aren't officially released or “unveiled.“
Centralization is efficient. There is one test system, which is important if your test environment is complicated. You don’t have to move code between multiple versions. You know where to go for manual testing.
Because of its efficiency, this is a great pattern for small teams. It is also a good pattern for systems that have very complicated test environments.
This approach relies on the principle of “as early as possible” integration and discovery of problems. People are committing frequently, tests run frequently, and conflicts between changes are discovered quickly. This minimizes the amount of wasted programming effort and improves efficiency.
Centralized continuous integration works well with Subversion, where it is called “active trunk.” Subversion does a good job of synchronizing developers onto a single stream.
Centralized continuous delivery doesn’t scale very well if you have many contributors, many new contributors, or distributed teams. The more changes that you put into the shared version, the more often you will have a “broken build” that doesn’t work, or possibly doesn’t even compile.
As you add distributed contributors, the process becomes more stressful. To avoid delaying everyone else, every contributor has to be alert to broken tests and broken builds and fix them immediately, regardless of time zone. This puts extra stress on distributed team members and gives them responsibilities after the end of their workday. Jez Humble is an advocate of the centralized approach, but he doesn't recommend it for truly distributed teams.
You can't release every change. Whenever you put two changes together for "early as possible" integration, you expect to find problems. The software is not releasable until you have tested for the possibility of new problems.
The fix: Test and review
Centralized continuous delivery is well suited to a two-week release cycle that includes user acceptance testing and batched releases. With this release cycle it often becomes a continuous integration system, and not a continuous delivery system. But if you want to release every day, or release every change, you may decide make a major leap from “as early as possible” integration to “as late as possible.”
You can eliminate almost all of these disadvantages and go to continuous release if you test and review incoming commits. We will discuss this below.