[Системы сборки] Сборка (CI/CD) проектов

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
04-Апр-2021 15:31

Tags: continuous deployment, разработка ПО, CI/CD, DevOps, системы сборки, gradlePAA: ??? Labels: gradle, kotlinВ некоторых проектах сборке отводится роль Золушки. Основные усилия команда сосредоточивает на разработке кода. А самой сборкой могут заниматься люди, далёкие от разработки (например, отвечающие за эксплуатацию, либо за развёртывание).Если сборка хоть как-то работает, то её предпочитают не трогать, и речь об оптимизации не заходит.Вместе с тем в больших гетерогенных проектах сборка оказывается достаточно сложной и к ней вполне можно подходить как к самостоятельному проекту. Если же относиться к сборке как к второстепенному проекту,то в результате будет получен неудобоваримый императивный скрипт, поддержка которогобудет в значительной степени затруднена.В этой заметке мы рассмотрим, по каким критериям мы выбирали инструментарий, а [в следующей](build-systems-2-gradle-howto-ru.md) — каким образом этот инструментарий используем.[![CI/CD (opensource.com)](https://opensource.com/sites/default/files/uploads/...rule-them-all)## Общая модель сборки проектовМодель сборки проектов во всех рассматриваемых инструментахпредставляет собой [направленный граф без циклов](https://ru.wikipedia.org/wiki/Ориентированный_ацикл...ий_граф)([орграф, DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)), а не иерархическую структуру, типичную для структурного подхода(когда процедура вызывает другие процедуры, а затем пользуется результатами).Связано это с тем, что при разработке проекта вносятся небольшие изменения и бо́льшая частьопераций по сборке не требуется. То есть организация проекта в форме орграфа является основой для того, чтобы выполнялись только те действия, которые необходимы для ближайшей задачи, тем самым часто используемые операции будут выполняться достаточно быстро.Узлами в графе являются цели или задачи. Цели — результаты, которые необходимо достичь; а задачи — операции, которые надо выполнить, чтобы достичь текущей цели. При этом задача можетбыть запущена только в том случае, когда все зависимости удовлетворены.Такая модель схватывает структуру проекта и позволяет достигать не одну конечную цель,а несколько разных целей, на основе общей системы целей/задач. Эти несколько разных целейсосуществуют вместе и их подзадачи пересекаются. Например, сборка, тестирование игенерация документации взаимосвязаны как раз таким образом.Поверх этой основной модели в ряде инструментов реализованы более высокоуровневые модели.## Декларативный или императивный стильПри написании программ часто противопоставляются императивный и декларативный стили программирования.Под *императивным* стилем понимается описание последовательности действий, описывающих, **как** прийти к какому-то результату. Причём сам результат не описывается.При использовании *декларативного* стиля описывается желаемый результат, **что** мы хотим получить.Последовательность действий при этом выбирается инструментом самостоятельно.Такое разделение в некоторой степени условно. Сравним, например, такие программы:```kotlinfun loadPerson(file: File): Person = TODO()val ivan = loadPerson("ivan")```и```kotlinfun personDefinedInFile(file: File): Person = TODO()val ivan = personDefinedInFile("ivan")```Второй пример выглядит более декларативным, хотя разница всего лишь в названии функции.Здесь можно отметить, что код, являющийся императивным на одном уровне абстракции, может оказатьсядекларативным на другом уровне абстракции.В описанной выше модели структура целей может считаться декларативной, т.к. мы называем желаемый результат,а описание шагов по достижению какой-либо цели является императивной программой. В некоторых инструментах, рассмотренных ниже, могут быть и другие декларативные элементы.## Выбор инструментаПри старте проекта иногда бывает можно оценить, насколько сложной окажется интеграция проекта.В нашем случае оказалось, что требуется собирать несколько модулей node.js, несколько go-lang, осуществлять развёртывание нескольких модулей terraform (и ни одного jvm-модуля).В других аналогичных проектах, развивавшихся "органически", сборка осуществлялась с использованием `make`, а в скриптах сборки использовались `bash`, `perl`, `python`, `php` и др. Механизм сборки было трудно поддерживать, производительностьоставляла желать лучшего и ряд возможностей не был реализован.Для нового проекта мы задумались, какой инструмент взять за основу системы сборки. Оценили такие варианты:- make,- maven,- sbt,- gradle/groovy,- gradle/kotlin.<cut/>### MakeЭта программа создана достаточно давно, широко применяется во многих проектах и, в целом,позволяет реализовывать сборку достаточно больших и сложных проектов.Плюсы- наличие компетенции;- похож на shell.Минусы- поддерживается только базовая модель целей и задач, нет поддержки понятия проекта;- запутанный синтаксис;- глобальные состояния;- нет поддержки плагинов, трудно повторно использовать части кода;- отсутствует возможность декларативного описания сборки; только императивный код.В отсутствии ограничений, в скриптах сборки можно встретить - генерацию шаблонов с помощью perl;- установку недостающих исполняемых файлов путём исполнения .sh скриптов из интернета при каждом запуске скрипта;- вызов make-файлов для подпроектов с нестандартными названиями целей;- отсутствие согласованной обработки ошибок.Такие неожиданности затрудняют поддержку и делают сборку небезопасной операцией.### MavenMaven стал революцией в системах сборки в момент своего появления. Идеи декларативногоописания проектов, широкого применения конвенций, использования плагинов, хранения артефактов в репозиториях, использования системы идентификации, включающей версии — всё это обеспечило признание и широкое использование во многих JVM-проектах по сей день.Плюсы- наличие компетенции (часть команды имеет богатый опыт работы с Maven-проектами);- развитая модель проектов и подпроектов;- поддержка плагинов;- декларативная модель;- maven wrapper.Минусы- слабая поддержка других технологий;- наличие трудно-преодолеваемых ограничений; - трудоёмкость реализации плагинов;- отсутствие удобной возможности реализации императивных скриптов;- жёсткая структура жизненного цикла;- не очень удобный XML-формат.Отсутствие императивных скриптов является и плюсом и минусом. С одной стороны, декларативный подход обеспечивает жёсткое разделение кода и модели, с другой стороны,задачи сборки зачастую требуют отдельных вставок императивной логики, и решение таких задачв maven'е мучительно.### SbtSbt — инструмент сборки Scala-проектов. Появился примерно в то же время, что и gradle.Плюсы- развитый язык;- поддержка плагинов и императивных вставок;- поддержка инкрементной сборки;- поддержка непрерывной сборки по мере изменения;- параллельное исполнение.Минусы- неожиданная модель (вместо задач — "настройки");- неявные зависимости через `.value`;- слабая поддержка других технологий (go, node.js);- неожиданный синтаксис.Sbt в целом выглядит как специализированная система для сборки Scala-проектов, нежели чем универсальный инструмент сборки любых проектов.### GradleGradle появился в 2007 году в качестве ответа на основные ограничения maven — отсутствие императивногокода, трудность реализации плагинов, неудобство при нестандартных операциях.Gradle базируется на идеях, предложенных Maven'ом, развивает их и меняет акценты.Основными частями модели gradle являются:- задачи (Task) — выполняемые операции, узел графа зависимостей, имя+описание;- проект — логическая единица организации кода, совокупность и scope задач, точка подключения плагинов;- плагин — возможность или фича, добавляемая в проект. Среди прочего — набор задач;- зависимости, проверка up-to-date.Важным усовершенствованием стало использование DSL (domain specific language), основанного на императивном языке, с помощью которого формируются элементы декларативной модели, а также решаются императивные задачи.Плюсы- поддержка модели проектов;- поддержка декларативного (основанного на модели) и императивного подхода одновременно;- поддержка инкрементной сборки;- непревзойденная гибкость; - превосходная документация (для двух диалектов сразу);- очень быстрая работа (даже определения задач выполняются только в случае необходимости);- кросс-платформенность — работает везде;- gradle wrapper — небольшой скрипт для загрузки и запуска gradle правильной версии; разработчикам не требуется вручную настраивать утилиты и обновлять при изменении версии в репозитории; - удобный и понятный DSL.Минусы- отсутствие компетенции (до этого gradle широко не применялся членами команды);- насколько мне известно, отсутствуют механизмы защиты от чрезмерного использования императивного кода. Необходимы дисциплина и следование рекомендованным практикам при разработке скриптов сборки во избежание макаронного кода;- не поддерживаются иные механизмы зависимостей, кроме JVM (maven-repository, ivy2);- необходимость предпринимать определённые усилия для того, чтобы каждая задача поддерживала проверку up-to-date (полезную для инкрементной сборки). В частности, для каждой задачи необходимо описать входные и выходные данные. В принципе, обычные возможности DAG доступны без усилий, но gradle позволяет достичь ещё более высокой скорости работы при условии указания входов и выходов.#### Выбор диалекта — gradle/groovy или gradle/kotlinИзначально gradle использовался с помощью groovy-DSL. В дальнейшем был разработан DSL на основе Kotlin'а.Плюсы Kotlin'а- компилируемый строго-типизированный язык: — защита от ошибок на этапе компиляции, — поддержка intelli-sense, — безопасный рефакторинг,- хорошая поддержка DSL;- простой синтаксис, меньше бойлерплейта, по сравнению с Java; - достаточно много сахара.Минусы- на просторах интернета большинство примеров — для groovy, вначале бывает трудно сообразить, как переписать пример на kotlin'е;- изначально был сделан gradle/groovy DSL, поэтому некоторые элементы неидеально представлены в kotlin'е (`extra`, имена задач, ...);- немного повышается порог входа в связи с необходимостью освоения нового языка.## ЗаключениеПо итогам сравнения имеющихся инструментов сборки проекта мы решилипопробовать в нашем проекте реализовать сборку и CI/CD с использованием gradle/kotlin. Этот вариант обладает рядом преимуществ в сравнении с реализацией сборки проекта на основе make/shell.### Gradle/kotlin vs makeНиже приведены сравнительные преимущества gradle/kotlin по отношению к make:Преимущества:- высочайшая скорость работы. Команда Gradle прикладывает постоянные усилия в направлении улучшения скорости и в реализации инструментов, способствующих реализации высокоскоростных скриптов. Можно добиться того, что все задачи, не требующие выполнения, будут пропущены. А задачи, требующие выполнения — выполнены только для изменившихся файлов. - унификация языка. Все задачи решаются в рамках одного компилируемого строго-типизированного языка с согласованным и продуманным синтаксисом — Kotlin. Нет необходимости изучать особенности режимов make, различия версий shell-интерпретаторов, варианты обработки параметров командной строки в разных утилитах, отдельные языки программирования для шаблонов (php?, perl?). За счёт использования современного языка со статической типизацией, исключается множество классов ошибок, характерных для скриптовых языков.- декларативная модель проектов/подпроектов и плагинов поверх декларативного орграфа задач. В make — только непосредственно императивные задачи.- возможность комбинирования декларативного и императивного подхода. Несмотря на то, что декларативный подход обеспечивает понятность и чистоту кода, лёгкость поддержки, возможности комбинирования компонентов, императивный подход может оказаться незаменимым в силу своей гибкости. Новые задачи можно вначале решить императивным способом (ad-hoc), а затем обобщить и выделить в форме декларативных конфигурируемых плагинов.- возможность создания повторно-используемых плагинов. Причем написание таких плагинов не вызывает особых сложностей и плагинам предоставляется удобный API с широкими возможностями. В случае make стандартных механизмов не предусмотрено, из-за чего возникает дублиирование кода и переизобретение велосипедов.- платформа JVM, на которой реализованы библиотеки на все случаи жизни. В make некоторые задачи требуют установки платформо-специфических приложений Недостатки:- неудобно вызывать shell-команды. Для каждой команды надо создать и настроить task. - более высокие требования к инженерной культуре — язык со статической типизацией, декларативная модель проекта, использование развитых концепций (свойства, вывод зависимостей, проверки up-to-date).В следующей части рассмотрим некоторые особенности применения gradle/kotlin к сборке не-JVM проектов.### БлагодарностиХотелось бы поблагодарить @nolequen, @Starcounter, @tovarischzhukovза конструктивную критику черновика статьи.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_sistemy_sborki (Системы сборки), #_ci/cd, #_gradle, #_devops, #_sistemy_sborki (системы сборки), #_razrabotka_po (разработка по), #_continuous_deployment, #_sistemy_sborki (
Системы сборки
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 15:12
Часовой пояс: UTC + 5