Все мы давно уже привыкли к Maven, к версионности предложенной им и управлению зависимостями. Maven появился на свет, когда ежедневная сборка проекта была уделом самых смелых, когда считалось нормальным релизиться хотя-бы пару раз в год, Jenkins тогда еще назывался Hudson, а деревья были большими…

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

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

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

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

Далее мы попробуем изменить мир к лучшему и упростить себе жизнь.

Дисклеймер
Я предполагаю, что читатель знаком с Java, Maven, жизненным циклом разработки и настройкой CI/CD, понимает зачем все это ему надо и вообще ниндзя.

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

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

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

При использовании maven с релиз плагином, появляется еще одна интересная особенность: пересборка выполняется не тем же набором команд, что и оригинальная версия.

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

Теперь, когда проблема видна, давайте попробуем ее решить, так чтоб не сильно менять набор инструментов, процессов, и вообще чтоб оно само, как-нибудь.

Что требуется:

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

Предположим, что CI/CD сделает для нас получение тега и чекаут проекта.

Допустим, что тег для нас заполнен CI/CD в переменную окружения RELEASE_TAG, тогда, для того чтоб выпустить релиз, мы должны выполнить следующие команды:

mvn -B versions:set -DnewVersion=$RELEASE_TAG (1)
mvn -B deploy (2)

1 — обновляет версии в pom-файлах проекта и его модулей
2 — выполняет сборку и, при правильной настройке проекта, загружает артефакты в репозиторий

Не забываем ставить флаг -B, иначе лог исполнения превращается в тыкву.

Важно: для того чтоб не возникло путаницы и однозначно было видно как и откуда идет сборка, надо установить версию проекта в что-нибудь абстрактное, например DEVELOPMENT-SNAPSHOT. Воспользоваться можно той же самой командой: version:set. Операция разовая, мы ведь больше не храним версию проекта в файле.

В результате изменений можно удалить конфигурацию maven-release-plugin и scm блока из pom файла.

» Из минусов:
Если у вас где либо используются SNAPSHOT версии, то может начаться путаница, теперь все SNAPSHOT версии выглядят одинаково. И, возможно, такой способ релизить проекты не для вас.

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

» Из плюсов:

  • Все требования удовлетворены, и даже больше!
  • версия хранится только в теге проекта
  • сборка новой и пересборка старой версии выполняется таким-же набором команд что и оригинальная версия
  • отпала необходимость прав на коммит в проект
  • набор инструментов остался тот-же
  • бонус: конфигурация проекта упростилась

Вот так, две строчки опять спасли мир.
На этом и все, спасибо за внимание!

Комментарии (16)


  1. vba
    26.09.2018 15:06
    +1

    Позвольте заметить, у вас в заголовке опечатка, там лишняя буква "Л" перед словом ад.


    1. osigida Автор
      26.09.2018 15:53

      Что верно то верно. :-D Подход maven к организации проекта привел к «ожирению» системы, переход на gradle позволяет писать меньше и косячить еще быстрее! Кмк будущее за разделением на небольшие утилиты, каждая из которых делает одну вещь и делает ее хорошо. А вместе организуется CI/CD. Подвижки есть в этом направлении, но замахнуться на священный maven, пока, не решился никто.


      1. vba
        26.09.2018 16:23

        и косячить еще быстрее!

        Если вы надумали удалить /etc из вашего gradle скрипта и по стечению обстоятельств у этого скрипта есть права для этого, то это откровенный поиск приключений на пятую точку опоры. Но даже этого можно избежать, следуя принципу доверяй да проверяй, на стороне CI, например не пропускать все что не является управлением зависимостями. Это кстати гораздо проще достигается в sbt


        но замахнуться на священный maven, пока, не решился никто.

        Не совсем понятно что тут имелось ввиду, maven просто погружается в забвение, где ему и самое место.


        1. osigida Автор
          26.09.2018 16:59

          Gradle развивается на тех-же принципах и подходах что и maven. В него пишут и тянут неимоверное количество плагинов, как результат, сборка занимает не пойми сколько, отчего упала непонятно, куда бежать — неясно (конечно, это со стороны моего опыта).
          Подход, когда все разделено и физически невозможно смешать, мне гораздо ближе: релиз разбивается на конечное число атомарных шагов, простых и понятных. Но, пока мы не там.


          1. imanushin
            26.09.2018 19:26

            это со стороны моего опыта

            К сожалению, это только со стороны вашего опыта. Например мы каких-то тормозов в работе gradle не наблюдали (т.е. компиляторы тратят время, upload тратит время, однако самого gradle при этом почти не видно). Здесь можно даже увидеть, что современный gradle может обгонять современный maven. Так что it depends.


            тянут неимоверное количество плагинов

            У нас их порядка пяти. Из них kotlin/spring boot, которые так и так много где будут.


            отчего упала непонятно

            https://docs.gradle.org/current/userguide/logging.html ?


            не пойми сколько

            IntelljJ Idea показывает, сколько времени работали таски. И плюс здесь есть рекомендации, если какие-то задачи работают медленно.


            1. osigida Автор
              26.09.2018 22:58

              А вот вы никогда не задумывались, почему мавен (якобы) медленнее? Может от того что многопоточность в нем по умолчанию выключена? Кмк, я видел разоблачающую статью показывающую, что разница далеко не на порядки.

              Инструмент, он невиноват, когда его неправильно используют. 100% тормозов в мавене, да и грейдле, были вызваны кривыми руками. И там и там можно такого натворить, что е-ге-гей!


        1. sshikov
          27.09.2018 19:21

          >maven просто погружается в забвение

          Apache Hadoop — 144 участника на github, Hive — 168. Spark — 1285, Hbase — 196. Это только четыре компонента из большой экосистемы Hadoop. Народу работает более чем много для типичного проекта (хотя только spark сопоставим скажем со spring по числу людей). Все собираются maven. Даже написанный на скале Spark.

          Так где можно глянуть на пару ваших проектов размером с Apache Hadoop?


          1. vba
            27.09.2018 19:34
            +1

            Бизнес модель Spark ничем не отличается от любого ос проекта, написан он может быть на чем угодно, а работает из java и scala, к сожалению кто говорит java подразумевает maven на уровне предприятия.


            Народу работает более чем много для типичного проекта (хотя только spark сопоставим скажем со spring по числу людей).

            Количество не означает качесто.


            Так где можно глянуть на пару ваших проектов размером с Apache Hadoop?

            Все проекты в мире под андроид собираются из gradle и что, о чем это говорит? Да ни очем, из раздела да мой папа знает каратэ, а мой айкидо, итд...


            1. sshikov
              27.09.2018 20:00

              >к сожалению кто говорит java подразумевает maven на уровне предприятия.
              Не испытываю никакого сожаления. И еще человек 30 разработчиков вокруг. Что мы все делаем не так?

              >Количество не означает качество.
              Количество участников означает сложность проекта. Практически однозначно. Применительно к перечисленным проектам я могу спокойно утверждать, что Spark прилично сложнее, чем Spring Framework, потому что достаточно хорошо знаю оба. А хадуп скорее всего на порядок сложнее.

              А уж коли вы собрались выступить за качество — так вы должны показать, что скажем Spark чем-то хуже Spring. А пока вы это не показали — какой может быть разговор про качество?

              >Все проекты в мире под андроид собираются из gradle и что, о чем это говорит?
              Это говорит очень о многом. В первую очередь — об их масштабе.

              Упростим задачу. Покажите мне хотя бы один проект под андроид, в котором 1285 человек участников? Я вот априори более чем уверен, что такого не существует.

              Кстати, если бы вы сразу сказали, что в мире мобильных приложений мавен (и далее по тексту) — я бы наверное и спорить не стал. Мне не нравятся только обобщения вида «все проекты в мире», по одной простой причине: я вот лет 10 минимум уже работаю на разные крупные банки, и совершено точно знаю, что работая внутри, никогда не видел и не слышал о большей части проектов, которые там делаются. В лучшем случае — процентов 10 может быть видел. То есть, я бы даже про свою компанию начиная с определенного ее размера так бы не стал обобщать. А уж за весь мир — и подавно.


              1. vba
                27.09.2018 20:56

                Что мы все делаем не так?

                Откуда мне знать, я не врач и не психолог


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

                Причем здесь мейвен? Вам же сказали что его выбрали лишь бы угодить интерпрайзу.


                А уж коли вы собрались выступить за качество — так вы должны показать, что скажем Spark чем-то хуже Spring.

                Нет тут речь идет о древне русской мудрости, которая гласит что количество не означает качество, только и всего.


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

                Покажите мне хотя бы один проект под андроид, в котором 1285 человек участников? Я вот априори более чем уверен, что такого не существует.

                Ну кто его знает что там в закромах проприетарных проектов творится, опять же см про качесто и кол-во.


                я вот лет 10 минимум уже работаю на разные крупные банки

                Искрене собалезную, я как-то в прошлом работал на JPMC, меня хватило на 2 мес их дурдома, больше с банками дела не имею.


        1. a_e_tsvetkov
          28.09.2018 09:45
          +1

          А что конкретно не так с мавеном?

          На данный момент с ним у меня было меньше всего проблем. Хотя это скорее всего объясняется тем что с ним у меня больше всего опыта.


  1. nicholas_k
    26.09.2018 15:50

    А как быть в случае, когда очень надо использовать зависимость от еще не зарелизенного проекта?


    1. osigida Автор
      26.09.2018 16:05

      Вы, либо выбрали наркотики микро-сервисы и собираете проекты, потому что вам нужно, и тогда проблема решается сама собой (на локальной машине, можно собрать локально snapshot версию и подключить, временно, ее). Либо, вы столкнулись с одним из недостатков и такой способ сборки вам не подходит.

      Как еще один вариант: собирать snapshot и ставить версию = хешу, в случае когда тег не определен.
      В таком варианте есть свои плюсы и минусы: к плюсом можно отнести однозначное понимание что попало в сборку, разночтений быть не может; к минусам, неочевидно куда мы движемся меняя одну страшную строчку на другую, семантическая версионность говорит нам идем ли мы вперед (версия стала больше) или назад (меньше).


  1. sshikov
    26.09.2018 22:08

    Если вы в 2018 все еще пользовались релиз плагином, тем самым, из прошлого, то вообще говоря, это ваши проблемы из-за недостаточного любопытства :) Решения есть, давно, их много, хороших и разных, под разные потребности.

    Ну вот например, axelfontaine.com/blog/final-nail.html

    Первый пост из этой серии был написан еще в 2011 году. А в последнем от 2016 года на первый взгляд описано ровно такое же решение, как и у вас.


    1. osigida Автор
      26.09.2018 23:04

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


      1. sshikov
        27.09.2018 19:07

        Ну, не совсем те же. Релиз плагин (оригинальный) делал намного больше, в том числе лишнего.