Как готовить Cake, используя только Frosting

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Итак, Cake. Многие слышали, многие хотели попробовать, но откладывали. Конечно, если ты все время работал на TeamCity или на Jenkins и продолжаешь, то зачем переизобретать то, что уже отлично работает? Люби свою жизнь и радуйся. Но вот, допустим, в твоей любимой жизни появился новый проект, новый дедлайн, минимум сторипойнтов до релиза, а опыта с новым сборщиком нет? Мне в этом случае и пригодился Cake.

Я сразу оговорюсь, что эта статья не подтолкнет сразу на использование Cake, как меня, и многих моих коллег не подтолкнули статьи, которые выходили ранее. По большей части потому что на него нет смысла переходить в проекте, который не приносит боль и который работает стабильно. Собираете в своем любимом Jenkins и все идет нормально. Но пусть после этой статьи в голове отложится, что Cake существует. Он в очередной раз никуда не делся, он умеет уже многое и работать с ним все проще. Гораздо проще, чем было раньше.

На что похож Cake? Наверное, любой разработчик, не погрязший в мире .Net, найдет свою аналогию: gradle, gulp, golang make. Make-системы не откровение в 2020 году. Это всегда было удобно, а значит — нужно и правильно. Мир .Net долгое время был обделен такими средствами. Фактически был и есть до сих пор MSBuild, но у него есть очень-очень много недостатков. Основной - кто вообще умеет им пользоваться из рядовых разработчиков? И какова целесообразность его освоения? Какие-то базовые и нужные всем вещи явно проще делать на билд-сервере. Наверное, кому-то он и удобен, но я уверен, что значимая часть коммьюнити предпочтет MSBuild'у освоить новый билд-сервер. Один раз написать конфиг и забыть как страшный сон.

А что если бы существовала make-система с DSL на C#, автокомплитом и прочими фишками типизированного языка? Да, я про Cake. В частности сейчас пойдет разговор про библиотеку Cake.Frosting, являющуюся одним из раннеров make-системы.

Подробней про доступные раннеры можно прочитать тут: Cake Runners

С Frosting все привычно — самодокументирующийся Api с которым почти сразу находишь общий язык. Методы расширения, загружаемые из Nuget — на любой случай жизни, структура проекта, похожая на смесь тестов или бенчмарков и хоста Asp. Все решения угадываются сразу, все как дома.

Frosting от остальных раннеров Cake отличается тем, что существует не в виде тулза, а в виде отдельного проекта, который можно докинуть в solution и хранить вместе с ним в репозитории. Это невероятно упрощает работу с системой. Фактически стоит просто создать новый проект, подключить к нему зависимость Cake.Frosting, сконфигурировать Build-хост и можно запускать этот проект командой.

dotnet run

Чтобы нам стало еще проще, существует темплейт проекта. К нему в комплект даже идут шелл-скрипты для Mac OS, Linux и Windows, подгружающие SDK, если его нет в окружении. Через них стоит вызывать сборку вместо dotnet CLI, если в этом есть необходимость.

Тут можно почитать подробнее об этом: Frosting Bootstraping

После того, как проект создан, можно начинать конфигурировать процесс сборки. Из основных мест для нашего кода мы сразу обращаем внимание на прогрев и очистку системы перед сборкой — это соответствующие методы класса Lifetime: Setup и TearDown. В них привычно делать уборку артефактов до и после сборки.

Вторая интересующая нас часть проекта — папка Tasks. Тут хранятся все шаги сборки в виде классов -наследников от FrostingTask<Context>.

Задачи автоматически регистрируются в IoC контейнере, как мы привыкли в Asp. Более того, Frosting реализует точно такой же паттерн с DI через IServiceCollection, к которому мы все привыкли.

Порядок выполнения билд-шагов определяется их зависимостями. Анализ зависимостей начинается с корня графа, по умолчанию это задача Default. Для того, чтобы уведомить систему, что эта задача зависит от другой, ей можно установить атрибут

[Dependency(typeof(MyPreviousTask))]

Где MyPreviousTask — это задача, которая должна завершиться ранее помеченной.


Список задач может быть любым, в том числе привычный нам:

  1. Восстановление пакетов.

  2. Билд.

  3. Прогон unit-тестов.

  4. Publish.

  5. Поставка артефактов.

В качестве поставки артефактов мы можем делать как привычную нам архивацию и отправку в среду исполнения приложения, так и упаковку приложения в образ docker, словом — все, что мы можем написать на C#.

Как уже было сказано выше, на данный момент существует масса пакетов с расширениями контекста выполнения, понимающего, благодаря им, множество команд сборки. Копирование файлов, удаление, логирование и т. д.

Единственный минус такого похода — захламление IntelliSense окна чудовищным количеством методов, но когда это нас останавливало?

По случаю хотелось бы напомнить про относительно свежую фичу .Net coreself-contained приложения. В этом способе публикации надо явно задать версию рантайма, в результате чего формируется не библиотека, исполняемая в контексте dotnet, а запускаемое приложение, содержащее рантайм, так сказать, «в себе». Она может пригодиться при упаковке в образ без установленного рантайма, если по каким-то причинам установить последний нельзя. Нет никаких причин не делать этого в Cake.

Когда все готово, настроено и залито в репозиторий, мы делаем в TS или Jenkins всего одну команду

dotnet run ./Build/Build.csproj

Путь до проекта у вас будет свой (Ваш Кэп) и смотрим, как происходит медитативный процесс сборки. Frosting пишет события сборки в стандартный вывод, который читает билд-сервер, так что никакие данные не пропадут.

Конечно, это минимальный и самый простой сценарий использования системы. Билд-сервер может передать в dotnet аргументы при вызове билда Frosting. Например, чтобы в дальнейшем установить версию сборки или образа или тип рантайма или папки назначения — для публикации.

В общем — полный простор фантазии.

Мотивация

  1. Это удобно. Вы пишете на своем основном языке и не зависите от выразительности скриптов и настроек/плагинов билд-сервера;

  2. Это мобильно. Вы заливаете код в репозиторий и он универсально запускается на любом билд-сервере. И никакого вендор-лока.

  3. Это версионно. Код сборки хранится в репозитории. Вместе с самим релизом.

  4. Это позволяет экономить. Если тарифный план билд-сервера не позволяет делать много билд-конфигов, вам достаточно одного, запускающего разные проекты. Тот же результат без лишних трат.

  5. Это легко. IntelliSense, автокомплит, разберется даже обленившийся senior.

Проблемой же может стать отсутствие в Cake необходимых интеграций с линтерами, сонарами и т. д. Этот вопрос следует уточнить перед использованием системы. Или дописать свои расширения, залить в Nuget и быть очень-очень хорошим человеком.

Бонусом — пример использования Cake.Frosting на github. Для «затравки» так сказать: Link

Ссылка на сайт проекта Cake

Источник: https://habr.com/ru/post/535106/


Интересные статьи

Интересные статьи

Laravel – классный PHP-фреймворк, мы им постоянно пользуемся в компании. Но как известно, ничто в мире не идеально, можно всегда предложить улучшения.Несколько недель наз...
Чем особенно хорош Vim/Neovim? Тем, что твой инструментарий — это не только редактор (который сам по себе сильно расширяем плагинами и имеет богатый базовый функционал и очень гибок в области кас...
Но если для интернет-магазина, разработанного 3–4 года назад «современные» ошибки вполне простительны потому что перед разработчиками «в те далекие времена» не стояло таких задач, то в магазинах, сдел...
Введение Несколько лет назад, мы решили, что настало время поддержать SIMD код в .NET. Мы представили пространство имен System.Numerics с типами Vector2, Vector3,Vector4 и Vector<T>. Эти т...
Хабр, привет! Так получилось, что меня давно просили сделать старую настольную игру из СССР — «Сражение». Вот пришло время выполнять обещание, заодно решила показать как создавать макеты для ...