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:
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.
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.
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:
In this schema there may be:
All artifacts (DLL, EXE, MSI) that carry a version number shows their origin based on the last two numbers.
After this long introduction, I’ll show the schema apt to a small-medium project.
Compile (and check-in) tools and libraries usedby other builds or tools for dev/test/deploy
Some (5) latest
Continuous Integration, just compileand run some unit test
Official build, good for deploy on test
50 good, 10 others
Scheduled at 14:30
Official build for Acceptance / Production
Official patch for Acceptance / Production
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.