Controlled Integration Cycle
To this point, I have introduced the concept of controlled integration, but how does it really happen? The answer is simple -- once a day, a week, or at most every couple of weeks, depending on the working volume, the stack of finished tasks gets integrated by the integrator, a new release is created, tested, and then marked as the baseline for the next iteration. Figure 11 shows the full cycle. Notice that testing (unit testing, automated GUI testing, manual checks, and so on) plays a key role in the process. If there were no tests, the cycle would make no sense.
Are there any drawbacks in the controlled integration cycle? Of course, no method is perfect, but the following ones are worth noticing:
- If no build and test server is in place (something quite extended when continuous integration is present), developers run the test suites on their own workstations. This is normally time consuming and can have an impact in productivity. In case automated GUI testing is used, developer's workstations will be blocked until the tests finish.
- Results are not published: Using an integration and build server there will be usually a way to publish the test results, but when they are run on developer's workstation such an option could be more difficult.
The Best of Both Worlds: Controlled + Continuous Tools
What about having the build and test tools normally used in continuous integration mixed with the controlled best practices? This way you would still get the best out of the branching patterns, the added control introduced into the process, and benefit from the build technology spread by the continuous practitioners. Figure 12 shows a mixed process. Each time a developer finishes a task, the integration server triggers a build getting the code from the associated branch. All the available tests get run and then results are published and made available to the whole team. Now developers can continue working while the tests are run, and they can get feedback after the whole test suite is run.
When a regular controlled integration is performed, the integrator runs a subset (smoke tests) of the complete test suite for each integrated branch. This practice lets you reject offending tasks if they break the build or don't pass the tests. The integrator is the person responsible for merging the code, running the tests, labeling the results, packing, and so on. Figure 13 illustrates the process. The problem is that the task itself can be time consuming. Normally, if the right tool is used and it implements a good merging support, the merge process is extremely fast, but running all the tests again and again will be CPU demanding.
Are there any other options to solve the problem? In Figure 14, developers integrate their branches against the mainline from their development branches, then the integration server triggers the build-and-test cycle. When a number of tasks have been integrated, the integrator checks the mainline stability and decides to create a new baseline. This approach is close to continuous integration, but has the following differences:
- Developers still count on their own versioned sandboxes.
- All tasks start from a well-known baselined point, which is supposed to be stable, so bug spreading is still avoided.
Figure 15 introduces a variation on the same alternative that mixes controlled and continuous integration together: Developers continue integrating their changes when they finish a task, but they do it against an integration branch. The integrator is in charge of promoting the changes to the mainline when needed, also creating new baselines. Now mainline code is kept clean and contains correct and finished code.