Проблемы Управления Релизами Maven-Проектов При Ci-Подходе К Разработке Программного Обеспечения

После прочтения статьи «Простое управление релизами с помощью Git» Я хотел бы поделиться парой своих мыслей об управлении выпусками проектов Maven. В этой заметке я не столько предложу решение проблем, сколько хотелось бы их более корректно сформулировать.

Вкратце: основная проблема управления релизами maven-проектов — это сам maven, который не разрабатывался с учетом требований подхода CI (Continious Integration) к разработке программного обеспечения.

Парадигма версий SNAPSHOT устарела с тех пор, как CI стал стандартным подходом к разработке программного обеспечения.

Более подробная информация ниже.

Современный взгляд на CI, изложенный, например, в книге «Непрерывная доставка» предполагает, что любая ветка – это зло.

В идеале разработка должна вестись в одной ветке, стволе.

Следует по возможности избегать создания любой новой ветки разработки.

Так называемое " функциональные ветки «, ветки, единственная цель которых — отложить трудности интеграции новых функций до последнего момента, что полностью противоречит принципу Continuous Integration («непрерывной интеграции»).

Единственное место, где, на мой взгляд, можно использовать ветки, это в случае " ветка релиза ", то есть ветки, созданные для исправления ошибок в производственной версии, в то время как разработка идет параллельно в магистрали.

Более того, не стоит даже спешить с их созданием.

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

Филиал следует рассматривать как «параллельную линию развития».

Если вам нужно параллельно разрабатывать несколько строк кода, то вам нужно создать новую ветку.

На практике это [должно быть] крайне редко.

Единственный случай — исправления ошибок и сервисные релизы предыдущих версий, для которых используются ветки релизов.

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

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

Другой принцип методологии непрерывной доставки заключается в том, что каждый артефакт сборки, созданный системой CI, должен получить уникальный номер версии.

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

Например, на Staging после прохождения UAT (User Acceptance Test) тестов определенной версии в Тестовой среде.

Вместо этого артефакт с уникальной версией должен храниться в репозитории артефактов (например, Nexus, и ни в коем случае в VCS (системе контроля версий) вместе с кодом).

Если ваш проект использует maven для управления зависимостями, то настоящая проблема с управлением выпусками заключается в том, что maven не предназначен для получения каждой новой сборки новой уникальной версии.

Классическая последовательность действий для выпуска новой версии с помощью maven — вручную создать новую ветку выпуска, обновить pom.xml, собрать проект и в случае успеха зафиксировать изменения в VCS. На этом этапе уже происходит путаница версий, поскольку один и тот же артефакт теперь соответствует двум ревизиям в VCS. Мы не будем здесь поднимать тему транзакционности этих изменений.

Для автоматизации этих действий можно использовать плагин maven Release, который, однако, не решает проблему по существу и не делает maven-проект более подходящим для CI и Continuous Delivery/Deployment. На первый взгляд, использование версий SNAPSHOT может сделать возможным создание CI-сборок.

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

А если добавить версию начиная с Maven 3, то сложность согласования всех частей головоломки быстро превышает разумную.

В идеале система сборки CI сама должна генерировать номер версии артефакта и передавать его во все сборки конвейера непрерывной доставки.

Hudson/Jenkins, например, не знают, как это сделать, и имеют два фундаментальных недостатка, которые исключают их из серьезного рассмотрения при выборе CI-системы:

  1. Отсутствие поддержки языка выражений в настройках задания.

  2. Отсутствие возможности иерархического построения конфигураций с наследованием настроек плагинов (существующие плагины, решающие подобную задачу, имеют очень мало практической пользы).

Достойная система сборки CI легко справляется с задачей генерации и передачи версий сборки.

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

К сожалению, перенести версию на maven-сборку без побочных эффектов невозможно (было?) невозможно.

Максимум, что можно сделать:

   

<project xmlns=".

" xmlns:xsi=".

" xsi:schemaLocation=".

"> <modelVersion>4.0.0</modelVersion> <groupId>org.xxx</groupId> <artifactId>xxx</artifactId> <version>${ciVersion}</version> <packaging>jar</packaging> <properties> <ciVersion>0.0.0</ciVersion> </properties> mvn -DciVersion=1.1.1 deploy

Но в этом случае в pom.xml, сохраненном в репозитории maven после развертывания, будут храниться

${ciVersion}

без изменений, что станет проблемой при построении проектов, от этого зависящих.

Итак, грубо говоря, на пути к эффективному CI maven-проекту есть две проблемы:

  1. Сложность генерации и передачи уникальной версии уникальной версии через цепочку связанных заданий с использованием CI-системы.

  2. Невозможность перенести сгенерированную версию в maven-сборку.

Первую проблему можно решить правильным выбором CI-системы или дополнительными трудозатратами на настройку существующей.

Вторую проблему можно решить, например, перейдя на использование Ant+Ivy. Ivy изначально не страдает детскими болезнями maven, но требует значительно более длительной подготовки, а также его сложнее настроить (хотя это, вероятно, придется сделать только один раз).

В качестве компромисса мы теперь используем следующий подход.

  1. Вся разработка ведется в транке, настроенном для версии SNAPSHOT.
  2. CI создает транк, как только обнаруживает новую регистрацию в VCS.
  3. Когда магистраль готова к UAT, вручную запускается другая конфигурация системы/задание CI, которое:
    1. генерирует уникальную версию сборки (например, на основе ревизии VCS)
    2. побрит строящуюся ветку от VCS
    3. использует плагин версий maven для обновления версии проекта и всех подпроектов до релизной версии, созданной на шаге 1 (при желании вы можете обновить зависимости SNAPSHOT для релизной версии на этом шаге)
    4. строит проект
    5. развертывает созданные артефакты с версией выпуска в Nexus (обратите внимание, что после этого изменения в файлах pom не фиксируются в VCS)
    6. Версия VCS запоминается или создается тег.

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

    Эта работа запускается непосредственно на целевой машине через удаленный агент CI-системы, либо же все развертывание может осуществляться через ssh-соединение.

    Сценарий развертывания также хранится в VCS.

  5. Если необходимо выпустить исправление или подготовить пакет обновлений, мы разветвляем нужную ревизию (или тег) и меняем параметры выпуска системного задания CI, чтобы оно использовало новую ветку и генерировало подходящие основные/второстепенные версии встроенного артефакты.

    В случае использования Quickbuild эта процедура буквально сводится к корректировке двух-трех значений существующих параметров конфигурации без необходимости создания нового задания по шаблону.

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

Соответственно, для каждого такого подпроекта настроены свои CI и Release задания.

Если система сборки CI хорошо поддерживает иерархическую структуру заданий, то управление несколькими конфигурациями не является проблемой, поскольку все общие настройки следуют принципу DRY и хранятся только в одном месте.

Возвращаясь к заметке «Простое управление релизами с помощью Git», хотелось бы отметить, что отказ от релиза веток для многих станет непреодолимым препятствием для реализации описанного подхода.

Каждая новая ветка – зло.

Намерение раз и навсегда минимизировать количество веток весьма похвально, но при попытке поддержки более сложных вариантов использования (например, независимого выпуска исправлений) количество используемых нестандартных живых веток и сложность их использования возрастает. Но настоящая проблема, решение которой предлагается в статье, это не проблема организации ветвей/порядка работы с VCS, а проблема неспособности maven адаптироваться к подходу Continuous Integration к разработке ПО.




На основе комментариев, немного подумав, что можно предложить вместо SNAPSHOTов, я пришел к выводу, что приветствовал бы развитие maven (или другой сборки системы и системы контроля зависимостей) в следующих направлениях:
  • Поддержка «стратегий» автоматического создания версий.

    Что-то вроде: «при сборке назначайте версию артефакту по этому шаблону, используя генератор случайных чисел, ревизию VCS или что угодно» (вот здесь сегодня на помощь приходят гибкие EL-выражения Quickbuild)

  • Вместо SNAPSHOT введите концепцию сборки выпуска, чтобы maven знал, что эти артефакты, созданные и на которые ссылаются в этой конкретной сборке, больше не могут быть удалены из репозитория.

    А вот другие, номера версий которых в целом не отличаются от версий релизных артефактов, со временем можно безболезненно удалить.

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

    Если вдруг на какой-либо из них была ссылка из «релизной» сборки, то она автоматически переходит в статус релизного артефакта.

Теги: #maven #ci #ветвление #релиз #Системы контроля версий
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.