Информационный портал по безопасности » Программирование » Автоматизированное создание NuGet-пакетов

 

Автоматизированное создание NuGet-пакетов

Автор: admin от 29-12-2015, 15:57, посмотрело: 841

Автоматизированное создание NuGet-пакетов
Коль захотел ты сборки передать
И с ними пламенный привет
Нугетом не забудь запаковать
В пакет!


Сразу оговоримся, что в этой статье речь пойдёт о стеке технологий Microsoft .NET.

Часто так бывает, что какое-то подмножество проектов начинает использоваться в разных решениях.

Как правило, программисты, разглядев в соседнем проекте что-то полезное, первое время не заморачиваются — создают папку lib (dll, assemblies и т.п.) и складывают туда скомпилированные сборки из оригинального решения. Со временем становится понятно, что это не самый удобный вариант и вот почему:


  • оригинальное решение начинает развиваться в свою собственную сторону, без учёта «потребителей»: добавляются новые зависимости, обновляются версии .net и т.п. «приколы»;

  • если даже о «потребителях» задумываются, то забывают обновить сборки у них, когда выходит критическое обновление или просто новая версия, а потом всё становится ещё хуже, когда сборок становится больше одной и между ними возникают некоторые зависимости — обновляя одну сборку, получаем проблемы в момент исполнения, т.к. другая сборка может оказаться не той версии;

  • оригинальное решение перестаёт дальше разрабатываться.


Ответом на все эти неприятности может служить вынесение проектов в отдельное решение и создание NuGet-пакета, включающего общие сборки, и смена парадигмы развития этих сборок. По большому счёту, всё это можно сделать и без NuGet, но удовольствия в этом гораздо меньше.Как сделать так, чтобы NuGet-пакет собирался сам автоматически вместе с компиляцией проекта на сервере построения и включал все необходимые свистелки и гуделки — об этом и будет наш рассказ.

Изготовление NuGet-пакетов


Процесс изготовления NuGet-пакетов довольно прост. Вся общая теоретическая часть доступна и, в целом, понятна. В пакеты можно упаковывать различный контент, не только скомпилированные сборки, но и отладочные символы, картинки и т.п. ресурсы, и даже исходный код.

В данном описании мы ограничимся наиболее насущным вопросом упаковки скомпилированных сборок.

Подготовка первого NuGet-пакета


Для того, чтобы наладить автоматизированное создание NuGet-пакетов на сервере построения, надо «состряпать» первую версию пакета. Самый простой и понятный способ создания пакета – это использование NuSpec-файла, который описывает, что это будет за пакет. Получить данный NuSpec-файл можно разными способами:


  • Взять чужой пример и исправить.

  • Сгенерировать утилитой NuGet.exe (команда «NuGet.exe spec»).

  • Создать новый пакет или открыть существующий чужой пакет GUI-утилитой NuGet Package Explorer, исправить и сохранить командой «Save Metadata As…».


В принципе, можно полностью всё создание NuSpec-файла выполнить в GUI, но понимать то, как устроен NuSpec, всё же будет полезно.

Для примера, один из наших NuSpec-файлов с сокращениями выглядит как-то так:


В скрипте выполняются операции по преобразованию относительных путей в абсолютные (можно без труда найти описание доступных переменных, которые означаются CI-системой при запуске скрипта). В некоторых случаях требуется модификация NuSpec-файла в этом скрипте. Например, таким образом можно обработать создание пакетов для различных конфигураций (Any CPU, x86).

На этом, собственно, настройка автоматического механизма создания NuGet-пакетов заканчивается. Запускаем сборку на сервере построения, проверяем, что всё сработало. Для получения отладочной информации, если что-то пошло не так, не забываем писать –Verbose в параметрах скрипта в настройках определения построения. Готовые пакеты заливаем в общий ресурс или галерею и приглашаем первых пользователей.

Тонкости процесса


Как говорится, «главная задача программиста – убить в себе перфекциониста». Если внутренний перфекционист ещё не сдался, то ему должны пригодиться следующие пункты.

Кроме возможностей по созданию NuGet-пакетов, скрипт для сервера построения для каждого из пакетов может запускать утилиту генерации автодокументации на основе XML-комментариев в коде. Данная возможность удобна в том плане, что для каждой версии пакета у нас появляется своя версия автодокументации, это удобно, если пользователи применяют разные версии NuGet-пакетов. Для генерации автодокументации у нас применяется Doxygen. Вот раздел скрипта, посвящённый автодокументации:


Второй пункт будет касаться сборки проекта в случае, если в один пакет упаковываются разные версии сборок под разные версии .net framework.

Хитрости начинаются с того, чтобы заставить сервер построений собирать сборки под разные версии .net framework. Рассмотрим, проекты, которые будут собираться, в формате csproj, а не новым json-форматом файла проекта (ASP.NET5). В Visual Studio поддерживается механизм конфигурации сборок. Обычно применяется 2 конфигурации – Debug и Release, но этот же механизм позволяет настроить переключение версий .net.Автоматизированное создание NuGet-пакетов

Можно создавать свои конфигурации, что мы и делаем. К сожалению, чтобы выполнить «тонкую» настройку всех необходимых параметров, придётся открыть csproj-файл и, как минимум, прописать там TargetFrameworkVersion в каждой из секций конфигурации.
Конфигурации в Visual Studio переключаются в основном тулбаре, в определении сборки на сервере можно выбрать одновременно несколько конфигураций, которые будут компилироваться последовательно.

Стоит отметить, если у вас код под разные версии .net framework начинает различаться, то это можно обрабатывать при помощи директив:

        #if NETFX_35
            for (int i = 0; i < resValueLength; i++) 
        #else
            System.Threading.Tasks.Parallel.For(0, resValueLength, i =>
        #endif

При этом константы должны быть определены в соответствующей секции csproj-файла:

<DefineConstants>DEBUG;TRACE;NETFX_35</DefineConstants>

Когда у нас есть готовые скомпилированные сборки, давайте разберёмся, как правильно настроить nuspec. В nuspec задаются специальные каталоги под конкретные версии .net framework.

Пример секции files в NuSpec-файле:

  <files>
    <file src="Debug-Net35LogService.dll" target="libnet35LogService.dll" />
    <file src="Debug-Net35LogService.XML" target="libnet35LogService.XML" />
    <file src="Debug-Net40LogService.dll" target="libnet40LogService.dll" />
    <file src="Debug-Net40LogService.XML" target="libnet40LogService.XML" />
    <file src="Debug-Net45LogService.dll" target="libnet45LogService.dll" />
    <file src="Debug-Net45LogService.XML" target="libnet45LogService.XML" />
  </files>

Ещё одна проблема, с которой можно часто столкнуться при использовании (даже не при создании) NuGet-пакетов — проблема подключения одного проекта в несколько солюшенов. Дело в том, что в csproj-файле ссылки на сборки проставляются вплоть до конкретных dll, которые по умолчанию восстанавливаются Visual Studio в папку packages рядом с sln-файлом. Отсюда возникает проблема, когда один и тот же проект включён в несколько солюшенов, располагающихся в разных папках. Для решения этой проблемы можно воспользоваться NuGet-пакетом, который включает в себя специальный Target, который переписывает ссылки перед билдом: https://www.nuget.org/packages/NuGetReferenceHintPathRewrite.

Ещё одной особенностью использования NuGet-пакетов является тема восстановление пакетов при сборке. Дело в том, что до некоторых пор Visual Studio не имела встроенных средств восстановления пакетов, поэтому в csproj дописывался специальный Target, который отвечал за восстановление. В современных Visual Studio (2013+) это уже не актуально, следите за чистотой своих csproj-файлов, никаких Target-ов для восстановления NuGet-пакетов больше не требуется.

Ну и напоследок можно рассказать о том, что при использовании TFS папка packages по умолчанию лезет в Source Control и кто-нибудь периодически может проморгать и всё-таки зачекинить все сборки в TFS. Чтобы такого не случилось (мы уверены, что для тех, кто чекинит сборки в TFS в аду должен быть отдельный котёл), можно использовать файл .tfignore, который должен спасти от этой напасти.

Результат


Итак, выполнив всё, что описано в предложенной нами инструкции, вы можете получить готовый механизм упаковки пакетов, который работает без участия человека. Наши пакеты собираются именно так. Разве что, сама публикация требует некоторого внимания.

Полезные ссылки:





Источник: Хабрахабр

Категория: Программирование

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent