August 30, 2007

Automating A .NET Build With MSBuild and Surround SCM

Surround SCM

Works with Surround SCM 5 and later

The following article shows how to set up a Surround SCM trigger to get the latest version of each file in a specified repository and then launch MSBuild to build the solution. This article was written using Surround SCM 5.0.4, a Visual Studio 2005 Solution containing one project written in C#, and the MSBuild executable distributed with the .NET framework version 2.0.50727. A similar example for non-.NET applications is included in the Surround SCM and Apache Ant Integration article.

About the Files in Surround SCM

The solution file, named WysiCM.sln, is stored on a mainline branch called "WysiCorp, Inc.". The Solution is stored in a repository named "WysiCM". This repository has a child repository by the same name, where the project file exist. The repository structure from here mimics the folder structure of the project. Some information that will be used in this article:
  • Branch Name: WysiCorp, Inc.
  • Full Path to Top Level Repository: WysiCorp, Inc./WysiCM
  • Working Directory: D:WysiCorp AppsNew DevWysiCM

About the Trigger

For this example, I am going to set the trigger so it only runs when a changelist is committed. The reason is because I don't want to invoke this for each file that gets checked in. If I check in 10 files, I really do not want to run a build 10 times, one right after the other. I just want to run one build after all of the files have been checked in. Please note that you can set the Surround SCM Server Options to enforce the use of changelists. You can also set your user options to always be prompted for a changelist on check in. This functionality is also available if you do your check ins from Visual Studio. The trigger will call a single batch file. The batch file will first run a get command, recursively, and then will call MSBuild to make a build based on the latest versions of the files. Set up a user specifically for this action - The username and password you will be passing to Surround SCM will be stored in a batch file. Anyone who can access this file will have access to the user's credentials. Set up a user with only basic permissions to be able to do a get. Also, set it up so the working directory for this user on the server is the directory where you want to make the build. This directory will be passed to MSBuild in the batch file. In the working directory mentioned above, D:WysiCorp AppsNew DevWysiCM is the working directory for the user that I will use in the batch file to perform the get operation. Creating the batch file - The batch file consists of only two lines. The first one performs the get (recursively) off all the files. MSBuild will need access to all of the files, and if any file is read-only, the build may fail. To prevent this error, the options "-f" (force file retrieval) and "-e" (Writable) are used. Without the "-f" option, only those files that are not "current" would be made writable. Please refer to the Surround SCM CLI Guide for more information. This is what the contents of the batch file look like:
SSCM GET / -e -r -p"%SSCM_REPOSITORY%" -b"%SSCM_BRANCH%" -yBuildUser:builder -z127.0.0.1:4900

C:WINDOWSMicrosoft.NETFrameworkv2.0.50727MSBUILD.exe "D:WysiCorp AppsNew DevWysiCMWysiCM.sln">>D:buildresult.log
In this batch file, I include the entire path when calling MSBuild. An alternative would be to add this path to the PATH variable. Another alternative might be to copy the MSBuild.exe and all needed files to a path that is already in the PATH variable. Setting up the trigger - As mentioned, the trigger is set up to run when a changelist is committed. Since we have to hard code the location of the solution file, this trigger will set to only run on the branch and repository associated with this directory. The summary of the trigger is as follows: Trigger applies to files in branch [WysiCorp, Inc.] and in repository [WysiCorp, Inc./WysiCM] [recursively] -- after an event when a changelist is committed -- Run script located at "d:batchbuild.bat"


There are some improvements that could be made to further extend this process. Change File State In Surround SCM - You could incorporate the Surround SCM workflow. You could add to the batch file a "setstate" command to set the state to "Build Made" or something similar. A little more complex extension of this would be to first set the state to "build started", call MSBuild, and then parse the output of the build to see if the build was successful. You could then run another "setstate" command to set the files to a state that reflects the success of the build. Create a Snapshot Branch - If you are able to determine the success of the build, you could also create a snapshot branch if the build was successful. Creating a snapshot branch of an unsuccessful build would not make much sense. Note: Seapine does not provide support for sample triggers and scripts.