The UI provides support for pre and post build events (see the "Build Events" project property page), however some of you have been asking if it is possible to have steps invoked before or after the deployment step. This will show you how to do this.

  1. Create a simple SQL Server 2005 database project named "PrePostDeploy".
  2. For demo purposes change project to always re-create the database (right click project node in Solution Explorer | Properties | Build tab | check "Always re-create database"), by making this change we can constantly re-deploy the same build script.
  3. Open a Visual Studio command prompt so we can call MSBuild (Programs | Microsoft Visual Studio 2005 | Visual Studio Tools | Visual Studio 2005 Command Prompt).
  4. Go to the directory where you created a Database Project; in this example that will be c:\src\scratch\PrePostDeploy.
  5. Build from the command line:

    msbuild PrePostDeploy.dbproj /t:build
  6. Deploy from the command line:

    msbuild PrePostDeploy.dbproj /t:deploy
  7. The output will look something like this:

    Microsoft (R) Build Engine Version 2.0.50727.42
    [Microsoft .NET Framework, Version 2.0.50727.42]
    Copyright (C) Microsoft Corporation 2005. All rights reserved.

    Build started 1/24/2007 10:17:29 PM.
    __________________________________________________
    Project "C:\src\scratch\PrePostDeploy\PrePostDeploy.dbproj" (deploy target(s)):

    Target SqlDeploy:
    Deploying script C:\src\scratch\PrePostDeploy\sql\PrePostDeploy.(local)_SQL90.PrePostDeploy.sql to server (local)\SQL90
    Database Created.
    :
    (1 row(s) affected)

    DBCC execution completed. If DBCC printed error messages, contact your system administrator.
    C:\src\scratch\PrePostDeploy\sql\PrePostDeploy.(local)_SQL90.PrePostDeploy.sql --> Server:"(local)\SQL90", Database:"PrePostDeploy"

    Build succeeded.
    0 Warning(s)
    0 Error(s)

    Time Elapsed 00:00:00.79
  8. The key thing to note is the target name "SqlDeploy".

    If you would open the "%ProgramFiles%\MSBuild\Microsoft\VisualStudio\v8.0\TeamData\Microsoft.VisualStudio.TeamSystem.Data.Tasks.targets" file which defines the MSBuild targets and properties for our build tasks you will find that the target name "Deploy" is dependent on the "SqlDeploy" target which invokes the SqlDeployTask.

    In order to wiggle ourselves in between so we can have a pre- and post-deployment event we can hook we need to add two targets and make sure that these targets are added to the dependency chain.

    So lets do just that!
  9. Unload the project file (right click project node in Solution Explorer | Unload Project).
  10. Edit the XML project representation (right click project node in Solution Explorer | Edit <project name>.dbproj), this will open the dbproj file inside the XML editor and now we can start making the changes we need.
  11. Add two new targets named PreDeploy and PostDeploy

    <Target Name="PreDeploy"></Target>
    <Target Name="PostDeploy"></Target>
  12. Add a property group to route the dependencies

    <PropertyGroup>
          <DeployDependsOn>PreDeploy;$(DeployDependsOn);PostDeploy</DeployDependsOn>
    </PropertyGroup>

    This tells MSBuild that the existing dependency chain gets prefixed with the newly add PreDeploy target and appended with the PostDeploy target.
  13. Lets add something to the targets to do, so we can see if this works.

    <Target Name="PreDeploy">
          <Message Text="PreDeploy"/>
    </Target>
    <Target Name="PostDeploy">
          <Message Text="PostDeploy"/>
    </Target>
  14. Save the dbproj file
  15. Reload the project (right click on project node in Solution Explorer | Reload project), this will validate that your XML changes are valid
  16. Go back to the command prompt so we can deploy again from the command prompt:

    msbuild PrePostDeploy.dbproj /t:deploy
  17. Now the output will now look like this:

    Microsoft (R) Build Engine Version 2.0.50727.42
    [Microsoft .NET Framework, Version 2.0.50727.42]
    Copyright (C) Microsoft Corporation 2005. All rights reserved.

    Build started 1/24/2007 10:36:32 PM.

    __________________________________________________
    Project "C:\src\scratch\PrePostDeploy\PrePostDeploy.dbproj" (deploy target(s)):

    Target PreDeploy:
    PreDeploy
    Target SqlDeploy:
    Deploying script C:\src\scratch\PrePostDeploy\sql\PrePostDeploy.(local)_SQL90.PrePostDeploy.sql to server (local)\SQL90
    Database Created.
    :
    (1 row(s) affected)

    DBCC execution completed. If DBCC printed error messages, contact your system administrator.
    C:\src\scratch\PrePostDeploy\sql\PrePostDeploy.(local)_SQL90.PrePostDeploy.sql --> Server:"(local)\SQL90", Database:"PrePostDeploy"
    Target PostDeploy:
    PostDeploy


    Build succeeded.
    0 Warning(s)
    0 Error(s)

    Time Elapsed 00:00:01.04
  18. As you can see the pre and post deployment targets are invoked right where you expected them.

NOTE: Be aware that when the Deploy target fails the PostDeploy target will not get executed.

I hope this is useful, hereby a link to the sample project (PrePostDeploy.zip)

-GertD