39

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

В настоящее время мы не увеличиваем наши номера версий для нашего проекта, и все сидит в версии 0.0.1-SNAPSHOT уже более года. Мне интересно, что такое способ Maven для непрерывной доставки веб-приложений. Кажется, слишком сложно поднять номер версии на каждом коммите, и никогда не натыкаться на номер версии, как мы сейчас делаем, также кажется неправильным.

Какова рекомендуемая практика для использования в этом типе использования Maven?

Проблема на самом деле два раза один:

  • Выросшие проект номер версии в индивидуальном pom.xml файле (и там может быть много).
  • Обновление номера версии во всех зависимых компонентах для использования последних друг от друга.

ответ

32

Я рекомендую следующую презентацию, обсуждает практические реалии doi нг непрерывной поставки с Maven:

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

+0

Я отмечаю это как правильный ответ, потому что видео You Tube было отличным ответом на этот вопрос. Однако мне пришлось несколько раз остановиться и перемотать несколько раз, чтобы получить некоторые более тонкие точки. поставили сводку процесса, рекомендованного в видео, в моем собственном ответе. – ams

+1

Видео довольно хорошее и поможет вам загрузиться. @ 23m35s в видео, я бы сказал, что Maven должен выполнить большую часть краткосрочной проверки здравомыслия, например, модульные тесты, проверки покрытия, интеграционные тесты и т. Д. ... однако непрерывная доставка не прекращается. Для крупных организаций типа SOA разбиение вашего трубопровода на незаметные фазы на самом деле является очень хорошей практикой, например, функциональные тесты с издеваемыми конечными точками, тесты производительности, большие интеграционные тесты, тестирование UAT, проверка соответствия, анализ статического кода, обзор безопасности и т. Д. – user924272

+0

Отличное видео. Моя единственная забота - это то, что люди делают со всеми «кандидатами на выпуск» в репо-релизе, которые официально не выпускаются? У нас есть график очистки для наших SNAPSHOT, однако выпуски артефактов хранятся навсегда. Я вижу это, используя много дискового пространства, на стороне хранилища Maven. – Patrick

8

Есть некоторые большие дискуссии и предложения, как бороться с номером Maven версии и непрерывной доставкой (CD) (я добавлю их после моей части ответа).

Итак, сначала мое мнение о версиях SNAPSHOT. В maven SNAPSHOT показывает, что это в настоящее время разрабатывается до конкретной версии до суффикса SNAPSHOT. Из-за этого такие инструменты, как Nexus или плагин maven-release, имеют специальную обработку для SNAPSHOTS. Для Nexus они хранятся в отдельном репозитории, и ему разрешено обновлять несколько артефактов с той же версией выпуска SNAPSHOT. Таким образом, SNAPSHOT может измениться, если вы не знаете об этом (потому что вы никогда не увеличиваете число в своем помпе). Из-за этого я не рекомендую использовать зависимости SNAPSHOT в проекте, особенно в мире компакт-дисков, так как сборка не является надежной.

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

Другая проблема SNAPSHOT для меня - это то, что на самом деле не является прослеживаемым или воспроизводимым. Когда я вижу версию 0.0.1-SNAPSHOT в производстве, мне нужно сделать некоторые поиски, чтобы узнать, когда она была создана, из какой версии она была создана. Когда я нахожу выпуски этого программного обеспечения в файловой системе, мне нужно посмотреть на pom.properties или файл MANIFEST, чтобы узнать, старый ли это мусор или, может быть, самая последняя версия.

Чтобы избежать ручного изменения номера версии (особенно при создании нескольких сборок в день), пусть сервер сборки изменит номер для вас. Таким образом, для развития я бы с версией

<major>.<minor>-SNAPSHOT 

но при создании новой версии Билда сервер может заменить SNAPSHOT с чем-то более уникальным и отслеживаемым.

Например, один из этого:

<major>.<minor>-b<buildNumber> 
<major>.<minor>-r<scmNumber> 

Так что основной и второстепенный номер может быть использован для маркетинговых проблем, или просто показать, что новая большая веха будет достигнута и может быть изменена вручную когда вы хотите его , И buildNumber (номер с вашего сервера непрерывной интеграции) или scmNumber (Revision SUbversion или GIT) делают каждую версию уникальной и прослеживаемой. При использовании ревизии buildNumber или Subversion версии проекта даже сортируются (не с номерами GIT). С buildNumber или scmNumber также легко увидеть, какие изменения в этой версии.

Другим примером является версионирование StackOverflow, которые используют

<year>.<month>.<day>.<buildNumber> 

И здесь недостающие звенья:

+1

Первая ссылка Вершина в трубопроводе сломана –

+0

Кажется, что ее удаляют. Я не нашел ссылку на замещение или содержимое в кэше веб-сайтов :( – mszalbach

+0

Этот ответ больше относится к формату имени версии и его значению. Существует уже достаточно формализованная спецификация [называемая «семантическая версия»] (http: // semver .org /) - просто добавьте 'SNAPSHOT' в значение« еще не выпущенная »версия. И формат версии ** не ** действительно проблема в Maven и там ** [ограничения] (http: // goo.gl/JW9PS7)**. Проблема заключается в том, чтобы сделать этот процесс _effortless_ и желательно _automatic_ (по крайней мере до выпуска с семантикой = ручная версия, такая как 'XYZ'). Обновление разделов нескольких взаимозависимых файлов' pom.xml' * * is ** проблема. – uvsmtid

29

Это мое резюме, основанное на видео, связанном с ответом Марка О'Коннора.

  • Для решения требуется DVCS, такой как git и сервер CI, как Jenkins.
  • Не используйте сборки моментальных снимков в конвейере непрерывной доставки и не используйте плагин релиза maven.
  • Варианты снимков, такие как 1.0-SNAPSHOT, превращаются в реальные версии, такие как 1.0.buildNumber, где buildNumber - номер задания Дженкинса.
  • шаги

Алгоритм:

  1. Дженкинс клоны мерзавец репо с исходным кодом, и сказать, что исходный код имеет версию 1.0-SNAPSHOT
  2. Дженкинс создает GIT ветвь под названием 1.0.JENKINS-JOB-NUMBER поэтому версия снимок превращается в реальная версия 1.0.124
  3. Jenkins вызывает плагин версий maven для изменения номера версии в файлах pom.xml с 1.0-SNAPSHOT по 1.0.JENKINS-JOB-NUMBER
  4. Дженкинс вызывает mvn install
  5. Если mvn install имеет успех, то Дженкинс будет совершать ветвь 1.0.JENKINS-JOB-NUMBER и реальная версия, не моментальный снимок создается с соответствующим тегом в мерзавцем, чтобы воспроизвести позже. Если mvn install терпит неудачу, тогда Дженкинс просто удалит вновь созданную ветку и завершит сборку.

Я настоятельно рекомендую видео, связанное с ответом Марка.

+1

Как вы обрабатываете проект с несколькими модулями maven? Вы просто отпустите весь проект и всех детей с одинаковой версией? Если у меня есть проект A в зависимости от B, и я делаю фиксацию в проекте B, вышеуказанные шаги запускаются для B, который затем запускает вышеуказанные шаги для проекта A, но тогда как A знает версию B? – dukethrash

+1

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

+3

В моем случае это даже не мультимодуль.У меня есть проект A, который зависит от проекта B. Project B имеет свою собственную работу Jenkins и может иметь фиксацию, которая генерирует выпущенный артефакт. Затем проект A должен ссылаться на выпущенный артефакт в помпе. Предлагаете ли вы просто вручную обновить проект А, когда сборка проекта Б преуспеет, и артефакт доступен? Проект B - это основной проект, а Project A - это веб-приложение, поэтому они связаны друг с другом, но имеют большие накладные расходы при обновлении зависимостей Project A от Project B, особенно при разработке в среде IDE, которая рассматривает изменения с зависимостями SNAPSHOT. – dukethrash

5

НЕ ДЕЛАЙТЕ ЭТО!

<Major>.<minor>-<build> 

укусит вас в зад, потому что Maven лечит что-либо после дефиса лексические. Это означает, что версия 1 будет лексически выше 10.

Это плохо, как если бы вы просили последнюю версию чего-то в maven, то победа выше.

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

ДЕЛАТЬ ЭТО!

<Major>.<minor>.<build> 

Это нормально иметь версии SNAPSHOT локально, но и как часть сборки, то лучше использовать

mvn versions:set -DnewVersion=${major}.${minor}.${build.number} 

Есть способы, чтобы получить главную/второстепенную версию с ПОМ, например, с помощью help: оцените и перетащите переменную окружения перед вызовом версий: set. Это грязно, но я действительно почесал голову (и другие в моей команде), чтобы сделать ее проще, и (в то время) Maven был недостаточно зрелым, чтобы справиться с этим. Я считаю, что Maven 2.3.1 может что-то сделать, помогая этому, поэтому эта информация больше не может быть релевантной.

Это нормально для кучки разработчиков, выпущенных на той же версии major.minor, но всегда хорошо помнить, что незначительные изменения не нарушаются, а основные изменения в версии имеют некоторые нарушения API-интерфейса или устаревание функциональности/поведение.

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

+4

Подразумевается http://mojo.codehaus.org/versions-maven-plugin/version-rules.html и, согласно моим собственным тестам, это неверно. Стандартная версия версии Maven по умолчанию - '. . - '(с большей частью необязательно). Пока часть после тире является числовой, она не будет сравниваться лексически. Я тестировал это с помощью 'mvn версий: use-latest-versions' и т. Д. '1.4-11' корректно определяется как более новый, чем' 1.4-2'. –

+0

Какую версию Maven вы проверили? Кроме того, вы пытались также установить версию 1.4.21, а затем играть, чтобы узнать, как работает разрешение диапазона версии Maven? Было бы интересно узнать о ваших выводах, поскольку у меня, безусловно, есть эта проблема с 2.2.1, и я проверил это, посмотрев исходный код Maven. Кроме того, я не думаю, что эти правила действительно применимы ни к чему, кроме плагина версий, и я говорю о разрешении зависимостей. – user924272

+0

Следуйте https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN401 @philipp правильно. Это безопасно использовать инкрементные числа в $ {major}. $ {Minor}. $ {Build.number} и $ {major}. $ {Minor}. $ {Build.number} - $ {patchNumber}, но не $ {major}. $ {minor}. $ {build.number}. $ {patchNumber} – iMysak

1

В моей работе для веб-приложений, в настоящее время мы используем этот шаблон управления версиями:

<jenkins build num>-<git-short-hash>

Пример: 247-262e37b9.

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

В Maven 3.2.1+ они, наконец, убили предупреждения об использовании $ {property} в качестве версии, так что это действительно упростило их создание. Просто измените все ваши пемы на использование <version>${revision}</version> и постройте с помощью -Drevision=whatever. Единственная проблема в том, что в ваших выпущенных версиях версия останется в ${revision} в фактическом файле pom, который может вызвать всевозможные странные проблемы. Чтобы решить эту проблему, я написал простой плагин maven (https://github.com/jeffskj/cd-versions-maven-plugin), который выполняет замену переменных в файле.

+0

Плагин кажется решением для обновления версий самих файлов 'pom.xml'. Однако следующей проблемой является обновление версий в разделе зависимостей всех зависимых компонентов, участвующих в выпуске, так что они фактически используют последние друг от друга. У меня есть ** [эта проблема, когда автоматическое обновление ненадежно] (http://stackoverflow.com/q/31579730/441652) ** в сборке с несколькими модулями/реакторами (которые обновляют внешние и не только внутренние компоненты). Итак, краткосрочное решение остаться в «SHAPSHOT». ** Прокомментировать, как вы решили эту проблему? ** – uvsmtid

+0

В основном вы не должны использовать версии снимков. Обновляйте версии зависимостей перед созданием. –

+0

Храните все модули в той же версии. В корневом модуле dependencyManagement раздел устанавливает модули в '$ {project.version}'. Тогда простые 'mvn версии: set -DnewVersion = whatever' будут делать трюк и менять версии в порядке реактора, включая родителей и т. Д. –

6

Начиная с Maven 3.2.1 непрерывной доставки дружественные версии поддерживаются из коробки: https://issues.apache.org/jira/browse/MNG-5576 Вы можете использовать 3 предопределенные переменные в версии:

${changelist} 
${revision} 
${sha1} 

Так что вы в основном делают это:

  1. Установите версию, например, 1.0.0-${revision}. (Вы можете использовать mvn versions:set, чтобы сделать это быстро и правильно в многомодульном проекте.)
  2. Поместить недвижимость <revision>SNAPSHOT</revision> для местной разработки.
  3. В вашей среде CI запустите mvn clean install -Drevision=${BUILD_NUMBER} или что-то в этом роде или даже mvn clean verify -Drevision=${BUILD_NUMBER}.

Вы можете использовать, например, https://wiki.jenkins-ci.org/display/JENKINS/Version+Number+Plugin, чтобы генерировать интересные номера строек.

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