Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSDeploy skip rules when using MSBuild PublishProfile with Visual Studio 2012

Tags:

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. 
like image 642
nekno Avatar asked Sep 25 '12 05:09

nekno


People also ask

What is PublishProfile?

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.

What is publish profile in MSBuild?

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.

Where is the Pubxml file?

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.

What command does Visual Studio use to publish?

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.


2 Answers

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.

like image 78
Richard Szalay Avatar answered Oct 30 '22 07:10

Richard Szalay


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> 
like image 42
nekno Avatar answered Oct 30 '22 06:10

nekno