Не удается автоматически обновить пакет NuGet до последней версии во время сборки
У нас есть два отдельных решения.NET:
- Запуск сборки для первого решения приводит к нашему конечному продукту: куче DLL. Эти DLL доставляются нашим клиентам через пакет NuGet.
- Второе решение служит решением для тестирования продукта: к нему устанавливается пакет NuGet, он создается и выполняется - таким образом, он использует наш продукт точно так же, как и наши клиенты.
Проблема здесь заключается в том, что наш последний пакет NuGet должен автоматически устанавливаться в решение для тестирования продукта, предпочтительно во время сборки этого решения для тестирования продукта.
Основываясь на идеях из аналогичного вопроса, я дошел до настройки решения для тестирования продукта:
- Сначала я включил восстановление пакета NuGet. Это позволяет мне полностью избавиться от каталога "packages" из VCS, поскольку пакет с версией, определенной в файле packages.config, будет автоматически загружаться NuGet перед сборкой.
- Затем я добавил следующее событие предварительной сборки в Visual Studio:
$(SolutionDir).nuget\nuget update -prerelease $(ProjectDir)packages.config
, Это позволяет мне загружать последнюю версию нашего пакета NuGet во время сборки.
В настоящее время я использую описанный выше сценарий для запуска локальных сборок с использованием Visual Studio и автоматических сборок с использованием TeamCity. На первый взгляд, решение работает для обоих сценариев, но на самом деле оно не дает ожидаемого результата: когда создается решение для тестирования продукта, в bin
каталог Я не получаю последнюю версию DLL, только последнюю версию-1.
Проблема в том, что хотя nuget update
Команда обновляет все как ожидалось, включая packages.config
и .csproj
файл, их новое содержимое не принимается сборкой, поэтому, как я догадываюсь, настройки HintPath из .csproj
файл по-прежнему отражает состояние "до сборки", поэтому старые библиотеки DLL копируются в bin
каталог. Я предполагаю .csproj
файл обрабатывается только один раз: до запуска события предварительной сборки, а изменения, внесенные событием предварительной сборки, игнорируются до следующей сборки.
Я рассмотрел следующие решения:
- По-видимому, предварительной сборки недостаточно. Если бы была еще более ранняя точка, я мог бы вставить
nuget update
команда, мое решение выше, вероятно, будет работать. - Я прочитал, что могу переопределить HintPath-ы в файле.csproj, определив ReferencePath. Но я сомневаюсь, что мог бы легко найти правильный путь или я мог бы установить его достаточно рано, чтобы сборка его подобрала.
- В качестве обходного пути я мог запустить сборку дважды: продублировать шаг сборки для решения для тестирования продукта в TeamCity, и я всегда мог собрать решение дважды локально в Visual Studio.
Кто-нибудь выяснил, как автоматически обновлять пакет NuGet до последней версии во время сборки?
3 ответа
Посмотрите на сообщение в блоге, которое я только что сделал относительно этого процесса. Вместо того, чтобы настраивать что-то на сервере, я сделал это, дополнив файл Nuget.Targets, который устанавливается с помощью параметра восстановления пакета Nuget. Прелесть этого подхода в том, что он выполняется локально И на сервере (поэтому вы можете увидеть любые возможные побочные эффекты, прежде чем нарушать сборку)
Подробности размещены здесь: http://netitude.bc3tech.net/2014/11/28/auto-update-your-nuget-packages-at-build-time/
Я думаю, что поставить автоматическое обновление на этапе предварительной сборки это не стиль NuGet. Вы можете понять, что вам нужна эта операция каждый раз, когда вы делаете это. Главным образом потому, что это может увеличить время сборки. Например, когда вы используете TDD и часто перестраиваете проект и запускаете тесты, вы ожидаете, что это будет сделано быстро. Кроме того, он может обновить неожиданные пакеты и что-то сломать, после чего вы можете потратить много времени на поиск проблемы.
Предлагаю делать обновление как отдельный шаг. На TeamCity вы можете использовать NuGet installer
шаг строительства. Для выполнения обновления просто установите два флажка в нижней части шага конфигурации:
Кроме того, если вы хотите сохранить результат обновления после успешной сборки и прохождения теста, вы можете добавить более поздний шаг сборки, который фиксирует эти изменения в VCS (например, с помощью cmd или PowerShell).
Когда вы работаете локально, я рекомендую запускать пакеты обновлений один раз, прежде чем начинать работу с проектом. Ты можешь использовать Package Manager Console
для этого с командой Update-Package -IncludePrerelease
,
MSBuild-решение, которое я понял, это переопределить BuildDependsOn
имущество. Поэтому я создал UpdateNugetPackages.target
который выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildDependsOn>
UpdateNugetPackages;
$(BuildDependsOn);
</BuildDependsOn>
<UpdateCommand>"$(SolutionDir)pathToYourNugetExe.exe" update "$(SolutionDir)NameOfYourSolution.sln"</UpdateCommand>
</PropertyGroup>
<Target Name="UpdateNugetPackages">
<Exec Command="$(UpdateCommand)"></Exec>
</Target>
</Project>
UpdateCommand
определяет, где и с какими аргументами nuget.exe
вызывается. Не стесняйтесь принять это для собственных нужд.
Эта цель затем будет указана в вашем .csproj
Файл. Так просто:
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- After the initial decleration of the BuildDependsOn-Property. -->
<Import Project="UpdateNugetPackages.target" Condition="Exists('UpdateNugetPackages.target')" />
Имейте в виду, что порядок импорта имеет значение. Вы должны импортировать свой целевой файл (UpdateNugetPackages.targets
), с переопределением (или на самом деле украшает) BuildDependsOn
свойство, после target-файла Microsoft.Common.targets
который определяет это. В противном случае свойство будет переопределено и удалит ваши изменения, как первоначальное определение в Microsoft.Common.targets
не включает в себя какие-либо существующие значения в BuildDependsOn
, Microsoft.Common.targets
импортируется Microsoft.CSharp.targets
для проекта C#. Таким образом, ваш импорт должен идти после импорта Microsoft.CSharp.targets
,