A Journey into MSBuild
For the majority of the time I have avoided looking too deeply into the depths of our MSBuild scripts allows TeamCity to build our projects, run our tests, prepare our artefacts and even run the deployment to our development and test servers but I am starting a new project and looking at using MSBuild to co-ordinate all of these activities.
However, the current project files in existing projects seem to be large and overly complex, there are a lot of properties and it is difficult to see what needs to change when adding new components into the system. What I want to do is to simplify the process and reduce the amount of thought that you need in order to create a new project.
The Master Project File
The standard way I approach this is that we have a teamcity-master.proj file that has the responsibility for loading any projects and MSBuild tasks that are required as well as providing a series of high-level targets:
- This is solely responsible for building the solution, however, it will defer to an actual task in the teamcity-build.proj that knows how to build your project.
- This requires that the Build target is run and is solely responsible for running all of the unit tests that you have written, however, it will defer to the actual unit test tasks in the teamcity-unit-tests.proj file.
- This requires that the UnitTest target is run and is then solely responsible for packaging the artefacts for deployment to a staging area. Once again this defers to a separate teamcity-package.proj file that manages the complexity of preparing the artefacts.
- This will take the latest set of deployment artefacts from the staging area and deploy them to the test deployment environment and is controlled by the contents of the teamcity-deploy.proj project file for details.
- Whereas the UnitTest project may have run "acceptance tests" that involve mocking out external dependencies this will drive the automated integration-level tests that require the ability to drive the user interface etc. These tests are again controlled directly from the teamcity-integration-tests.proj file.
As you can see, the master project file is solely there for orchestrating the builds, providing the standard targets for different teamcity builds to run depending on their job, e.g. you may have a simple build and unit test project to run after every check-in but nightly run a full build that builds, runs unit tests, packages, deploys and runs the integration tests (or it may be an on demand project). Details are kept away from the master file allowing each independent section to be controlled in finer detail.