Ответ 1
Получение развертывания App_Data при запуске с нуля
@tdykstra получил эту часть справа. Чтобы получить App_Data там (и ACL устанавливаются автоматически), я сделал следующее:
- Добавление файла-заполнителя в App_Datali >
- Установите действие сборки для содержимого на заполнителе (у моего файла-заполнителя есть текст в нем, чтобы люди, спотыкающиеся о нем, знали, почему он там).
- Не отмечена "Исключить файлы из папки App_Data" на вкладке Пакет/Публикация Web свойств проекта в VS 2010
Это создает мою папку App_Data, созданную и готовую для использования на сервере. Тем не менее, это приведет к удалению всех моих файлов всякий раз, когда я переиздаю. Это проблема №2 в моем вопросе выше и очень близко напоминает этот другой SO question/ответ.
Предотвращение удаления данных на сервере при последующих событиях публикации
В MsDeploy есть два механизма, которые могут запутаться (по крайней мере, я их смутил):
- Исключение файлов
- Правила пропустить MsDeploy
Они могут использоваться для решения проблемы в зависимости от сценария:
- решение @tdykstra, скорее всего, будет работать, если вы:
- Знайте имена файлов в App_Data заранее (например, база данных sqlite)
- У вас есть файлы, включенные в папку App_Data в вашем проекте.
- Использовать правила пропуска MsDeploy, чтобы сообщить MsDeploy полностью пропустить все удаления на сервере для этого каталога и файлов в этом каталоге. Это решает проблему во всех случаях, но гораздо более активно.
Внедрение правил пропуска MsDeploy
Чтобы реализовать правила пропуска, вам придется отказаться от щелчка правой кнопкой мыши по опции "Развернуть" в VS 2010 в пользу щелчка правой кнопкой мыши, "Пакет", перейдите в командную строку, повторно запустите пакетный файл и запустите командную строку), Если вы готовы мириться с этим опытом (я, потому что я автоматизирую все это через процесс CI), вот подробности:
-
Отредактируйте файл проекта и добавьте следующее. Обратите внимание, что аргумент AbsolutePath является регулярным выражением, поэтому вы можете получить фантазию:
<Target Name="AddCustomSkipRules"> <ItemGroup> <MsDeploySkipRules Include="SkipDeleteAppData"> <SkipAction>Delete</SkipAction> <ObjectName>filePath</ObjectName> <AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath> <XPath> </XPath> </MsDeploySkipRules> <MsDeploySkipRules Include="SkipDeleteAppData"> <SkipAction>Delete</SkipAction> <ObjectName>dirPath</ObjectName> <AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath> <XPath> </XPath> </MsDeploySkipRules> </ItemGroup> </Target>
- Пакет не развертывает проект. Это создаст zip файл и .cmd файл в целевом каталоге (определяемом "Местоположение, где будет создан пакет" на вкладке "Пакет/Публикация Web" ). По умолчанию это obj\Debug\Package (или obj\Release\Package)
- Разверните сайт с помощью полученного командного файла
В моем тестировании вы должны упаковать и запустить командный файл. В настройках файла проекта msbuild укажет необходимое правило -skip в командном файле. Однако использование функции "публиковать" прямо из VS 2010 похоже, не запускает командный файл (см. Предупреждение это пошаговое руководство)... он вызывает msdeploy напрямую и, похоже, не соблюдает правила пропуска профайла проекта. Я считаю, что это разница между VS с использованием msbuild -T: Package и msbuild -T: MsDeployPublish для создания проекта, но я этого не тестировал.
Наконец, командный файл не совсем корректен, по крайней мере, в VS 2010 SP1. Там отличное описание того, что пойдет не так в this SO answer, но в основном, VS (или, возможно, цель /t: Цель пакета - лучший преступник) устанавливает командный файл для публикации на машине без указания сайта. Чтобы исправить это, вам нужно как-то получить "? Site = sitename" (возможно, это: site = Default + Web + Site, для полного URL-адреса https://machine: 8172/MsDeploy.axd? Site = Default + Web + Site) в конце аргумента computerName.
Проблема заключалась в том, что командный файл (командный файл) имеет трудное время с использованием site = anything в командной строке, поскольку он неправильно анализирует аргумент командной строки (даже если экранирован). Я не вижу пути вокруг этой проблемы, кроме изменения файла cmd напрямую, но для тестирования я скопировал вывод msdeploy.exe, который я видел из моего неудачного тестового прогона, и изменил его, чтобы вызвать msdeploy.exe напрямую без script.
Теперь, когда он работает, я намерен работать над этим в своих процессах сборки CI. Что я буду делать для окончательного решения:
- Измените мою сборку script на использование /T: Пакет (прямо сейчас /T: MsDeploy)
- Попросите сценарий поиска/замены изменить сгенерированное развертывание cmd script
- Запустите измененное развертывание script
Это действительно должно быть проще.
Обновление
Здесь сценарий поиска/замены, с которым я столкнулся в PowerShell:
(Get-Content "project.deploy.cmd")
-replace('^set _ArgComputerName=$'
,"set ArgComputerName=https://server:8172/MsDeploy.axd?Site=Default+Web+Site")
| Out-File -Encoding ascii deploy.cmd
Как только это будет запущено, можно вызвать deploy.cmd(без опции /M ), и он будет работать как ожидалось.