Builds: how many?
Update (2011-03-21)Changed table layout. |
An interesting question I rarely see discussed is: how many build should I plan for in my project and how do they relate each other.
This latter point is of paramount importance as it drives us to two other questions:
- why should I need such build? or, in other words, which are the motivations and objectives for a having particular build?
- how do we distinguish the outputs?
Let’s sketch some answers.
I assume knowledge of merge and branching; if you need to be up at speed take a look at Visual Studio TFS Branching Guide 2010.
Build Objectives
A primitive kind of build is compiling the project’s deliverables for some user to consume. Different users may require different flavors of the same outputs. A case is signing: for development or test, you use fake keys or certificates, while an official build will use the official encryption keys. Another case is multiple teams: the output of a team is consumed by the team itself, or is on “official” version release to the other teams. Some projects require different builds for binaries and documentation, as the latter has different timing.
This is an important point: as your whole product/project is partitioned in various team (see How Microsoft/DevDiv uses TFS - Chapter 2 (Feature Crews)), you have a natural source of different builds, a group of builds for each team.
As a projects grows bigger, you’ll need to split some of your builds in pieces, to reduce the time they requires.
A very special build is a build created for testing the build itself (see my Testing the Build post).
A very common pattern is to have a continuous integration (CI) and a daily build. Typically the first is aimed at a quick verification of a check-in, while the second is a thorough exercise of automation. For example, the CI simply compiles and run a portion of unit tests, while the Daily exercises as much as possible the code with integration test and packages the output in MSI. I will not spend more words on this subject as there is plenty of material about.
Another common theme is the have a different flavor of the same build for the developers branches, so they may run that flavor on their branch and be reasonably sure of the outcome after merging on the trunk(so called, reverse integration). In this case we have private builds, for private consumption of a single developer or teams, and public builds, shared among various teams or the end-users.
Build Outputs
As we have different builds and different flavors of the same builds, it’s extremely important to clearly distinguish the outputs. In my opinion the difference has to be something easy to recognize in the binaries and the artifacts.
For .NET you may use attributes like AssemblyConfiguration or AssemblyInformationalVersion; the latter is easily checked from Windows Explorer as “Product version”.
A second element that differentiates the builds is the version assigned to the output: I refer to the four part number major.minor.build.revision (see Version Information). A well know schema, widely used in Microsoft, is to:
- fix major and minor for the whole product release;
- build is incremented by official builds;
- revision may refer to a patch build that spins off an official build.
In this schema there may be:
- private builds, where build and revision are fixed (0.0);
- public builds, where build number is increasingly incremented and the revision stays zero;
- public patches, where the build number stays fixed and the revision number is increasingly incremented.
All artifacts (DLL, EXE, MSI) that carry a version number shows their origin based on the last two numbers.
Update (2010-04-30)I have found this interesting post Best Practices for .NET Assembly Versioning that gives you a good explanation on the version numbering topic. |
A basic schema
After this long introduction, I’ll show the schema apt to a small-medium project.
Build |
Description |
Version |
Retention |
Trigger |
Tools |
Compile (and check-in) tools and libraries usedby other builds or tools for dev/test/deploy |
(default) |
Some (5) latest |
Manual |
CI |
Continuous Integration, just compileand run some unit test |
(default) |
Some (5) latest |
Batch |
Daily |
Official build, good for deploy on test |
1.0.*.0 |
50 good, 10 others |
Scheduled at 14:30 |
Release |
Official build for Acceptance / Production |
1.0.*.0 |
All |
Manual |
Hotfix |
Official patch for Acceptance / Production |
1.0.*.* |
All |
Manual |
Private* | Private builds for developers’ branches | 1.0.0.* | Some (5) latest |
Manual |
Some variations, should be immediately evident: you may have more build for different tools; a private build distinct by branch; release and hotfix builds by branch, when you have multiple outstanding deployments.
In a future post, I’ll show how the version number may be computed during the build so to satisfy this scheme. Also note that in TFS 2010, Daily / Release build are candidate for the new Gated check-in feature.
This arrangement isn’t really complex and works well for a single team; when you account for more complex project structure, like feature teams, more complex schemes are needed, both on naming and versioning… but discussing such topic requires more than a blog post.
Hope this may spawn some comments.
Comments
- Anonymous
April 03, 2010
very interesting post. I witness some previous experiences on builds in agile teams. in order to improve team velocity teams used to simplify, improve practices and skills and reduce variations (builds types and manual triggers). this means team used to:
- have one unique build for the Tool and for the CI (we called it CI build)
- have one unique build for the Release and the Daily (we called it Daily build)
- replace Hotfix and Private build with proper team practice so we just had 2 builds. this worked in agile IT departiments with 8 to 30 developers working in the same small-medium size code-base (600 KLOC), and I have read about much bigger agile IT departments doing the same. offcourse i'm courious to ear about experiences in other agile and non-agile teams. also one question: is it correct to have one build (Release or Daily or CI) for one releasable product ?
- Anonymous
April 30, 2010
Sorry for the dealy, Luca. This is matter for a more detailed answer, but the number and type of builds depends on many factors. To be practical, I'll sketch a couple of scenarios. First scenario: you are mantaining a web site with no significant dependencies with other systems. Here speed is paramount; you have often a reduced number of testing stages -- maybe just dev-integration and user acceptance. This is similar to what you describe. Second scenario: your team is developing a piece of a much larger system with strong interaction with other system mantained by other groups on mixed technologies. Testing is fundamental: you have many testing stages before going live: team-integration, integration between systems, user acceptance test, pre-production. In such case you may have more builds than the one I suggested. A third scenario is a big product with many sub-teams. The whole build and automated testing, simply takes too much time to be useful to the single team. That's another case for creating specialized builds -- private, global, you name it.