Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS2012 publish to multiple locations

I am currently using the inbuilt Publish function within VS2012 to publish an ASP.NET MVC site to a file system directory share on a Web Server. Is there anyway that I can have it publish to multiple locations rather than just the one when I click the Publish button?

I don’t want to have to create a second profile and have to do the same process twice and I have looked at modifying the pubxml file by adding in an additional tag to see if the publish routine picks it up. But unfortunately it just seems to pick up the last configuration in the list.

I know the ideal would be to implement a CI solution but for the time being my hands are tied with the Publish functionality and need to keep it relatively straight forward.

Many thanks

like image 613
Cragly Avatar asked Jan 11 '13 11:01

Cragly


2 Answers

We had the same need of publishing our solution to multiple file share locations, and while the question was asked several months ago I thought that an answer could benefit to the community.

Since VS publish profiles are plain MSBuild files that can easily be extended, here is the solution I came with.

Note that I extracted some code fragments from our build process that is a bit more complex so I do not guarantee that it will all works without having to alter it a bit.

In the publish profile, I added a custom DeploymentPaths item as shown below. Note that you could define one or more additional locations.

<ItemGroup Label="Defines additional publish locations">
  <DeploymentPaths Include="\\SERVER1\ShareFolder\ProjectA\" />
  <DeploymentPaths Include="\\SERVER2\ShareFolder\ProjectA\" />
</ItemGroup>

Then I added a custom target CustomWebFileSystemPublish to run after WebFileSystemPublish. This target calls another MSBuild file publish.xml that performs the delete of existing files and copy the new files.

<!-- Custom File System Publish to deploy to additional locations based on DeploymentPaths -->
<Target Name="CustomWebFileSystemPublish" AfterTargets="WebFileSystemPublish" Condition=" @(DeploymentPaths)!='' ">
  <CreateItem Include="$(MSBuildProjectDirectory)\$(_PackageTempDir)">
    <Output ItemName="AbsoluteSourcePathItem" TaskParameter="Include" />
  </CreateItem>
  <CreateProperty Value="%(AbsoluteSourcePathItem.Fullpath)">
    <Output PropertyName="AbsoluteSourcePath" TaskParameter="Value" />
  </CreateProperty>

  <Message Text="### CustomWebFileSystemPublish" Importance="high" />
  <Message Text="### DeploymentPaths: @(DeploymentPaths)" Importance="high" />

  <MSBuild Projects="$(MSBuildProjectFile)" Properties="AbsoluteSourcePath=$(AbsoluteSourcePath)" Targets="DoPublish" />
</Target>

<Target Name="DoPublish">
  <Message Text="### DoPublish $(AbsoluteOutputPath) | %(DeploymentPaths.Identity)" Importance="normal" />
  <!-- Adjust path to the publish.xml file depending on where you put it in your solution -->
  <MSBuild Projects="..\Deployment\publish.xml" Properties="OutputPath=$(AbsoluteSourcePath);DeployPath=%(DeploymentPaths.Identity)" />
</Target>

Finally, here is the publish.xml MSBuild file

<!-- Publish.xml -->
<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <Target Name="Start">
  <PropertyGroup>
   <!-- Ensure DeployPath has the expected trailing slash -->
   <DeployPath Condition=" '$(DeployPath)' != '' and !HasTrailingSlash('$(DeployPath)') ">$(DeployPath)\</DeployPath>
  </PropertyGroup>
  <Message Text=" # Deploying from $(OutputPath) to $(DeployPath) " Importance="normal" />
 </Target>

 <Target Name="CleanDeployFolder" DependsOnTargets="Start"
      Condition=" $(DeployPath)!=''">
  <Message Text=" # Cleaning files in $(DeployPath)" Importance="normal" />

  <!-- Defines the files to clean -->
  <ItemGroup>
   <DeployCleanFiles Include="$(DeployPath)\**\*.*" />
  </ItemGroup>

  <!--Delete files in Deploy folder (folders not deleted by Delete Task)-->
  <Delete Files="@(DeployCleanFiles)" />

  <Message Text=" # Cleaning files in $(DeployPath) Completed" Importance="normal" />
 </Target>

 <Target Name="CopyToDeployFolder" DependsOnTargets="CleanDeployFolder"
      Condition=" $(DeployPath)!=''">
  <Message Text=" # Copying files to $(DeployPath)" Importance="normal" />

  <ItemGroup>
   <OutputFiles Include="$(OutputPath)\**\*.*" />
  </ItemGroup>

  <Copy SourceFiles="@(OutputFiles)" DestinationFolder="$(DeployPath)%(OutputFiles.RecursiveDir)" />

  <Message Text=" # Copying files to $(DeployPath) Completed" Importance="normal" />
 </Target>

 <Target Name="Default" DependsOnTargets="CopyToDeployFolder" 
      Condition=" $(OutputPath)!='' And $(DeployPath)!='' ">
  <Message Text=" # Deploying from $(OutputPath) to $(DeployPath) Completed" Importance="normal" />
 </Target>
</Project>
like image 187
Julien Jacobs Avatar answered Sep 25 '22 14:09

Julien Jacobs


You could create a small Windows Service that monitors a Directory and copies to multiple locations when new files are added

Try FileSystemWatcher on MSDN

like image 24
Stokedout Avatar answered Sep 23 '22 14:09

Stokedout