15

I use the following script to deploy my ASP.NET MVC app to our web server:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MySolution.sln^
/p:Configuration=TeamCity-Test^
/p:OutputPath=bin^
/p:DeployOnBuild=True^
/p:DeployTarget=MSDeployPublish^
/p:MsDeployServiceUrl=https://mywebserver.com:8172/msdeploy.axd^
/p:username=MyDomain\MyUser^
/p:password=MyPassword^
/p:AllowUntrustedCertificate=True^
/p:DeployIisAppPath=mywebsitename.com^
/p:MSDeployPublishMethod=WMSVC

Now I need to specify to not sync the /uploads folder. Can I specify that in this script? Thanks!

Clarification: I have the Uploads folder in my project. I'd like for Web Deploy to create the folder. I do not want it to delete the folder/subfolders/files from my web server because it contains user-uploaded content.

Clarification #2: I just found the SkipExtraFilesOnServer=True option. However, I don't want this to be global. I'd like to set it to a single folder.

Mike Cole
  • 14,474
  • 28
  • 114
  • 194

1 Answers1

21

UPDATE: Apparently, what you really want is prevent web deploy from removing existing directory on the destination server, but still have the folder created in case it's not there. You can accomplish this as follows:

  • create YourWebProjectName.wpp.targets file next to you the project file with the following content:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
          <MsDeploySkipRules Include="SkipELMAHFolderFiles">
          <SkipAction></SkipAction>
          <ObjectName>filePath</ObjectName>
          <AbsolutePath>$(_DestinationContentPath)\\NameOfYourFolder\\.*</AbsolutePath>
          <Apply>Destination</Apply>
          <XPath></XPath>
        </MsDeploySkipRules>
    
        <MsDeploySkipRules Include="SkipELMAHFolderChildFolders">
          <SkipAction></SkipAction>
          <ObjectName>dirPath</ObjectName>
          <AbsolutePath>$(_DestinationContentPath)\\NameOfYourFolder\\.*\\*</AbsolutePath>
          <Apply>Destination</Apply>
          <XPath></XPath>
        </MsDeploySkipRules>
      </ItemGroup>
    </Project>
    

Change NameOfYourFolder and YourWebProjectName accordingly. This assumes, you have it in the root, I believe, you can use relative path if it's not the case.

  • The first MsDeploySkipRules entry tells webdeploy not to remove any files in Name_OfYourFolder.
  • The second MsDeploySkipRules tells webdeploy not to remove any child folders in Name_OfYourFolder.

Also, to have the folder created if it's not present on the destination server, you have to do the following:

  • include the folder into the project
  • add a dummy DeployemntPlaceholder.txt file into it and include it into the project as well

DeployemntPlaceholder.txt is required to tell MSBUild to add the folder into the package: empty folders are ignored.

I've tested this approach and it works fine when you run publish in the manner you've shown. I've used this answer to get the msbuild items syntaxt right. I believe, this is a MSBuild way to customize flags, passed to webdeploy by MSBuild Deployment Pipeline.

If you ran MSDeploy directly, you could use skip arguments in the following manner:

-skip:objectname='filePath',absolutepath='logs\\.*\\someNameToExclude\.txt'

UPDATE 2

You might also want to have ACL write permissions set on your \Uploads folder - there's a complete guide to do this: Setting Folder Permissions On Web Publish

Conserning the original question "Specifying folders not to sync in Web Deploy", the easiest way to do this is as follows:

You can create a publish profile and add the following lines:

<PropertyGroup>
  <ExcludeFilesFromDeployment>
    File1.aspx;File2.aspx
  </ExcludeFilesFromDeployment>
  <ExcludeFoldersFromDeployment>
    Folder1;Folder2
  </ExcludeFoldersFromDeployment>
</PropertyGroup> 

I've tested this approach for excluding files using publish profiles. An easy guide is here (scroll to Edit the .pubxml file to exclude robots.txt section).

You can also do this in .wpp.targets file or edit you csproj. See more information at Web Deployment FAQ for Visual Studio and ASP.NET

Community
  • 1
  • 1
Isantipov
  • 19,491
  • 2
  • 26
  • 41
  • Sorry, I should have clarified: I want Web Deploy to create the folder because it exists in my solution. I just don't want it to delete any files/subfolders. This is a folder with user uploaded content and I don't want to lose it. – Mike Cole Aug 16 '13 at 15:34
  • @MikeCole , do you have the files in the directory included into the project? – Isantipov Aug 18 '13 at 14:13
  • Yes, I created an \Uploads folder in the project. However, it is not required to be there - I could remove it if the answer requires. – Mike Cole Aug 18 '13 at 14:21
  • @MikeCole , I've updated the answer to allow not deleting existing files, but this requires you to have the folder on the server, not sure how to have it created if it's not there. – Isantipov Aug 18 '13 at 15:35
  • @MikeCole , ok, I've had a look at the Microsoft.Web.Publishing.targets and updated the answer to have the folder deployed, but all the additional files on the server not removed. You'll need to have the folder included into project *along with* a deployment placeholder file (I use deploymentPlaceholder.txt file) to ensure its deployed, but not the rest of the files, you don't want to be deployed. – Isantipov Aug 18 '13 at 16:04
  • Do I need to tell the deploy process to target the targets file? Or does it just know? – Mike Cole Aug 19 '13 at 16:34
  • When I add the targets file, I get the following error during MSBuild: `The project file could not be loaded. There are multiple root elements` – Mike Cole Aug 19 '13 at 18:12
  • 1
    @MikeCole , I believe you're getting `The project file could not be loaded. There are multiple root elements` error due to the missing project node in *YourWebProjectName.wpp.targets* file. I've updated the answer (it looks like `` node was not shown due to markdown formatting being wrong). – Isantipov Aug 20 '13 at 09:38
  • Yeah this does not work at all. It still deletes all folders on the server that don't exist in my source code. – The Muffin Man Apr 15 '14 at 23:15
  • @TheMuffinMan are you sure, you've changed skip directives correctly to match your folder structure? – Isantipov Apr 16 '14 at 12:59
  • If I have a folder in the root `TestFolder` then it should be `$(_DestinationContentPath)\\TestFolder`? (For now let's ignore the rule for child folders/files) – The Muffin Man Apr 16 '14 at 17:52
  • 1
    I think, you should have exactly 2 skip rules: one for files and 1 for folders (see the code in the answer). If your folder is in root:For files: '$(_DestinationContentPath)\\TestFolder\\.*' For folders: $(_DestinationContentPath)\\TestFolder\\.*\\* – Isantipov Apr 17 '14 at 15:54
  • 1
    To get rid of the `dummy` files, take a look here in the `CreateEmptyFolders` target: http://stackoverflow.com/a/23812739/114029 – Leniel Maccaferri May 22 '14 at 23:00
  • @LenielMacaferi this totally makes sense to me (although I prefer the placeholder files to keep things similar in dev and prod environments). – Isantipov May 23 '14 at 10:59
  • @Isantipov: I use it in dev and prod. ;) Same behavior since you have different `.pubxml` files. One for local IIS and one for prod, etc. – Leniel Maccaferri May 23 '14 at 13:26