I had customize our Build Process Template to support multiple target environments on a single Build Machine. I.e.: to resolve the "file references" at Build time depending on the environment targeted for the deployment.
Click to Read More
TFS Build Machines not only compile the applications to be deployed via the standard Release Distribution, but also the urgent fixes to be deployed directly in Pre-Production without passing through Integration and Qualification environments. It also happens, although really quite seldom, that a Build skips the Integration and goes directly to Qualification.
It's also to be noticed that none of our applications (assemblies) are strong named and deployed in the GAC, neither on development workstations nor on servers. Instead, all referenced assemblies are always copied within the application's bin folders, also on the servers.
Therefore, basically, we would need Build Machines dedicated for each target environment with the adequate assemblies made available on them, for reference resolution purpose. That would be a pity to have such Build Machines (and the related setup, maintenance, backup costs, ...) for at most one build per month (Fix in Production and Qualification are fortunately not common).
To avoid that, I did customize our Build Process Template to take a Reference Path as input and to pass it to MSBuild. Actually, when editing a Build Definition, the Builder can select the target Environment, and the Build will simply receive a path to the location containing the related assemblies.
Ex.: MSBuild mySolution.sln /p:ReferencePath="c:\RefAssemblies\Qualification\"
How can I be sure that this Reference Path won't interfere with any Hint Paths defined in the Visual Studio projects?
First, note that the location provided to MSBuild via the "ReferencePath" parameter will be probed to resolve all "file references" before any other location on the standard probing path. But we also pay attention to not make the assemblies available on the Hint Path on the Build Machines:
- On Development Workstations, all our assemblies are made available in a single "Reference Assemblies" folder. Developers add references on assemblies in there for development and local testing purpose. They can also start a task at will to update this "Reference Assemblies" folder with the latest version of the assemblies (the versions used in the Integration Environment) or with the version currently deployed in the Qualification or Production Environments (e.g.: for bug fixing purpose).
- On the Build Machines, there is one "Reference Assemblies" folder per environment (i.e.: updated by the Release Distribution with the assemblies currently in use in that environment). None of those folders is located at the same path as the "Reference Assemblies" folder of the Development Workstations. As a result, MSBuild cannot use the Hint Paths found in the Visual Studio projects to locate the referenced assemblies. Instead, it uses the path of the "Reference Assemblies" folder passed to it via its parameter /p:ReferencePath.
In addition to the "Reference Assemblies" folders per environment, we also have one extra folder containing the output of each latest successful Build. This one is used for "Continuous Integration". No need to update the references in the Visual Studio Projects, MSBuild always find in that folder the latest version of each assembly recently built on any Build Machine (if requested to do so via the Build Definition). This is by the way the default "target environment" for all "Rolling Builds" defined on "Development Branches", so any breaking features in a new version of a referenced assembly is immediately detected. Builds "candidate" to be promoted use by default the Reference Path with the assemblies from the Integration environment.