Try to get your integration builds down to ten minutes by increasing computing resources, offloading slower tests, offloading or reducing inspections, and running staged builds.
Build scalability indicates how capable the build system is of handling an increase in the amount of code that it integrates and analyzes. Build performance refers to the duration of the build.
Developers do not move on to the next task until their most recent check-in integrates successfully. Therefore, builds taking longer than ten minutes can interrupt their flow.
Prioritize improvement tactics, for build duration reduction, by scalability, performance, and difficulty in implementation.
Integration Build Metrics
Compilation time. The time it takes to compile the software, and how it compares to your past compile times. [Recorded by daily builds.]
Number of source lines of code (SLOC). This indicates the system’s size or at least what needs to be compiled. [Calculated by SSMT.]
Number and types of inspections. The number of different types of inspections you are performing. Consider eliminating any redundancy.
Average assembly generation time. The time it takes to generate the assembly, archive, or however you are packaging the software. [Recorded by daily builds.]
Test execution time (based on category). The time it takes to perform testing at each level: unit, component, and system.
Ratio between successful and unsuccessful builds. Divide the number of failed builds into the number of total builds to determine the ratio between successful and unsuccessful builds. [Calculable from daily build archive.]
Inspection time. The time it takes to perform all of the automated inspections. [Timeable from a Klocwork or Purify run.]
Deployment time. The time it takes to deploy the software into the target environment from the integration build.
Database rebuild time. The time it takes to rebuild your database.
Integration build machine system resources and usage. Improving the memory, disk speed, and/or processor can improve the performance of your integration builds. This helps determine whether an integration build machine has an application server or database server or some other process that is using up memory or processor speed.
Version control system load. Helps determine the version control system’s peak-time load, how long it takes to check out/update your project from the integration build machine, and if the network bandwidth, processor, memory, or disk drives are adequate.
Integration Build Duration Improvements
Use a dedicated integration build machine. Reduce false positive or negative builds, and enable faster builds.
Increase integration build machine(s) hardware capacity. Perform available upgrades to CPU, disk, or memory. Offload processes to other systems. Eliminate unnecessary system processes.
Improve test performance. Separate automated tests by category—unit, component, and system—and run these tests at different times (e.g., unit tests at every commit, component/system tests in a secondary build). Refactor your tests based on the results of the inspection tools. Use mocks/stubs for components that may otherwise be too difficult or complex to use in the unit-testing environment. For example, a common implementation of a mock object is mocking the interface for data access. Separate long-running integration tests into separate specialized test suites. Execute your tests in parallel. Run different types of tests based on build type: a commit build is followed by secondary builds, a full integration build, or release build.
Streamline integration builds. See the practice Stage Builds.
Examine and optimize infrastructure. Investigate and improve any infrastructure resources to reduce the build duration.
Optimize the build process. An incremental build will compile and/or regenerate only the files that have changed. Ideally, an integration environment should be cleaned by removing old files and then compiling/regenerating the code to effectively determine if anything has broken. Might be reasonable to only rebuild once a day, objects that rarely change.
Build system components separately. Break apart the software into smaller subsystems (modules) and build each of the subsystems separately. If there are any changes to one project based on the dependencies, the other projects are rebuilt as well.
Improve software inspection performance. Which metrics are used? Does each metric provide tangible value? Are there two or more tools providing the same metrics, which may decrease your build performance? Are you running automated inspections with every build? Are there certain analyses that can run as part of a secondary or periodic build? Are there inspections that you can run on specific subsystems rather than the entire code base?
Perform distributed integration builds. Moving part of the build to another machine may mean copying large files around as part of the build process, which has the potential to slow things down even more.
[Duvall et al. 2007, “Building Software at Every Change”]