MSDeploy пропускает правила при использовании MSBuild PublishProfile с Visual Studio 2012

Я пытаюсь использовать WebDeploy для публикации веб-сайта с использованием пользовательских правил пропуска MSDeploy и профиля публикации, сохраненного в Visual Studio 2012.

У меня есть профиль публикации, работающий из командной строки, но правило пропустить удаление папки не работает.

у меня есть ErrorLog подпапка в моем веб-приложении с web.config файл внутри него, чтобы установить правильные права доступа к папке. Без каких-либо правил пропуска ErrorLog папка и web.config Файлы публикуются в обычном режиме, но все существующие файлы журнала ошибок в папке на сервере удаляются при публикации.


Ошибка с<SkipAction>Delete</SkipAction>

Когда я добавляю пользовательское правило пропуска к своему wpp.targets файл, правило пропуска больше не принимает значение для <SkipAction> элемент. Если я установлю <SkipAction>Delete</SkipAction>Я получаю следующую ошибку:

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]

Если я просто опущу <SkipAction> элемент, ErrorLog папка удаляется, когда она обычно публикуется.

Если я установлю <SkipAction></SkipAction>опять же ErrorLog папка удалена при публикации.

Если я установлю <KeyAttribute>Delete</KeyAttribute>, затем ErrorLog и web.config файл публикуется нормально.

Насколько я понимаю, чтобы использовать пользовательские правила пропуска, вам нужно вызывать MSBuild из командной строки, а не публиковать из VS 2012. Однако я все же хотел бы использовать свои сохраненные профили публикации, и я понимаю, что теперь это возможно, так как VS 2012.


Моя командная строка MSBuild:

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>

Мой вывод MSBuild показывает пользовательское правило пропуска, но все равно удаляет файлы:

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.

7 ответов

Решение

Редактировать: Оказывается, вы правы: директива пропуска игнорируется при выполнении из Visual Studio.

К счастью, есть обходной путь.

То, что вы хотите, это:

<!-- Skip the deletion of any file within the ErrorLog directory -->
<MsDeploySkipRules Include="SkipErrorLogFolder1">
  <SkipAction>Delete</SkipAction>
  <ObjectName>filePath</ObjectName>
  <AbsolutePath>ErrorLog</AbsolutePath>
</MsDeploySkipRules>

Кроме того, вам нужно запретить VS использовать UI-задачу (которая, как представляется, содержит ошибку, касающуюся правил пропуска). Вы можете сделать это, объявив следующее в вашем wpp.targets или pubxml:

<PropertyGroup>
  <UseMsDeployExe>true</UseMsDeployExe>
</PropertyGroup>

Я проверил это локально, и я могу подтвердить, что он работает как нужно: дополнительный файл обновлен, но никакие файлы в каталоге не удалены.

Для справки, вот мой полный .wpp.targets файл с рабочим правилом пропуска, чтобы пропустить удаление ErrorLog папка и пользовательские ACL, чтобы сделать ErrorLog папка для записи на сервере.

Начиная с VS 2012 Update 3, это работает только при публикации с MSBuild из командной строки с DeployOnBuild=true;PublishProfile="Test Server - Web Deploy" параметры переданы в MSBuild. Это не будет работать при публикации из 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>

Другой подход заключается в том, чтобы избежать SkipAction тег, я успешно использовал эту настройку прямо из VS 2013:

<Target Name="AddCustomSkipRules"
        AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
        <MsDeploySkipRules Include="SkipMedia">
            <objectName>dirPath</objectName>
            <absolutePath>media</absolutePath>
        </MsDeploySkipRules>
        <MsDeploySkipRules Include="SkipUpload">
            <objectName>dirPath</objectName>
            <absolutePath>upload</absolutePath>
        </MsDeploySkipRules>
    </ItemGroup>
</Target>

Насколько я могу сказать, только предостережение о том, что он будет игнорировать операции обновления, удаления и добавления.

После долгих часов просмотра в сети. я создал этот файл как {myprojectname}.wpp.targets в корневой папке сайта. это работает при публикации в визуальной студии. папка мультимедиа игнорируется. Я использую VS 2010.

<?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 - WPP Targets 2" />
        <ItemGroup>
            <MsDeploySkipRules Include="SkipErrorLogFolder">
                <SkipAction>Delete</SkipAction>
                <ObjectName>dirPath</ObjectName>
                <AbsolutePath>media</AbsolutePath>
                <XPath></XPath>
                <Apply>Destination</Apply>
            </MsDeploySkipRules>
        </ItemGroup>
    </Target>
</Project>

Это сработало для меня в 2015 году, тип проекта веб-сайта:

<!--Added inside existing <ProjectGroup> tag-->
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>

<!--Added new ProjectGroup tag inside <Project></Project>-->
<PropertyGroup>
   <WebPublishMethod>MSDeploy</WebPublishMethod>
</PropertyGroup>

<!--Added inside existing <Project> tag at the bottom-->
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
 <ItemGroup>
  <MsDeploySkipRules Include="SkipConfigFolder">
    <SkipAction></SkipAction>
    <!--<KeyAttribute>Delete</KeyAttribute>-->
    <ObjectName>dirPath</ObjectName>
    <AbsolutePath>App_Data\\Composite\\Logfiles</AbsolutePath>
    <XPath>
    </XPath>
  </MsDeploySkipRules>
 </ItemGroup>
</Target>

Работает для меня: мой полный файл prepprod.pubxml в моей папке App_Data/PublishProfiles в моем веб-решении. Web Deploy больше не удаляет файлы из папки cachefiles в webdeploy из VS 2015. Первая PropertyGroup была автоматически сгенерирована с использованием графического интерфейса веб-публикации в Visual Studio. Я добавил вторую PropertyGroup и раздел Target из предыдущих комментариев.

<?xml version="1.0" encoding="utf-8"?>
<!--
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. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <LastUsedBuildConfiguration>Production</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish>{masked}</SiteUrlToLaunchAfterPublish>
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <MSDeployServiceURL>{masked}</MSDeployServiceURL>
    <DeployIisAppPath>{masked}</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
    <MSDeployUseChecksum>true</MSDeployUseChecksum>
    <EnableMSDeployBackup>True</EnableMSDeployBackup>
    <UserName>{masked}</UserName>
    <_SavePWD>True</_SavePWD>
    <PublishDatabaseSettings>
      <Objects xmlns="">
      </Objects>
    </PublishDatabaseSettings>
    <ExcludeFilesFromDeployment>packages.config;*.bat;*.sln;*.suo,*.p4ignore</ExcludeFilesFromDeployment>
    <ExcludeFoldersFromDeployment>packages;cachefiles;.ebextensions</ExcludeFoldersFromDeployment>
  </PropertyGroup>

  <PropertyGroup>
    <AfterAddIisSettingAndFileContentsToSourceManifest>
      $(AfterAddIisSettingAndFileContentsToSourceManifest);
      AddCustomSkipRules;
    </AfterAddIisSettingAndFileContentsToSourceManifest>
  </PropertyGroup>

  <Target Name="AddCustomSkipRules">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
      <MsDeploySkipRules Include="SkipcachefilesFolder">
        <objectName>dirPath</objectName>
        <absolutePath>cachefiles</absolutePath>
      </MsDeploySkipRules>
    </ItemGroup>
  </Target>

</Project>

Я думаю, что проблема в неправильном AbsolutePath. Это должно быть регулярное выражение для соответствия файла или папки. таким образом, это должно быть должным образом экранировано. Ниже приведен пример, который работал для меня (я хотел пропустить удаление app_offline.htm, чтобы сделать доставку частью более крупного развертывания)

<PropertyGroup>
    <PackageUsingManifestDependsOn>$(PackageUsingManifestDependsOn);AddCustomSkipRules</PackageUsingManifestDependsOn>
  </PropertyGroup>
  <Target Name="AddCustomSkipRules">
    <ItemGroup>
      <MsDeploySkipRules Include="SkipAppOfflineOnDeploy">
        <SkipAction></SkipAction>
        <ObjectName>filePath</ObjectName>
        <AbsolutePath>app_offline\.htm</AbsolutePath>
        <Apply>Destination</Apply>
        <XPath></XPath>
      </MsDeploySkipRules>
    </ItemGroup>
  </Target>
Другие вопросы по тегам