Есть ли рекомендуемый подход к настройке пакета NuGet для нескольких платформ в TeamCity с использованием MSBuild?
Я прочитал несколько постов (см. Ссылки ниже) и еще не нашел руководства по лучшим практикам, характерным для моего стека технологий.
Цель: создать единый пакет NuGet, предназначенный для нескольких платформ.NET, созданный из одного файла.csproj через TeamCity, используя MSBuild и NuGet.
Ограничения:
- Вытащите код из VCS только один раз.
- Все скомпилированные сборки должны иметь одинаковые версии.
- Одиночный.csproj (не один на целевую платформу).
Я имею в виду два подхода:
Создайте единую конфигурацию сборки. Он будет состоять из трех этапов сборки: компилировать.NET 3.5, компилировать.NET 4.0, паковать с NuGet. Каждый шаг сборки будет зависеть от успеха последнего. Единственная реальная проблема, с которой я сталкиваюсь при таком подходе (и, надеюсь, есть решение, о котором я не знаю), заключается в том, что для каждого шага сборки требуется собственный набор параметров сборки (например, system.TargetFrameworkVersion и system.OutputPath) для обозначения уникальное расположение для библиотеки DLL (например, bin\release\v3.5 и bin\release\v4.0), чтобы шаг пакета NuGet мог выполнять свою работу на основе раздела Files в файле.nuspec.
Создайте несколько конфигураций сборки. Одна конфигурация сборки на этапы сборки, описанные выше. При таком подходе легко решить проблему с параметрами сборки TargetFrameworkVersion и OutputPath, но теперь мне нужно создать зависимости моментального снимка и предоставить номер версии сборки для всех сборок. Это также израсходует слоты конфигурации сборки, что нам подходит (но не оптимально), поскольку у нас есть лицензия Enterprise.
Вариант № 1 кажется очевидным выбором. Варианты № 2 кажутся грязными.
Итак, мои два вопроса:
- Можно ли создать параметры, которые являются уникальными для шага сборки?
- Есть ли третий, лучший подход?
Рекомендации:
- Многофункциональная сборка NuGet с символами для управления внутренними зависимостями
- Nuget - решение для нескольких проектов (нацеливание на несколько фреймворков)
- http://lostechies.com/joshuaflanagan/2011/06/23/tips-for-building-nuget-packages/
- http://msdn.microsoft.com/en-us/library/hh264223.aspx
- /questions/36432829/kak-ukazat-vyihodnuyu-papku-msbuild/36432838#36432838
- http://confluence.jetbrains.com/display/TCD7/Configuring+Build+Parameters
- http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package
2 ответа
Вот мое предпочтительное решение (Вариант № 1):
Магия опирается на неудачный обходной путь. Если вы готовы пойти на этот компромисс, это решение работает. Если нет, вы можете следить за проблемой, которую я открыл, на трекере JetBrains.
Конфигурация с одной сборкой выглядит так:
Обратите внимание на название первых двух шагов сборки. На самом деле они явно названы как значения TargetFrameworkVersion для.NET 3.5 и 4.0 соответственно.
Затем в разделе "Параметры сборки" я настроил следующие параметры:
И, наконец, шаг Nuget Pack выполняет преобразование пути к файлу в соответствии с разделом о моих файлах.nuspec:
<files>
<file src="bin\release\v3.5\*.*" target="lib\net35" />
<file src="bin\release\v4.0\*.*" target="lib\net40" />
</files>
Вот решение, использующее второй подход:
Проект содержит следующие конфигурации сборки и шаблон:
Генератор номеров общих сборок является первой сборкой в цепочке. Он не делает ничего, кроме как создает номер сборки, который будут совместно использоваться зависимыми сборками. Я использую ссылочный плагин TeamCity Shared Build Number от Николаса Уильямса.
И вот известные конфигурации в шаблоне сборки:
Обратите внимание, что номер сборки исходит из идентификатора сборки Генератора номеров общих сборок, упомянутого выше. Таким образом, в моем случае идентификатор этой сборки равен 14. Также обратите внимание на переменную%TargetFrameworkVersion% в пути артефакта. К счастью, TeamCity поддерживает интерполяцию переменных практически везде.
Чтобы шаблон мог использовать номер сборки, он должен иметь зависимость моментального снимка от этой конфигурации сборки:
И, наконец (в отношении шаблона), параметры сборки практически идентичны параметрам в моем предпочтительном решении. Однако обратите внимание на дополнительный параметр конфигурации. Вот что будет переопределено наследующими конфигурациями сборки:
Затем в зависимых сборках необходимо подключить зависимость моментального снимка, чтобы номер сборки (унаследованный из шаблона) действительно работал, также принимая зависимость от конфигурации сборки с общим номером сборки:
И, конечно же, вам нужно установить реальную целевую структуру:
Теперь, когда настроены фактические сборки, вы можете настроить конфигурацию сборки пакета NuGet. Вам не нужно подключаться к корню VCS:
Но вам нужно настроить кучу зависимостей (и снимок, и артефакт):
И, наконец, все готово.