Extreme ASP.NET Makeover: Getting Your House in Order - Cmd Line Build
Description
Let me give you a very brief introduction to MSBuild. In MSBuild terminology, build steps are called "targets." We will define three common targets initially: Clean, Init, and Compile. You can create other targets to automate other common tasks such as running tests, creating installer packages, deploying to a staging server, or generating documentation. MSBuild uses tasks to define operations within a target. There are many default tasks, such as RemoveDir, MakeDir, MSBuild, and Exec, among others. MSBuild also has the notions of items and properties. Items are files, directories, and references. Properties are name-value pairs representing configuration (Debug/Release), architecture (x86/x64/ia64/AnyCPU), or anything else.
Let's start by defining the Clean target, as shown in the following code:
<ItemGroup> <BuildArtifacts Include=".\buildartifacts\"/> </ItemGroup> <Target Name="Clean"> <RemoveDir Directories="@(BuildArtifacts)"/> </Target>
We use the RemoveDir/ task to remove the $\build\buildartifacts\ directory. Nothing surprising here.
Next we want to initialize our build environment, which means recreating the $\build\buildartifacts\ directory:
<Target Name="Init" DependsOnTargets="Clean"> <MakeDir Directories="@(BuildArtifacts)"/> </Target>
Note that the Init target depends on the Clean target so the $\build\buildartifacts\ directory will be removed and recreated if it already exists. This ensures a clean build.
Moving onto the Compile task itself, I don't want to re-specify the project references, C# files, and configuration options that are already present in the project file. (Some developers do like to have this level of control with their builds and use the project files solely for organizing files within Visual Studio.) I will simply use the MSBuild/ task to compile the solution (which will compile the associated project files) defined by ScrewTurnWiki.sln. I override OutDir to place the build output in $\build\buildartifacts\ rather than in various <Project>\bin\Debug directories. I pass through the build configuration (Debug or Release) and set it to Debug if it is left unspecified, as shown in Figure 7. You can override additional options, such as CPU architecture, in a similar manner:
Compile Using MSBuild
<PropertyGroup> <Configuration Condition=" '$(Configuration)' == " ">Debug</Configuration> </PropertyGroup> <ItemGroup> <BuildArtifacts Include=".\buildartifacts\"/> <SolutionFile Include="..\ScrewTurnWiki.sln"/> </ItemGroup> <Target Name="Compile" DependsOnTargets="Init"> <MSBuild Projects="@(SolutionFile)"Properties= "OutDir=%(BuildArtifacts.FullPath);Configuration=$(Configuration)"/> </Target>
Full Build Script
<?xml version="1.0" encoding="utf-8"?/> <Project ToolsVersion="3.5" DefaultTargets="Compile" xmlns="https://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == " ">Debug</Configuration> </PropertyGroup> <ItemGroup> <SolutionRoot Include=".."/> <BuildArtifacts Include=".\buildartifacts\"/> <SolutionFile Include="..\ScrewTurnWiki.sln"/> </ItemGroup> <Target Name="Clean"> <RemoveDir Directories="@(BuildArtifacts)"/> </Target> <Target Name="Init" DependsOnTargets="Clean"> <MakeDir Directories="@(BuildArtifacts)"/> </Target> <Target Name="Compile" DependsOnTargets="Init"> <MSBuild Projects="@(SolutionFile)" Properties="OutDir=%(BuildArtifacts.FullPath);Configuration=$(Configuration)"/> </Target> </Project>
Notice the Project DefaultTargets="Compile"/, which specifies that the Compile target should be run if none is specified. You can have msbuild run a specific target using the /t switch. For example, to only run the Clean target:
msbuild build/ScrewTurnWiki.build /t:Clean
For more information on creating MSBuild scripts, I encourage you to read Sayed Ibrahim Hashimi's Best Practices For Creating Reliable Builds Part 1 and Part 2. I would also like to extend my thanks to Sayed for his assistance in troubleshooting a MSBuild issue that I encountered while writing this article.
Conclusion
This article is just the beginning of our journey as we set out to improve ScrewTurn Wiki. It is never too late to implement good development practices on an existing codebase, such as version control, issue tracking, automated self-contained build scripts, and automated testing. These practices provide your team with a safety net that allows you to more confidently make changes to improve an existing codebase. The next article will focus on automated testing, including acceptance testing with WatiN, a Web testing framework, and unit/integration testing with NUnit.
Other videos from this article
· Overview
· Building from the command line
Read the full article at https://msdn.microsoft.com/en-us/magazine/dd758790.aspx
Download
Right click or Alt+Enter to download this episode
- High Quality WMV (5.0 MB)
- MP3 (891.7 KB)
- Low Quality MP4 (3.6 MB)
- Mid Quality WMV (3.5 MB)
- WMV (225.0 B)