views:

31

answers:

1

We're in the process of evaluating MSBuild and Nant for deploys. We may roll our own tool. One thing that a different business unit -- let's call it DeptA -- would really like to have (as in it better have it) is the ability for someone in DeptA to read the script and see what it will do. Currently we do this with .bat files. We hates the bat files. Nasty nasty bat files's. But if we ask DeptA to learn a new script language (nant, msbuild) they may be resistant.

Ideally the build tool of choice would be able kick out a list of actions without doing anything else. Along the lines of:

  • Stop service ABC on server Z
  • Stop service DEF on server Z
  • Copy all files from \server\dirA\dirB to \server2\dirC
  • Start service ABC on server Z
  • Start service DEF on server Z
  • Run all scripts in dir \server\dirA\dirC

Is it possible to do this with MSBuild? NAnt? Without me re-learning XSL?

+1  A: 

If I was you I would actually blend MSBuild and MSDeploy. You should have your MSBuild script perform the actions like start/stop service etc. Then let MSDeploy to the file copy. With MSDeploy you can use the -whatif switch to indicate that you only want a report of the actions to be executed instead of actually executing it. MSBuild unfortunately doesn't offer such an option out of the box you will have to "build" that into your scripts. You can do this with properties and conditions. For example it might look something like this:

<Project ...>
    <PropertyGroup>
      <!-- 
          Create the property to use, and declare a default value.
          Here I've defaulted this to true because it is better to force the
          caller to explicitly specify when to perform the action instead of it
          being the default.
      -->
      <SimulateExecution Condition= '$(SimulateExecution)'==''>true</SimulateExecution>
    </PropertyGroup>

    <Target Name="Deploy">
        <Message Text="Deploy started" />

        <Message Text="Stop service ABC on server Z"/>
        <WindowsService ... Condition=" '$(SimulateExecution)'=='false' "/>

        <Message Text="Stop service DEF on server Z"/>
        <WindowsService ... Condition=" '$(SimulateExecution)'=='false' "/>

        <!-- Call MSDeploy with the Exec task. -->
        <PropertyGroup>
            <MSDeployCommand>...\msdeploy.exe YOUR_OPTIONS_HERE</MSDeployCommand>

            <!-- Append the -whatif to the command if this is just a simulation -->
            <MSDeployCommand Condition= '$(SimulateExecution)'=='false' ">$(MSDeployCommand) -whatif</MSDeployCommand>
        </PropertyGroup>


         <Exec Command="$(MSDeployCommand)" />

         ... More things here
    </Target>
</Project>

For the service actions you can use the WindowsService task from the MSBuild Extension Pack. You will have to fill in the blanks there.

When you call MSDeploy you should just use the Exec task to invoke msdeploy.exe with your parameters. If you pass the -whatif it will not actually perform the actions, just report what it would have done. These will be logged to the msbuild log. So if you invoke msbuild.exe with /fl you will get those actions written out to a file. The only issue that I've seen when taking this approach is that for msdeploy.exe you many times have to use full paths (those without ..) which can sometimes be tricky so be wary of such paths.

Sayed Ibrahim Hashimi
@jcollum: Was that not enough detail? Haven't heard anything from you on this.
Sayed Ibrahim Hashimi
Thanks for the info. That does seem to be what I'm looking for.
jcollum