The evolution of deploy process, from NAnt token to config transform in MSBuild

Deploy process used to be very simple, copy/xcopy + a few manual modifications for connection strings and other stuff.

But too many manual operation in deploy is always problematic, due to tired eyes, fingers and people, etc.

Using NAnt tokenized config file looks very elegant then, here is typical layout of our project.

—-+-cfg
—-+—app.config.template
—-+—local.properties.xml
—-+—acceptance.properties.xml
—-+—production.properties.xml

Tokens in app.config.template will be replaced by the values defined in each properties.xml file for different environment.

After looking at Soctt Hanselmn’s post about MSDeploy and config transform in deploy process, this built-in config xml transform really impressed me, time to give it a try.


Apply config transform,

For us, the transform happens in acceptance/production is just to change connect string and set includeExceptionDetailInFaults to false.


<?xml version="1.0"?>

<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
   <connectionStrings>
      <add name="MyDB"
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
        xdt:Transform="Replace"/>
    </connectionStrings>
  </connectionStrings>
  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
  </system.web>
  <system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="DefaultServicesBehavior">
        <serviceDebug includeExceptionDetailInFaults="false" xdt:Transform="Replace"/>
      </behavior>
    </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Do a publish for this wcf service project, choose publish method as File System, the web.config in the output folder is transformed.

Build package can be done either through  GUI or command line or NANT.


  <target name="release.server" depends="">
    <msbuild project="${dir.src}/MyWcfServices/WcfServices.csproj" target="package" >
      <property name="Configuration" value="Release" />
      <property name="OutDir" value="${dir.release}/Server/" />
    </msbuild>
  </target>

The generated package:

This package can be deployed on target server by cmd, as described in readme.txt, or by IIS admin console.

Note, those deploy options won’t appear until MSDeploy is installed on IIS server through http://www.iis.net/download/WebDeploy.

Import application wizard is very friendly in normal MS way.


Here is the most beautiful step, parameterss for this deploy are automatically read from WcfServices.SetParameters.xml file located beside the package, connection string, app name, blah blah:

More transform syntax can be found at http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx

About MSDeploy package, http://msdn.microsoft.com/en-us/library/dd547591.aspx.

Our updated NAnt build script:


 <target name="release" depends="">
    <delete dir="${dir.release}" />
    <foreach item="String" in="Release Acceptance Production" delim=" " property="env">
      <echo message="releasing for env: ${env}" />
      <call target="release.client" />
      <call target="release.server" />
    </foreach>
  </target>

  <target name="release.client" depends="rebuild.assemblyinfo">
    <delete dir="${dir.release}/Client" />
    <msbuild project="${dir.src}/MyProject.UI.Wpf/MyProject.UI.Wpf.csproj"  >
      <property name="Configuration" value="${env}" />
      <property name="OutDir" value="${dir.release}/${env}/Client/" />
    </msbuild>
  </target>

  <target name="release.server" depends="rebuild.assemblyinfo">
    <msbuild project="${dir.src}/MyProject.WcfServices/WcfServices.csproj" target="Package">
      <property name="Configuration" value="${env}" />
      <property name="OutDir" value="${dir.release}/tmp/" />
    </msbuild>
    <copy todir="${dir.release}/${env}/Server/" flatten="true">
      <fileset>
        <include name="${dir.release}/tmp/_PublishedWebsites/WcfServices_Package/*.*" />
      </fileset>
    </copy>
    <delete dir="${dir.release}/tmp/" />
  </target>

I personally think this is really cool, unfortunately config transform is only available for Web project for now. I actually already did some tweet to WPF project to make it config transformable, I will put it in another post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s