title: Always remove Angular dist folder contents with WebDeploy on Destination
body: <p>We've got a single page application on Angular 5 with an ASP.NET backend, and when we compile it, the release contents for Angular are output to a folder "Project\dist". </p>
  
  <p>This works great on local dev machines, but all of the dist files are randomized with different names such as: </p>
  
  <ul>
  <li>polyfills.dc7175a7225af84b3c9b.bundle.js</li>
  <li>styles.dc7175a7225af84b3c9b.bundle.js</li>
  <li>inline.dc7175a7225af84b3c9b.bundle.js</li>
  </ul>
  
  <p>When we use Web Publishing to deploy to staging or production, everything transfers great and our custom folder in the publish profiles is included and published.</p>
  
  <p><strong>However, on the destination server (staging or production) these old, randomly named files and old (no longer used) folders persist.</strong> This results in hundreds and hundreds of old files (from old web deploys) that have accumulated on the staging and production servers. I need a method to automatically delete these every time we push updates with webdeploy.</p>
  
  <p>Ideally, the workflow is:</p>
  
  <ul>
  <li>Select publish profile, click Publish</li>
  <li>Enter my credentials</li>
  <li>Application builds successfully</li>
  <li>If app built successfully, we go delete "Project\dist" folder on the destination server. "Project" could be in c:\inetpub\www\project or d:\websites\Project, for example.</li>
  <li>Updated files are copied</li>
  <li>Web deploy executes and copies the custom files in dist folder (already working).</li>
  </ul>
  
  <p>Here's a redacted version of our current publish profile:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;!--
  This file is used by the publish/package process of your Web project. You can customize the behavior of this process
  by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. 
  --&gt;
  &lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    &lt;PropertyGroup&gt;
      &lt;WebPublishMethod&gt;MSDeploy&lt;/WebPublishMethod&gt;
      &lt;LastUsedBuildConfiguration&gt;Release&lt;/LastUsedBuildConfiguration&gt;
      &lt;LastUsedPlatform&gt;Any CPU&lt;/LastUsedPlatform&gt;
      &lt;SiteUrlToLaunchAfterPublish /&gt;
      &lt;LaunchSiteAfterPublish&gt;True&lt;/LaunchSiteAfterPublish&gt;
      &lt;ExcludeApp_Data&gt;False&lt;/ExcludeApp_Data&gt;
      &lt;MSDeployServiceURL&gt;staging.example.com&lt;/MSDeployServiceURL&gt;
      &lt;DeployIisAppPath&gt;Project&lt;/DeployIisAppPath&gt;
      &lt;RemoteSitePhysicalPath /&gt;
      &lt;SkipExtraFilesOnServer&gt;True&lt;/SkipExtraFilesOnServer&gt;
      &lt;MSDeployPublishMethod&gt;WMSVC&lt;/MSDeployPublishMethod&gt;
      &lt;EnableMSDeployBackup&gt;False&lt;/EnableMSDeployBackup&gt;
      &lt;UserName&gt;WebDeployUser&lt;/UserName&gt;
      &lt;PublishDatabaseSettings&gt;
        &lt;Objects xmlns=""&gt;
        &lt;/Objects&gt;
      &lt;/PublishDatabaseSettings&gt;
      &lt;ADUsesOwinOrOpenIdConnect&gt;False&lt;/ADUsesOwinOrOpenIdConnect&gt;
    &lt;/PropertyGroup&gt;
    &lt;Target Name="CustomCollectFiles"&gt;
      &lt;ItemGroup&gt;
        &lt;_CustomFiles Include="..\Project\dist\**\*" /&gt;
  
        &lt;FilesForPackagingFromProject  Include="%(_CustomFiles.Identity)"&gt;
          &lt;DestinationRelativePath&gt;dist\%(RecursiveDir)%(Filename)%(Extension)&lt;/DestinationRelativePath&gt;
        &lt;/FilesForPackagingFromProject&gt;
      &lt;/ItemGroup&gt;
    &lt;/Target&gt;
    &lt;PropertyGroup&gt;
      &lt;CopyAllFilesToSingleFolderForPackageDependsOn&gt;
        CustomCollectFiles;
        $(CopyAllFilesToSingleFolderForPackageDependsOn);
      &lt;/CopyAllFilesToSingleFolderForPackageDependsOn&gt;
  
      &lt;CopyAllFilesToSingleFolderForMsdeployDependsOn&gt;
        CustomCollectFiles;
        $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
      &lt;/CopyAllFilesToSingleFolderForMsdeployDependsOn&gt;
    &lt;/PropertyGroup&gt;
  &lt;/Project&gt;
  </code></pre>
  
  <p>I've tried a few accepted answer solutions already and can't get this to work:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/a/45538847/559988">https://stackoverflow.com/a/45538847/559988</a> (I tried this in the csproj and in the publish profile pubxml file.)</li>
  <li><a href="https://stackoverflow.com/a/5080942/559988">https://stackoverflow.com/a/5080942/559988</a></li>
  </ul>
  
  <p>Any ideas? I have essentially zero knowledge of web deploy aside from setting it up in IIS.</p>
  
  <p>Best,
  Chris</p>
  
  <p><strong>EDIT</strong> I've also tried this: (Based on this: <a href="https://stackoverflow.com/a/15113445/559988">https://stackoverflow.com/a/15113445/559988</a>) </p>
  
  <pre><code>  &lt;Target Name="CleanFolder"&gt;
  
      &lt;PropertyGroup&gt;
        &lt;TargetFolder&gt;$(_MSDeployDirPath_FullPath)\dist&lt;/TargetFolder&gt;
      &lt;/PropertyGroup&gt;
  
      &lt;ItemGroup&gt;
        &lt;FilesToClean Include="$(TargetFolder)\**\*"/&gt;
        &lt;Directories Include="$([System.IO.Directory]::GetDirectories('$(TargetFolder)', '*', System.IO.SearchOption.AllDirectories))"
                     Exclude="$(TargetFolder)"/&gt;
      &lt;/ItemGroup&gt;
  
      &lt;Delete Files="@(FilesToClean)" ContinueOnError="true"/&gt;
      &lt;RemoveDir Directories="@(Directories)" /&gt;
    &lt;/Target&gt;
  </code></pre>
  
  <p><strong>Update</strong>
  This is specifically what we're doing: <a href="https://docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/deploying-extra-files" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/deploying-extra-files</a></p>
  
  <blockquote>
    <p>The first comment from there is the same problem we're experiencing:
    This comes very handy in deploying Angular distribution files along
    with ASP.Net backend, whenever both SPA and the backend share the same
    single virtual application. Unfortunately, due to browser cache
    busting techniques, the bundle files for Angular deployment will
    always ship with unique names and, therefore, an msbuild
    command/attribute or other possibility to wipe the folder clean on the
    IIS side before sending the updated files would be very welcomed. If
    anyone has found a way to do that, please share.</p>
  </blockquote>
  
  <p>"Sync" functionality described here for msdeploy is exactly what we need to be doing but I don't know how to hook into this:
  <a href="https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd569034(v=ws.10)#sync" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd569034(v=ws.10)#sync</a></p>
  
  <blockquote>
    <p>In a sync operation, if the source file or folder does not exist on
    the destination, the provider creates the folder and any subfolders
    that have the corresponding files and attributes. If the destination
    folder already exists, the provider updates only those objects that do
    not match the source. This means that in some cases only one file or
    folder will be updated. Files on the destination that do not exist on
    the source will be deleted. The source and destination folders for
    contentPath do not have to have the same name. If the name of the
    destination folder differs from that of the source, the name of the
    destination folder will remain the same, but the contents of the
    folder will be updated to those of the source.</p>
  </blockquote>