3

I have mixed web and windows projects in VS 2013. I have a solution to build all the projects. For testing purposes I would like to automatically deploy some of the web projects into a local folder. I can do that manually, right click menu and select publish...

I have created publish profile which looks like

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>$(MSBuildThisFileDirectory)..\..\bin\PublishFolder\</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>

I can publish from the command line using msbuild as

msbuild C:\work\Source\AppManager\SereverManager.csproj  /p:DeployOnBuild=true /p:PublishProfile=Local 

That gives me the designed outcome as well.

What I would like to do is combine project build and publish. Which means I would like to deploy automatically every time I build the project.

I tried setting a batch file and calling msbuild from post-build event, but that causes VS to freeze, not even sure if that is the right approach. Is it possible to modify my csproj file to publish every time I build the project?

Yusuf
  • 33
  • 6

2 Answers2

5

Yes, this is absolutely possible. Simply add the following XML to your ServerManager.csproj file.

  <PropertyGroup>
    <DeployOnBuild>true</DeployOnBuild>
    <PublishProfile>Local</PublishProfile>
  </PropertyGroup>

UPDATED: 2017-02-13

After actually testing this solution I found Yusuf was correct and the deployment only worked when I explicitly set the DeployOnBuild and PublishProfile MSBuild properties on the MSBuild.exe call.

>"c:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild" /p:DeployOnBuild=true /p:PublishProfile=Local

Setting properties in the .csproj generally works without issue. It appears the DeployOnBuild property is special. Not sure if this is a bug or intentional but setting it in the project file or a referenced targets file is overwritten somewhere in the build. Only when you define it as a global MSBuild property by setting it as a flag on the MSBuild.exe call is it respected.

Once I discovered this I found an alternate solution that works. Pass the properties to a second MSBuild call in your project:

<Target Name="AfterBuild">
  <MSBuild Condition="'$(DeployOnBuild)'!='true'" Projects="$(MSBuildProjectFullPath)" Properties="DeployOnBuild=true;PublishProfile=Local;BuildingInsideVisualStudio=False"/>
</Target>

Now it will automatically deploy whether you build in VS or from the commandline.

chief7
  • 14,263
  • 14
  • 47
  • 80
  • Thanks @chief7 . I tried your suggestion but it didn't get me what I was looking. I even tried adding DeployOnBuild and PublishProfile in the PropertyGroup for Release Configuration – Yusuf Jan 24 '17 at 16:59
  • I've done this many times so I know it works. Are you building the Release configuration? – chief7 Jan 24 '17 at 17:06
  • Yes I am building Release configuration. I am sure it is doable, just not sure what I am missing. I have created link in the original message to copy of the csproj file. – Yusuf Jan 24 '17 at 21:49
  • I worked around it by making my project work with MSBuild but not VS. Your solution handles both cases and is more elegant. – Yusuf Feb 17 '17 at 13:42
  • Glad it was helpful. Thanks for sharing! – chief7 Mar 03 '17 at 16:59
2

Building on @chief7's answer, I was able to get this working in an MVC project in Visual Studio 2015 like so:

<Target Name="Deploy" AfterTargets="Build">
    <MSBuild
        Condition="'$(DeployOnBuild)'!='true'"
        Projects="$(ProjectPath)"
        Targets="WebPublish"
        Properties="PublishProfile=$(AutoDeployPublishProfileName)"/>
</Target>

The original answer was throwing MSB4006 for me:

There is a circular dependency in the target dependency graph involving target "AfterBuild"

This answer suggested changing the target name and adding the AfterTargets property as shown above, which worked.

As an aside for those who need to make deployment contingent on configuration (Debug, Release, etc.)—@chief7 has a great write-up on their website.

Eric Eskildsen
  • 4,269
  • 2
  • 38
  • 55