Friday, September 27, 2013

MSBuild Script - Versioning, Execute Batch files

MSBuild Overview

MSBuild Targets and Tasks

Targets group tasks together in a particular order and allow sections of the build process to be called from the command line. Targets are often grouped into logical sections to allow for project file expansion and to increase readability. For example, one target may delete all files in the output directory to prepare for the build, while another compiles the inputs for the project and places them in the empty directory.
Each target will have more then one task (MSBuild task reference :  http://msdn.microsoft.com/en-us/library/7z253716(v=vs.90).aspx)
There are two good external tasks library we can use
  1. MSBuild extension pack - http://www.msbuildextensionpack.com/
    • AssemblyInfo
    • AsyncExec
    • CommandLine
    • ConfigManager
    • DateAndTime
    • ....
  2. MSBuild Community - http://msbuildtasks.tigris.org/
    • SvnInfo
    • XmlUpdate
    • Zip
    • ...

Project Assembly Versioning

There is a task to update AssemblyInfo.css file in the MSBuild extension pack
Here is sample MSBuild target for applying updated version on the file
Sample - versioning target
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks" />
  
 <Target Name="AssemblyVersion">
 <PropertyGroup>
  <BUILD_NUMBER Condition="$(BUILD_NUMBER)==''">0</BUILD_NUMBER>
  <MajorVersion Condition="'$(MajorVersion)'==''">1</MajorVersion>
  <MinorVersion Condition="'$(MinorVersion)'==''">0</MinorVersion>
  <RevisionVersion Condition="'$(RevisionVersion)'==''">0</RevisionVersion>
 </PropertyGroup>
 <DateAndTime TaskAction="Get" Format="yyyy-MM-dd HH:mm:ss">
  <Output TaskParameter="Result" PropertyName="BuildDate" />
 </DateAndTime>
 <AssemblyInfo
   AssemblyInfoFiles="$(ProjectDir)Properties\AssemblyInfo.cs"
   AssemblyFileMajorVersion="$(MajorVersion)"
   AssemblyFileMinorVersion="$(MinorVersion)"
   AssemblyFileBuildNumber="$(RevisionVersion)"
   AssemblyFileRevision="$(BUILD_NUMBER)"
   AssemblyMajorVersion="$(MajorVersion)"
   AssemblyBuildNumber="$(RevisionVersion)"
   AssemblyRevision="$(BUILD_NUMBER)"
   AssemblyDescription="$(ProjectName). Revision $(RevisionVersion) Built on $(BuildDate)">
 </AssemblyInfo>
</Target>
execute batch file for taking care of combine and minify JS files
Execute Batch and Copy JS files
<Target Name="ExecBatch">
 <ItemGroup>
 <BatchFiles Include=".\**\*.bat" />
 </ItemGroup>
 <Exec Command="%(BatchFiles.FileName)" WorkingDirectory="%(BatchFiles.rootdir)%(BatchFiles.directory)" />
 </Target>
 <Target Name="CopyJS">
 <ItemGroup>
 <JSMinFiles Include=".\**\*.min.js" Exclude=".\publish\**\*" />
 </ItemGroup>
 <Message Text="Copy js min files" />
 <Copy
 SourceFiles="@(JSMinFiles)"
 DestinationFiles="@(JSMinFiles->'.\publish\%(RecursiveDir)%(Filename)%(Extension)')"
 />
 </Target>
and change build properties for web application, so it will be executed by passing /target:Publish option only if the project has web.config.
Target - Publish
<Target Name="Publish" Condition="Exists('$(MSBuildProjectDirectory)\web.config')" DependsOnTargets="AssemblyVersion;ExecBatch">
 <!-- BeforeTargets="BeforeBuild"-->
 <!--RemoveDir Directories=".\publish\" /-->
 <MSBuild Projects="$(MSBuildProjectName).csproj" Properties="Configuration=Release;WebProjectOutputDir=.\publish\;OutDir= .\publish\bin\" Targets="Rebuild;ResolveReferences;_CopyWebApplication" />
 <CallTarget Targets="CopyJS" />
</Target>