I get a lot of questions regarding how to publish your web plus your database incrementally. The users of Database projects in Visual Studio 2010 are especially curious about this and how we can integrate Web Deploy with VSDDcmd.exe. I’ve put together a sample which shows how you can use Web Deploy to deploy your web content and VSDBcmd.exe to incrementally publish your database, and the sample also shows how to do this from Team Build.
I am working on creating some more formal documentation for this, but I thought you guys might find this useful before we are able to formalize it. At the end of the post you will the link to download the sample. What you are going to find below is an email which I sent to a tech writer who will be creating the formalized documentation.
What you are going to find here is a bit different from other references which you may have seen but I think that this solution is going to work nicely for enterprise customers.
Here were my guiding principles when creating this:
- · You should be able to easily publish from the dev machine in a similar way that Team Build will
- Publish process should not be drastically different when publishing locally versus Team Build, if it is then it makes it easier for devs to make things work locally but not in the team env.
- · Typical Team Build customers like to build the .sln file (instead of hand crafting .proj files which are responsible for building the individual projects)
- · We should be able to publish both Web + Web Service + DB in a single shot
- · We should make it easy to define new environments
- · You should be able to use the same outputs to publish to multiple environments if you want to
- · Admins should not have to give developers settings to target environments
- i.e. connection strings for prod cannot be checked in via the developer. This rules out using web.config transforms
Let me break down the assets quickly:
Asset name | Description |
ContactManager-WCF.sln | The solution file which will be built both locally and from Team Build |
Publish\Publish.proj | The MSBuild project file which contains the logic to publish |
Publish\EnvConfig\Env-Dev.proj | The MSBuild project file which contains the properties for the Dev environment. |
Publish\Publish-Dev.cmd | A script file which developers can double click to invoke a deploy. It just calls out to MSBuild with the correct properties set. |
Publish\Reset-Local.cmd | You can ignore this, it’s just a script I was using to reset my target env so that I could test publishing. |
Publish\Reset-Database.sql | Same as previous, you can ignore it just used for my own testing. |
Pubish\Out | The folder where the build output will be placed when building locally. |
Here is what happens:
Publish.proj has a set of targets which perform the deployment. If you want to publish locally you will not use Visual Studio (because if you did you wouldn’t be able to publish all projects at the same time), instead the developer will simply double click the Publish\Publish-Dev.cmd file. When it is executed locally the Publish.proj file will build the solution and then publish all the projects.
At the very top of that file you will find the following Import statement
This import will use the property TargetEnvPropsFile to import the environment specific properties. This gives the hook to easily define environment specific properties. In my example case I have placed those properties in the file Publish\EnvConfig\Env-Dev.proj. When publishing when I call msbuild.exe I specify the property /p:TargetEnvPropsFile=EnvConfig\Env-Dev.proj which will import all the properties from that file. You can imagine that we can create different files for different environments and we just specify a different property value and the rest of the process stays the same.
For environments which devs don’t have access to admins can create these property files and just pass a different value for TargetEnvPropsFile.
After the solution is built the Publish.proj file will perform the following:
- Publish the database using vsdbcmd.exe and pass in the .deploymanifest file which was generated from the database project
- Update the SetParameters.xml file to contain the env specific values for both web projects
- Execute the deploy.cmd file for both web projects to perform the publish
Note: I had to create a parameters.xml file for the ContactManager.Mvc project in order to enable me to easily update the WCF endpoint value for the service.
Team Build
In Team Build here is what we are going to do:
- Create a Team Build definition which will first build the .sln file and then the Publish.proj file
- Specify the properties which will cause the web packages to be created and also specify the property for the target environment
- See the image below for the Team Build setup
In the Team Build situation there are these customizations that need to be made to the Publish.proj file:
- Pick up the output location from what Team Build specifies
- Ensure that Clean in not executed (taken care of by Team Build)
- Ensure that the .sln is not built (taken care of by Team Build)
Note: You can also specify the property /p:Whatif=true if you want to simulate a publish (MSDeploy updates are spewed to the command line, and DB operations written to a .sql file).
You can download the samples below, please send me any questions/concerns with this approach.
You can find the latest sources for this at my github repository: https://github.com/sayedihashimi/sayed-samples/tree/master/ContactManager-publish-example
Sayed Ibrahim Hashimi – @SayedIHashimi
Comments are closed.