<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>the tar pit &#187; msbuild</title>
	<atom:link href="http://blog.goneopen.com/tag/msbuild/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.goneopen.com</link>
	<description>Thrashing around in the stickiness of software</description>
	<lastBuildDate>Wed, 25 Aug 2010 10:10:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>MsBuild execution of SoapUI testrunner</title>
		<link>http://blog.goneopen.com/2010/01/msbuild-execution-of-soapui-testrunner/</link>
		<comments>http://blog.goneopen.com/2010/01/msbuild-execution-of-soapui-testrunner/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 01:35:13 +0000</pubDate>
		<dc:creator>todd</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[msbuild]]></category>
		<category><![CDATA[soapui]]></category>
		<category><![CDATA[UnitTesting]]></category>

		<guid isPermaLink="false">http://blog.goneopen.com/?p=103</guid>
		<description><![CDATA[I have just been writing an msbuild runner to wrap testrunner for soapUI. Here it is. There are a couple of techniques to note: stacking the args for the commandline in an ItemGroup (see thanks below) don&#8217;t forget to Html Escape quots when invoking command line ie &#38;amp;quot I also dependency check for each And [...]]]></description>
			<content:encoded><![CDATA[<p>I have just been writing an msbuild runner to wrap testrunner for soapUI. Here it is. There are a couple of techniques to note:</p>


<ul>
<li>stacking the args for the commandline in an <code>ItemGroup</code> (see thanks below)</li>
<li>don&#8217;t forget to Html Escape quots when invoking command line ie <code>&amp;amp;quot</code></li>
<li>I also dependency check for each</li>
<li>And the usual that the default target is Help and it tells about the targets and dependencies</li>
</ul>





<pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Project DefaultTargets=&quot;HelpTest&quot;  ToolsVersion=&quot;3.5&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;

  &lt;PropertyGroup&gt;
    &lt;SoapUiProject Condition=&quot;'$(TestProject)'==''&quot;&gt;agent-soapui-project.xml&lt;/SoapUiProject&gt;
    &lt;SoapUITestResultsFolder Condition=&quot;'$(SoapUITestResultsFolder)'==''&quot;&gt;$(MSBuildProjectDirectory)&lt;/SoapUITestResultsFolder&gt;
  &lt;/PropertyGroup&gt;

  &lt;ItemGroup&gt;
    &lt;Args Include=&quot;-a&quot;/&gt;
    &lt;Args Include=&quot;-e$(Endpoint)&quot; Condition=&quot;'$(Endpoint)'!=''&quot;/&gt;
    &lt;Args Include=&quot;-s$(TestSuite)&quot; Condition=&quot;'$(TestSuite)'!=''&quot;/&gt;
    &lt;Args Include=&quot;-c$(TestCase)&quot; Condition=&quot;'$(TestCase)'!=''&quot;/&gt;
    &lt;Args Include=&quot;-f$(SoapUITestResultsFolder)&quot; Condition=&quot;'$(SoapUITestResultsFolder)'!=''&quot;/&gt;
  &lt;/ItemGroup&gt;

  &lt;PropertyGroup&gt;
    &lt;SoapUiPath&gt;$(ProgramFiles)\eviware\soapUI-3.0.1\bin&lt;/SoapUiPath&gt;
    &lt;JAVA_HOME Condition=&quot;'$(JAVA_HOME)'==''&quot;&gt;$(SoapUiPath)\..\jre&lt;/JAVA_HOME&gt;
    &lt;TestProject&gt;$(MSBuildProjectDirectory)\src\AcceptanceTest\$(SoapUiProject)&lt;/TestProject&gt;
    &lt;SoapUiRunner&gt;&amp;quot;$(SoapUiPath)\testrunner.bat&amp;quot; $(TestProject) @(Args,' ')&lt;/SoapUiRunner&gt;
  &lt;/PropertyGroup&gt;

  &lt;Target Name=&quot;TestAll&quot; DependsOnTargets=&quot;AcceptanceTests&quot;/&gt;

  &lt;Target Name=&quot;CheckDependencies&quot;&gt;
    &lt;Error Text=&quot;SoapUI testrunner is not installed at: $(SoapUiPath)&quot; Condition=&quot;!(Exists('$(SoapUiPath)'))&quot;/&gt;
     &lt;Error Text=&quot;JAVA_HOME environment variable not set correctly to point to an JRE&quot; Condition=&quot;!Exists('$(JAVA_HOME)')&quot;/&gt;
  &lt;/Target&gt;
  
  &lt;Target Name=&quot;AcceptanceTests&quot; DependsOnTargets=&quot;CheckDependencies&quot;&gt;
    &lt;Message Text=&quot;Building Test Command: $(SoapUiRunner)&quot;/&gt;
    &lt;Exec Command=&quot;$(SoapUiRunner)&quot;/&gt;
  &lt;/Target&gt;

  &lt;Target Name=&quot;HelpTest&quot;&gt;
    &lt;Message Text=&quot;
    
    msbuild /t:TestAll
    
    Variables that can be overridden:
      SoapUiProject=soapui-project.xml
      SoapUITestResultsFolder=$(MSBuildProjectDirectory)
      Endpoint=http://12.0.0.7:8090/SERVICE
      TestSuite=WorkSuite
      TestCase=UpdateCase

    Targets:
     - TestAll
     - AcceptanceTests
	
    Dependencies: 
    - soapUI must be installed to $(SoapUiPath)
    - JAVA_HOME - currently set to: $(JAVA_HOME)
             
             &quot; /&gt;
  &lt;/Target&gt;

&lt;/Project&gt;
</pre>



<h2>Reference:<h2>

The technique for stacking args in the ItemGroup is fro:<br />
<ul>
	<li>http://weblogs.asp.net/lorenh/archive/2008/12/11/msbuild-trick-for-making-lt-exec-gt-calls-more-maintainable.aspx</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://blog.goneopen.com/2010/01/msbuild-execution-of-soapui-testrunner/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>One deployment for all environments</title>
		<link>http://blog.goneopen.com/2010/01/one-deployment-for-all-environments/</link>
		<comments>http://blog.goneopen.com/2010/01/one-deployment-for-all-environments/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 07:24:00 +0000</pubDate>
		<dc:creator>todd</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[msbuild]]></category>

		<guid isPermaLink="false">http://blog.goneopen.com/2010/01/one-deployment-for-all-environments/</guid>
		<description><![CDATA[Deploy the package This set of instructions should be reasonably straightforward. Always have the same deployment technique throughout all environments. In this case, I am explaining a strategy that which uses MSBuild to trigger installations and upgrades. This simple tenet that can be hard to follow. Often we also need manual intervention, or simply need [...]]]></description>
			<content:encoded><![CDATA[<h1>Deploy the package</h1>

<p>This set of instructions should be reasonably straightforward. Always have the same deployment technique throughout all environments. In this case, I am explaining a strategy that which uses <span class="caps">MSB</span>uild to trigger installations and upgrades. This simple tenet that can be hard to follow.</p>

<p>Often we also need manual intervention, or simply need to break up the process. To make a process manual we should wrap a commandline with a runner process (eg a <code>bat</code> or <code>cmd</code> file). This means that manual processes are still scripted rather than <span class="caps">GUI</span>-based. Moving from isolated scripts to automation is simply the process of chaining scripts together.</p>

<p>The basic checkout-and-compile for packaging and then download-and-deploy for installation sequence should be used across the local, build, test and production environments. </p>

<h1>A basic deploy/install process</h1>

<p>From commmandline:</p>



<pre>msbuild /t:Install</pre>



<p>This command will invoke the following lifecycle (this is found in <a href="http://github.com/toddb/msbuild-deployment-sample/blob/master/scripts/build.tasks">build.tasks</a>):</p>



<pre>&lt;Target Name=&quot;Install&quot; DependsOnTargets=&quot;Package;Extract;Deploy&quot;/&gt;</pre>



<p>We have already seen that packaging creates a zip file with <code>&lt;Target Name=&quot;Package&quot; DependsOnTargets=&quot;Version;Clean;Publish;Zip&quot;/&gt;</code>. The install then takes that package unzips it and then deploys. The idea here is that all it does it replicate what the user would do manually. The deploying is often quite straightforward but timeconsuming. In the sample, the main deployment is to an <span class="caps">IIS.</span> All of the third-party libraries have tasks for integration points and it worthwhile looking at them all. Personally, I am using extension pack at the moment.</p>

<p>So I am just said, the script works as though it is a person. Here&#8217;s where some complexity lies in the scripts. There are two part of the deployment scripts.</p>


<ol>
<li>the <code>Deploy</code> target is the worker for doing a deployment (that lives in the <code>build.tasks</code>)</li>
<li>the deployment scripts that are bundles in the package and do the work (eg deploy.proj)</li>
</ol>



<h2><code>Deploy</code> target as worker</h2>

<p>Let&#8217;s have a look at the targets for the worker task. Before you look at it, let&#8217;s just remember that if I did this manually I would simply get copy of the package, unzip and then double click on the bat file that invokes msbuild. This is the download-and-deploy philosophy.</p>

<p>Here are two targets: <code>Extract</code> and <code>Deploy</code>. A quick explanation that I hope really isn&#8217;t needed. <code>Extract</code> first creates a directory to put the files in it doesn&#8217;t exist and then does the extraction via an extensionpack <code>Zip</code> task. <code>Deploy</code> goes and runs the <code>deploy.bat</code> file that invokes msbuild.</p>



<pre>
&lt;Target Name=&quot;Extract&quot;&gt;
   &lt;MakeDir Directories=&quot;$(ExtractPath)&quot; Condition = &quot;!Exists('$(ExtractPath)')&quot;/&gt;
   &lt;MSBuild.ExtensionPack.Compression.Zip TaskAction=&quot;Extract&quot; ExtractPath=&quot;$(ExtractPath)&quot; ZipFileName=&quot;$(ReleaseZipFile)&quot;/&gt;
 &lt;/Target&gt;

 &lt;Target Name=&quot;Deploy&quot;&gt;
   &lt;Exec Command=&quot;$(ExtractPath)\deploy.bat $(ExtractPath)&quot; ContinueOnError=&quot;false&quot; /&gt;
 &lt;/Target&gt;
</pre>



<h2>Deployment that actually installs</h2>

<p>Now we&#8217;ll look at the deployment process once a package has been extracted more fully. Again, it doesn&#8217;t get any more complex in practice; there is just more of it. Let&#8217;s pickup from the worker process. It has just &#8220;clicked&#8221; on <code>deploy.bat</code> which effectively is the same as doing an <code>msbuild</code> command (for now let&#8217;s stay simple). It has now invoked <a href="http://github.com/toddb/msbuild-deployment-sample/blob/master/scripts/deploy.proj">deploy.proj</a> which does the work. It now goes through the motions to install the site with the <code>DeployWebsite</code> target. If you&#8217;ve installed on <span class="caps">IIS </span>this process is familiar. If not, it&#8217;s damn fine documentation! You can see that you need to create Application Pools, Http Bindings and add Applications. </p>



<pre>
  &lt;Target Name=&quot;DeployWebsite&quot; DependsOnTargets=&quot;CopyWebSite&quot;&gt;
    &lt;Message Text=&quot;Deploying site version: $(Version) for environment $(Environment)&quot;/&gt;
    &lt;CallTarget Targets=&quot;CreateAppPool&quot;/&gt;
    &lt;CallTarget Targets=&quot;CreateWebsite&quot;/&gt;
    &lt;CallTarget Targets=&quot;CreateBindingHttp&quot;/&gt;
    &lt;CallTarget Targets=&quot;CreateBindingHttps&quot; Condition=&quot;'$(Environment)'!='Test'&quot;/&gt;
    &lt;CallTarget Targets=&quot;AddApplication&quot;/&gt;
    &lt;CallTarget Targets=&quot;ModifyWebsite&quot; Condition=&quot;'$(Environment)'!='Test'&quot;/&gt;
    &lt;CallTarget Targets=&quot;SetupDirectoryBrowsing&quot; Condition=&quot;'$(Environment)'=='Test'&quot;/&gt;
    &lt;CallTarget Targets=&quot;StartWebsite&quot;/&gt;
  &lt;/Target&gt;
</pre>



<p>While we have this deployment in mind, I&#8217;ll add a couple of notes on this deployment. It has two modes of deployment: test and non-test. The test deployment doesn&#8217;t run https and it does have a multi-site structure which we use directory browsing for moving between sites. This is a bigger topic of hot-swapping sites that I might get back to.</p>

<p>A quick summary is that it is each to deploy a package in your own environment by scripting tasks you might normally do with  a point-and-click, or drag-until-you-drop, approach. This is an important start. Now you need do the same process on the build server (or build agent).</p>

<h2>Build Server deploy: allowing it to push out a deployment</h2>

<p>The build server should be no different. But it often is. It would ideally not be running as a interactive user and this can cause problems. In windows, there aren&#8217;t many good solutions. We don&#8217;t have ssh generally available that would make life easy. Running everything under Network Service or Local System is a poor solution that we often resort to.</p>

<p>Having read this entry you might asking yourself, how do we deal with the database? I&#8217;ll deal with that next because it cuts across the important issue of first-time installs and redeployments/upgrades.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.goneopen.com/2010/01/one-deployment-for-all-environments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Commandline msbuild in action</title>
		<link>http://blog.goneopen.com/2010/01/commandline-msbuild-in-action/</link>
		<comments>http://blog.goneopen.com/2010/01/commandline-msbuild-in-action/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 01:35:30 +0000</pubDate>
		<dc:creator>todd</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[msbuild]]></category>

		<guid isPermaLink="false">http://blog.goneopen.com/2010/01/commandline-msbuild-in-action/</guid>
		<description><![CDATA[Commandline msbuild So you&#8217;ve checked out the code. Now commandline it to the root folder of the project. Run msbuild.exe. Did it work? Probably not. That is because you don&#8217;t have msbuild on your path environment variable. There&#8217;s a couple of ways. When you installed Visual Studio, on the Start Menu it provides you with [...]]]></description>
			<content:encoded><![CDATA[<h1>Commandline msbuild</h1>

<p>So you&#8217;ve checked out the code. Now commandline it to the root folder of the project. Run <code>msbuild.exe</code>. Did it work? Probably not. That is because you don&#8217;t have <code>msbuild</code> on your <code>path</code> environment variable. There&#8217;s a couple of ways. When you installed Visual Studio, on the <em>Start Menu</em> it provides you with starting a console with <code>msbuild</code> on <code>path</code>.</p>

<div id="attachment_72" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1515411.png"><img class="size-medium wp-image-72" title="2010-01-15_151541" src="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1515411-300x228.png" alt="" width="300" height="228" /></a><p class="wp-caption-text">Starting console from Start Menu</p></div>

<p>Alternative one, go and update your <code>path</code> environment variable for all time.</p>

<p>[pict - Changing environment variable]</p>

<p>Alternative two, you can double click on <code>build.bat</code>. (But you are only delaying the inevitable getting msbuild on path)</p>

<div id="attachment_74" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1508341.png"><img class="size-medium wp-image-74" title="2010-01-15_150834" src="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1508341-300x179.png" alt="" width="300" height="179" /></a><p class="wp-caption-text">Double click on bat file in folder</p></div>

<p>Here&#8217;s the resulting console. Msbuild automatically uses build.proj because (a) it is a proj file and (b) it is the only one in the folder.</p>

<div id="attachment_75" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1507482.png"><img class="size-medium wp-image-75" title="2010-01-15_150748" src="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1507482-300x275.png" alt="" width="300" height="275" /></a><p class="wp-caption-text">msbuild with Help (1 of 2)</p></div>

<div id="attachment_76" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1507551.png"><img class="size-medium wp-image-76" title="2010-01-15_150755" src="http://blog.goneopen.com/wp-content/uploads/2010/01/2010-01-15_1507551-300x275.png" alt="" width="300" height="275" /></a><p class="wp-caption-text">msbuild with Help (2 of 2)</p></div>

<h1>Help as default target</h1>

<p>What you see in the screen above is that our build file by default makes no action other than to tell you what you can do. In other words, by default it won&#8217;t do bad. I therefore always have a Help target in every <code>proj</code> and <code>task</code> file and that that is the Default target. Here is an example from <code>build.tasks</code> that demonstrates how the default target is Help and what the structure of the help information.</p>


<pre>
&lt;Project DefaultTargets=&quot;HelpBuild&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;

  &lt;Target Name=&quot;HelpBuild&quot;&gt;
    &lt;Message Text=&quot;

    msbuild /t:Package

    Examples:
      msbuild /t:Install
      msbuild /t:Install /p:ReleaseEnvironment=Beta
      msbuild @build.properties /t:Package /v:d 

    Variables that can be overridden:
      DropLocation=C:\Binaries
      ReleaseEnvironment=Dev|[Test]|Beta|Prod
      BuildCmd=Build|[Rebuild] 

    Targets:
     - Compile
     - Clean
     - CleanReleases
     - Publish
     - Zip
     - Extract
     - Deploy
     - TODO

     - Package (Compile;Clean;Publish;Zip)
     - Install (Compile;Clean;Publish;Zip;Extract;Deploy) - will require IIS
                                                            setup because it 
                                                            runs the 
                                                            deploy.bat 
                                                            set of tasks

    Log output: msbuild.log

    Dependencies: Zip/Extract must have J# Redist installed

http://www.msbuildextensionpack.com/help/3.5.4.0/index.html

             &quot; /&gt;
  &lt;/Target&gt;

&lt;/Project&gt;
</pre>


<p>The general structure for help is as follows:</p>


<ul>
<li>what your likely (default) call is going be</li>
<li>examples of likely calls including variables</li>
<li>variables that can be overridden</li>
<li>targets</li>
<li>additional information</li>
</ul>



<p><em>Tip: Don&#8217;t make the text in the help wider than 64 characters so that it looks pretty in the console</em></p>

<h1><code>Build.proj</code> as manifest and linking helps</h1>

<p>When you ran msbuild, it also showed a number of <code>Help</code> targets. This is because the primary job of the <code>build.proj</code> is to link all the targets together. It looks like this and the points to note are:</p>


<ul>
<li><code>Import</code> includes each tasks</li>
<li><code>Help</code> is the default target that calls the help targets in of the child tasks</li>
</ul>



<p>Note: we need to suffix each Help (eg Build = HelpBuild, Package = HelpPackage) to avoid warnings in msbuild.</p>


<pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Project DefaultTargets=&quot;Help&quot;  ToolsVersion=&quot;3.5&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;
  &lt;Import Project=&quot;$(MSBuildProjectDirectory)\scripts\build.tasks&quot; /&gt;
  &lt;Import Project=&quot;$(MSBuildProjectDirectory)\scripts\package.tasks&quot; /&gt;
  &lt;Import Project=&quot;$(MSBuildProjectDirectory)\scripts\install.tasks&quot; /&gt;
  &lt;Import Project=&quot;$(MSBuildProjectDirectory)\scripts\db-setup.tasks&quot; /&gt;
  &lt;Import Project=&quot;$(MSBuildProjectDirectory)\scripts\migrations.tasks&quot; /&gt;

  &lt;Target Name=&quot;Help&quot; DependsOnTargets=&quot;HelpBuild;HelpPackage;HelpInstall;HelpDbSetup;HelpMigrations&quot;/&gt;
&lt;/Project&gt;
</pre>


<h2>Summary</h2>


<ul>
<li>Setup msbuild on <code>path</code></li>
<li>Always have Help as a default target</li>
<li>Tasks files need the Help target to have the task suffix to avoid warnings [bla microsoft]</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.goneopen.com/2010/01/commandline-msbuild-in-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MSBuild deployment sample for web applications</title>
		<link>http://blog.goneopen.com/2010/01/msbuild-deployment-sample-for-web-applications/</link>
		<comments>http://blog.goneopen.com/2010/01/msbuild-deployment-sample-for-web-applications/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 00:54:35 +0000</pubDate>
		<dc:creator>todd</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[msbuild]]></category>

		<guid isPermaLink="false">http://blog.goneopen.com/2010/01/msbuild-deployment-sample-for-web-applications/</guid>
		<description><![CDATA[Check out the code sample Download the Deployment Code Sample from github and select to download the zip archive of the source Overview of the code VERSION.xml build.bat build.proj lib/ MSBuildCommunityTasks/ extensionpack/ migratordotnet/ sdc/ teambuild/ scripts/ build.tasks db/ create.sql domainuser-for-db.sql drop.sql user-for-db.sql db-setup.tasks deploy.proj directorybrowsing.xml install.tasks migrations.tasks package.tasks version.tasks src/ Infrastructure/ Database/ Migrations/ Migr_001_CreateBanner_Table.cs Sql/ [...]]]></description>
			<content:encoded><![CDATA[<h1>Check out the code sample</h1>

<p>Download the <a href="http://github.com/toddb/msbuild-deployment-sample">Deployment Code Sample</a> from github and select to download the zip archive of the source</p>

<h1>Overview of the code</h1>



<pre>
    VERSION.xml
    build.bat
    build.proj

    lib/
        MSBuildCommunityTasks/
        extensionpack/
        migratordotnet/
        sdc/
        teambuild/
    
    scripts/
        build.tasks
        
        db/
            create.sql
            domainuser-for-db.sql
            drop.sql
            user-for-db.sql
        
        db-setup.tasks
        deploy.proj
        directorybrowsing.xml
        install.tasks
        migrations.tasks
        package.tasks
        version.tasks
    
    src/
        Infrastructure/
            Database/
                Migrations/
                    Migr_001_CreateBanner_Table.cs
                Sql/
                    migration-latest.sql
        Sample.sln
        UI/

    tools/
        [these are needed to be installed on machines]
</pre>



<h1>Explanation/Overview of files and folders</h1>

<p><dl><br />
<dt><code>VERSION.XML</code></dt><br />
<dd>This holds the major, minor and revision number for the product. This is effectively the marketing name of the product and is changed rarely. This &#8220;version&#8221; combined with the revision number from the source control is what is used to version <span class="caps">DLL</span>s.</dd></p>

<p><dt><code>build.bat</code> and <code>build.proj</code></dt><br />
<dd><code>Build.bat</code> is the merely a <span class="caps">GUI</span>-based, double-click runner for invoking msbuild file <code>build.proj</code>. <code>Build.proj</code> is a manifest file allowing access to the real worker tasks in the <code>scripts/</code> folder.</dd></p>

<p><dt><code>lib/</code></dt><br />
<dd>As you would expect holds all the dependent libraries. I always bundle up my script files ensuring that they are available in every environment. This project demonstrates the use of three msbuild libraries. Each have there strengths so I just use as needed and don&#8217;t get too hung up about which one. I often also bundle up the Visual Studio teambuild targets because this allows me to avoid having to install the correct version of Visual Studio on the build server (this problem has got better over time and haven&#8217;t reviewed problems here in a whiles).</dd></p>

<p><dt><code>scripts/</code></dt><br />
<dd>This is the focus of the sample. I keep my build scripts in their own folder as to not clutter up root and I keep them out of <code>src/</code> so that I get better reuse and a cleaner folder. I also keep my initial database creation scripts here too. These are the first-time creation scripts rather than the migration scripts which are in <code>src/Infrastructure/Database/</code></dd></p>

<p><dt><code>src/</code></dt><br />
<dd>Here&#8217;s the home of the application code. A couple of conventions, the demo is using a domain-driven-design naming conventions (UI, infrastructure) and java too (src cf Source). Importantly, I see that database work such as schema changes and data transformations are tightly coupled with the application code. Hence they are part of the application code base. I think this type of versioning is far simpler. There is a good blog entry that I can&#8217;t find that compares the &#8220;migration approach&#8221; versus the database compare. Both work compared with the free for all I see &#8211; I just prefer migrations and have never found its simplicity to cause problems. Plus it allows me to go up and down in migrations. The UI code is there just for illustrative purposes so that there is something to deploy.</dd></p>

<p><dt><code>tools/</code></dt><br />
<dd>All this binary packages that need to be installed on the target machine to make the system work but can&#8217;t be (or shouldn&#8217;t be bundled). If my packaging strategy is to &#8220;download-and-deploy&#8221; my source code strategy is to &#8220;checkout-and-compile&#8221;. So I want as much as possible available with source so that in two year&#8217;s time I don&#8217;t have to go looking. It is surprising how this pushes some people&#8217;s buttons.</dd><br />
</dl></p>

<h1><span class="caps">MSB</span>uild files: <code>proj</code> vs <code>tasks</code> vs <code>xml</code></h1>

<p>My assumption is that you know how msbuild works and the structure of the xml files. I use three extensions to mark out different types. Yet, they all follow the xml schema definition for msbuild.</p>

<p><dl><br />
    <dt><strong>proj:</strong></dt><br />
    <dd>a file to be run by msbuild &#8211; hopefully the only one in the folder so that you don&#8217;t have to specify it</dd><br />
    <dt><strong>tasks:</strong></dt><br />
    <dd>a specific set of tasks that is included/imported into a <strong>proj</strong> file and allows for clarity of purpose and reuse<dd><br />
    <dt><strong>xml:</strong></dt><br />
    <dd>a set of properties that are imported into a <strong>task</strong> or <strong>project</strong> file</dd><br />
</dd></p>]]></content:encoded>
			<wfw:commentRss>http://blog.goneopen.com/2010/01/msbuild-deployment-sample-for-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction to using msbuild to manage (asp.net mvc) application lifecycles</title>
		<link>http://blog.goneopen.com/2010/01/introduction-to-using-msbuild-to-manage-asp-net-mvc-application-lifecycles/</link>
		<comments>http://blog.goneopen.com/2010/01/introduction-to-using-msbuild-to-manage-asp-net-mvc-application-lifecycles/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 23:25:25 +0000</pubDate>
		<dc:creator>todd</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[msbuild]]></category>

		<guid isPermaLink="false">http://blog.goneopen.com/2010/01/introduction-to-using-msbuild-to-manage-asp-net-mvc-application-lifecycles/</guid>
		<description><![CDATA[Introduction: what&#8217;s there to really manage? Part 1: Code Overview Part 2: Commandline msbuild in action Part 3: Understanding the packaging Part 4: Build &#38; Test on your local machine Part 5: First-time installs and redeployments Parts 5-7 to come Summary and References Introduction Ever since &#8230; well since ever &#8230; I have needed to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="../introduction-to-using-msbuild-to-manage-asp-net-mvc-application-lifecycles/">Introduction: what&#8217;s there to really manage?</a> <br />
<a href="../msbuild-deployment-sample-for-web-applications/">Part 1: Code Overview</a><br />
<a href="../commandline-msbuild-in-action/">Part 2: Commandline msbuild in action</a><br />
<a href="../understanding-the-packaging/">Part 3: Understanding the packaging</a><br />
<a href="../one-deployment-for-all-environments">Part 4: Build &amp; Test on your local machine</a><br />
Part 5: First-time installs and redeployments<br />
Parts 5-7 to come<br />
<a href="../msbuild-overview/">Summary and References</a></p>

<h1>Introduction</h1>

<p>Ever since &#8230; well since ever &#8230; I have needed to manage the lifecycle of my applications. Through-the-GUI approaches hit a limit of manageability quickly so like most others I use scripting. In asp.net mvc, I use msbuild. It is already part of the .Net framework and generally accepted. I say generally accepted because it is not used a lot where I work. Only some seniors in the dotnet space actually use this toolset to manage their application lifecycle. This is a pity because many of these seniors have actually had a life before dotnet and often microsoft. They know about commandline tools. One of the problems for me is that this also means that we don&#8217;t have emerging developers who can actually think through the lifecycle of their applications, let alone script its phases. So let me get this little rant out of the way &#8230; in microsoft&#8217;s <span class="caps">GUI</span>-based application-lifecycle-management approach they attempt to make development accessible to a wider audience and speed up development; the wider goal is to commoditise development which in effect increases the uptake of microsoft products (ie revenues). The effect is that developers are deskilled, the application lifecycle is fragmented and unreliable across environments. Msbuild for all its limitations helps us to counter these problems: the build scripts help increase the transparency of the lifecycle and allow us to reproduce each step through each environment. </p>

<p>I personally find msbuild quirky and many features counter intuitive. I would really like to add &#8220;at first&#8221; after the counter intuitive but actually I still find its design that way. Output params, task items, default values for parameters are examples. But it is powerful and can do the job. If I had my way I would head down the Rake road like many others already have. It is cleaner and clearer: simply put, its build for purpose. Roll on iron ruby!</p>

<p>So this series of blogs spell out how I go about deploying web apps. There are lots of variations within each step that I will attempt to avoid distracting you with. So my goals is the illustrate the general approach with specific examples. These examples are taken over the last four projects that I have worked on.</p>

<h1>Application lifecycle</h1>

<p>The application lifecycle are the phases through environments that your code goes through. Here I mean that code are your binaries, data, configuration, documentation and setup scripts. Take a look at my provisional/simplified list below:</p>


<ul>
<li><strong>Environments:</strong> Local(Dev), Build, Test, Production (perhaps even pre-production as a clone of production)</li>
<li><strong>Configurations:</strong> Dev, Test, Production (production might be seen as the no-name environment)</li>
<li><strong>Phases:</strong> Checkout/Update, Build (Compile/ReBuild), Test, Package, Deploy</li>
</ul>



<p>Looking at the list, you&#8217;ll see that I already have added synonyms suggesting immediate difficulties in agreeing what things are called. For example, the &#8220;local&#8221; environment is often called &#8220;dev&#8221; &#8211; by local, I am meaning that you have an environment which tends to allow you to notionally pull out your <span class="caps">LAN </span>cable such that you can setup your environment for development and testing. For many, dev is something where the codebase for the dev lives but the data that they test against lives somewhere else. For me, when pursuing a layered test automation strategy, not having data under source control is a code smell: it works but it isn&#8217;t ideal.</p>

<h2>Around configuration</h2>

<p>Another complexity is matching configurations with environments. No one needs to be preached to on the importance of configuration management through the phases through the environments. Yet, this is difficult to get agreement on in dotnet because in practice microsoft&#8217;s out-of-the-box approaches are inadequate and people put up with it. My cynical view is that making providing inadequate tools creates the need for the tools in the first place because we are always seeking a solution to the fundamental problem. I think that this is also fuelled by the pleasures people in experiencing this pain. I take for instance that it is difficult to securely do a push deploy to a remote machine. By the time I exhaust all my secure options and I open it up to the Network Service which goes against all my beliefs that I experience relief and pleasure at simply getting the job done. In fact, is some weird way, I am grateful when the job is done regardless. So configuration management is just about always the bone of contention. Below are three approaches. The first two are acceptable approaches to automation. The third is still a dominant practice that I wish to discount.</p>

<p><strong>Option one:</strong> save each environment configuration in source control<br />
<strong>Option two:</strong> save each environment&#8217;s configuration in their environment and pass through at deployment<br />
<strong>Option three:</strong> manually update environment configuration in an ad hoc way</p>

<p>I prefer option two and often concede with option one. Option one is currently in the sample code I will provide: there is a separate web.config for each environment. The big problem with this approach is that to automate well you really should provide a package for each environment. You do this because as a rule the configuration settings from one environment should never be available to other environments. Conversely put, production settings should never be known outside the production environment. </p>

<p>So option two is preferable because I can save the configuration of each environment in each environment. I have range of options of how I store those settings. I can use environments variables, hand into commandline msbuild or file-based settings (as response files or project files). I don&#8217;t use registry settings. Ideally, these environment settings are centrally managed but are separate from source control. </p>

<h2>Around phases</h2>

<p>You would think that the phases are generally agreed upon. I don&#8217;t think so. At best I get agreement on the get source code (checkout/update), do something and build (compile and test in some form), and then send it somewhere to do something (deploy). the <span class="caps">GUI</span>-based tools in Visual Studio do little to help the situation for the local environment. Source control is often managed in ways that the inexperienced developer is in control. In web applications, they can then go publish which compiles, publishes and runs a local version of an application/web server. Next you can then publish from your local environment to say the test environment. That is, after you have manually updated settings in the local for the test. I want better separation and knowing what phases occur in what order and in which environment. Here&#8217;s a stab at it based on the scripts I will explain:</p>



<pre>
- Environment: Local
  - Configuration: Dev
    - Phases: Checkout, Update, Compile, UnitTest, Deploy, Migrations, IntegrationTest, AcceptanceTest
- Environment: Build
  - Configuration: Test
    - Phases: Checkout, Update, Compile, UnitTest, Package, Deploy, IntegrationTest, Notify
- Environment: Test
  - Configuration: Test
    - Phases: GetPackage, Deploy, Migrations, AcceptanceTests
- Environment: Production
  - Configuration: Producton
    - Phases: GetPackage, Deploy, Migrations
</pre>



<p>Let me compare and contrast the phases to see how each is subtly different but together they make up a coherent the application lifecyle. </p>


<ul>
<li>the local environment tends to have all phases except that in practice you don&#8217;t create packages for deployment</li>
<li>the build server in contrast is all about creating the package that will be moved through all of the subsequent environments (so it watches the source code respository and works out whether the package should be released and hence people notified)</li>
<li>the test environment is the place the confirms that the build server made the correct decisions to release the package and is also the place for verification at the system level. This environment is also the place where we try out the application and its migrations against the production data. So while the package moves forward through environments, data comes backwards. It is the place where the two get a change to meet and greet (integrate). We are looking for stability over time in the this environment. This environment may have acceptance tests that also get run to look for the &#8220;non-functional&#8221; tests.</li>
<li>the production environment should be no different to the prior (test) environment. </li>
</ul>



<h2>First-time cycle of phases versus subsequent cycles</h2>

<p>What I have actually just described are the phases went the application is actually underway. What we forget is that each environment has to be setup cycle in the first place. The classic is the new developer who takes days to get everything going. There are phases in this part of the cycle that too can be scripted. </p>



<pre>
- Environment: Local
  - Configuration: Dev
    - Phases: Setup Repository, Create Database with user perms, Create Aliases, Create IIS
- Environment: Build
  - Configuration: Test
    - Phases: Create Users, Create Database with user perms, Create Aliases, Create IIS
- Environment: Test
  - Configuration: Test
    - Phases: Create Users, Create Database with user perms, Create Aliases, Create IIS
- Environment: Production
  - Configuration: Producton
    - Phases: Create Users, Create Database with user perms, Create Aliases, Create IIS
</pre>



<h2>The goal of this approach is</h2>

<p>	* the local environment for developers is separated for all other areas of the system<br />
	* create packages on the build server that are potentially releasable to production<br />
	* deploying a package should aim for &#8220;download-and-deploy&#8221;<br />
	* configurations and dependencies should be setup only once prior to the first deploy<br />
	* deployments to test should lag development as little as possible<br />
	* the trend of success to test is the indicator of readiness for deployment to production<br />
	* changes must flow through environments in order, every time</p>

<h1>Understanding msbuild sample deployment project: an lifecycle overview</h1>


<ul>
<li>Check out the code sample</li>
<li>Overview of the code<br />
 </li>
<li>Commandline msbuild</li>
<li>Help as default target</li>
<li><code>Build.proj</code> as manifest and linking helps</li>
</ul>





<ul>
<li>build the package</li>
<li>unzip and explore</li>
<li>understand the versioning</li>
</ul>




<ul>
<li>Build in dev</li>
<li>Run the migrations in dev<br />
 </li>
<li>rebuild</li>
<li>setup the db</li>
<li>deploy to iis<br />
 </li>
<li>back in dev</li>
<li>update migrations</li>
<li>build</li>
<li>package</li>
<li>unzip</li>
</ul>




<ul>
<li>Script your initial setups</li>
<li>Scripted redeployments</li>
<li>up migrations</li>
<li>up iis</li>
</ul>




<ul>
<li>view</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.goneopen.com/2010/01/introduction-to-using-msbuild-to-manage-asp-net-mvc-application-lifecycles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
