I'm trying to use WebDeploy to publish a website using custom MSDeploy skip rules and a publish profile saved in Visual Studio 2012.
I have the publish profile working from the command line, but the skip rule to skip deleting a folder isn't working.
I have an ErrorLog
subfolder in my web app with a web.config
file inside it to set the proper folder permissions. Without any skip rules, the ErrorLog
folder and web.config
file are published normally, but all existing error log files in the folder on the server are deleted on publish.
Error with <SkipAction>Delete</SkipAction>
When I add a custom skip rule to my wpp.targets
file, the skip rule is no longer accepting a value for the <SkipAction>
element. If I set <SkipAction>Delete</SkipAction>
, I get the following error:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets(4377,5): error : Web deployment task failed. (Unrecognized skip directive 'skipaction'. Must be one of the following: "objectName," "keyAttribute," "absolutePath," "xPath," "attributes.<name>.") [C:\inetpub\wwwroot\My.Website\My.Website\My.Website.csproj]
If I simply omit the <SkipAction>
element, the ErrorLog
folder is deleted when it would normally be published.
If I set <SkipAction></SkipAction>
, again, the ErrorLog
folder is deleted on publish.
If I set <KeyAttribute>Delete</KeyAttribute>
, then ErrorLog
and the web.config
file are published normally.
My understanding is that in order to use custom skip rules, you need to call MSBuild from the command line instead of publishing from within VS 2012. I'd still like to use my saved publishing profiles, however, and I understand that's now possible as of VS 2012.
My MSBuild command line:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe My.Website.sln /p:Configuration=Release;DeployOnBuild=true;PublishProfile="Test Server - Web Deploy"
My.Website.wpp.targets:
<?xml version="1.0" encoding="utf-8" ?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest> </PropertyGroup> <Target Name="AddCustomSkipRules"> <Message Text="Adding Custom Skip Rules" /> <ItemGroup> <MsDeploySkipRules Include="SkipErrorLogFolder1"> <SkipAction></SkipAction> <KeyAttribute>Delete</KeyAttribute> <ObjectName>dirPath</ObjectName> <AbsolutePath>$(_Escaped_WPPAllFilesInSingleFolder)\\ErrorLog$</AbsolutePath> <XPath></XPath> </MsDeploySkipRules> </ItemGroup> </Target> </Project>
My MSBuild output showing the custom skip rule, but still deleting the files:
GenerateMsdeployManifestFiles: Generate source manifest file for Web Deploy package/publish ... AddCustomSkipRules: Adding Custom Skip Rules MSDeployPublish: Start Web Deploy Publish the Application/package to http://testserver.domain.com/MSDEPLOYAGENTSERVICE ... Starting Web deployment task from source: manifest(C:\inetpub\wwwroot\My.Website\My.Website\obj\Release\Package\My.Website.SourceManifest.xml) to Destination: auto(). Deleting filePath (MyWeb/ErrorLog\test.txt). Updating setAcl (MyWeb/). Updating setAcl (MyWeb/). Updating filePath (MyWeb/ErrorLog\Web.config). Updating filePath (MyWeb/Web.config). Updating setAcl (MyWeb/). Updating setAcl (MyWeb/). Successfully executed Web deployment task. Publish is successfully deployed.
The publish profile is an MSBuild file. A PowerShell script is created at Properties\PublishProfiles\profilename. ps1 . dotnet publish is called to gather the files to publish to a temporary folder.
A publish profile is just an MSBuild file. When you pass in PublishProfile and DeployOnBuild=true, then the publish profile is Imported into the build/publish process. It will supply the publish properties needed to perform the publish. Let's see how that works.
pubxml and are located in the PublishProfiles folder. The PublishProfiles folder is under Properties in a C# web application project, under My Project in a VB web application project, or under App_Data in a web site project.
Basic command-line publishing The default publish folder format is bin\Debug\{TARGET FRAMEWORK MONIKER}\publish\. For example, bin\Debug\netcoreapp2. 2\publish\. The dotnet publish command calls MSBuild, which invokes the Publish target.
Edit: It turns out you are right: the skip directive is ignored when executed from Visual Studio.
Fortunately, there's a workaround.
What you want is this:
<!-- Skip the deletion of any file within the ErrorLog directory --> <MsDeploySkipRules Include="SkipErrorLogFolder1"> <SkipAction>Delete</SkipAction> <ObjectName>filePath</ObjectName> <AbsolutePath>ErrorLog</AbsolutePath> </MsDeploySkipRules>
In addition, you need to prevent VS from using the UI-task (which appears to contain a bug regarding the skip rules). You can do this by declaring the following in your wpp.targets or pubxml:
<PropertyGroup> <UseMsDeployExe>true</UseMsDeployExe> </PropertyGroup>
I've tested this locally and I can confirm that it works as desired: the additional file is updated but no files in the directory are deleted.
For reference, here is my complete .wpp.targets
file with working skip rule to skip deleting the ErrorLog
folder and custom ACLs to make the ErrorLog
folder writable on the server.
As of VS 2012 Update 3, this only works when publishing with MSBuild from the command line with the DeployOnBuild=true;PublishProfile="Test Server - Web Deploy"
options passed to MSBuild. This will not work when publishing from within VS.
<?xml version="1.0" encoding="utf-8" ?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <UseMsdeployExe>true</UseMsdeployExe> <!-- Required for the MSDeploySkipRules to work --> <DeployManagedPipelineMode>Integrated</DeployManagedPipelineMode> </PropertyGroup> <PropertyGroup> <AfterAddIisSettingAndFileContentsToSourceManifest> $(AfterAddIisSettingAndFileContentsToSourceManifest); AddCustomSkipRules; </AfterAddIisSettingAndFileContentsToSourceManifest> </PropertyGroup> <Target Name="AddCustomSkipRules"> <Message Text="Adding Custom Skip Rules" /> <ItemGroup> <MsDeploySkipRules Include="SkipErrorLogFolder"> <SkipAction>Delete</SkipAction> <ObjectName>filePath</ObjectName> <AbsolutePath>ErrorLog</AbsolutePath> <XPath></XPath> </MsDeploySkipRules> </ItemGroup> </Target> <PropertyGroup> <AfterAddIisSettingAndFileContentsToSourceManifest> $(AfterAddIisSettingAndFileContentsToSourceManifest); SetCustomACLs; </AfterAddIisSettingAndFileContentsToSourceManifest> <AfterAddDeclareParametersItemsForContentPath> $(AfterAddDeclareParametersItemsForContentPath); SetCustomAclParameters; </AfterAddDeclareParametersItemsForContentPath> </PropertyGroup> <Target Name="SetCustomACLs"> <Message Text="Setting Custom ACLs" /> <ItemGroup> <!--Make sure the application pool identity has write permission to the download folder--> <MsDeploySourceManifest Include="setAcl" Condition="$(IncludeSetAclProviderOnDestination) And Exists('$(_MSDeployDirPath_FullPath)\ErrorLog')"> <Path>$(_MSDeployDirPath_FullPath)\ErrorLog</Path> <setAclAccess>Write</setAclAccess> <setAclResourceType>Directory</setAclResourceType> <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings> </MsDeploySourceManifest> </ItemGroup> </Target> <Target Name="SetCustomAclParameters"> <Message Text="Setting Custom ACL Parameters" /> <EscapeTextForRegularExpressions Text="$(_MSDeployDirPath_FullPath)"> <Output TaskParameter="Result" PropertyName="_EscapeRegEx_MSDeployDirPath" /> </EscapeTextForRegularExpressions> <ItemGroup> <MsDeployDeclareParameters Include="Add write permission to ErrorLog folder" Condition="$(IncludeSetAclProviderOnDestination) and Exists('$(_MSDeployDirPath_FullPath)\ErrorLog')"> <Kind>ProviderPath</Kind> <Scope>setAcl</Scope> <Match>^$(_EscapeRegEx_MSDeployDirPath)\\ErrorLog$</Match> <Description>Add write permission to ErrorLog folder</Description> <DefaultValue>Default Web Site/ErrorLog</DefaultValue> <Value>$(DeployIisAppPath)/ErrorLog</Value> <Tags>Hidden</Tags> <Priority>$(VsSetAclPriority)</Priority> <ExcludeFromSetParameter>True</ExcludeFromSetParameter> </MsDeployDeclareParameters> </ItemGroup> </Target> </Project>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With