2016-07-02 1 views
5

Вопрос: Как вы обрабатываете ветви функций для нескольких проектов проекта maven?Избежать столкновения версии хранилища maven при использовании ветвей функций

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

У нас есть сценарий для изменения родительской версии в дочерних версиях и версиях в корневом помпе. Хотя это разделяет ветви в пространстве maven, это приводит к дополнительной работе при слиянии.

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

Снова: как справиться с проблемой нескольких ветвей и maven?

+0

* У нас есть скрипт для изменения родительской версии в дочерних помах и версии в корне pom * Почему бы не использовать цель ['maven-release-plugin: branch'] (http://maven.apache.org/maven-release/maven-release-plugin/branch-mojo.html)? Она создаст ветвь автоматически и будет обновлять версию, которую вы можете установить на 'xx-my-branch' или что-то подобное. – Tunaki

+0

Спасибо @Tunaki. Слияние все еще проблема, поскольку помы были изменены? –

+0

Да, с другой версией это будет быть боль ... см. также http://stackoverflow.com/questions/3555160/merging-changes-from-a-maven-relase-branch-yields-conflicts-due-to-changed-versi (или http://stackoverflow.com/questions/12197191/git-merge-conflict-onl y-on-version-tag-in-pom-xml) – Tunaki

ответ

3

Как насчет следующего подхода:

  • Используйте buildnumber-maven-plugin для извлечения информации из мерзавца и заполнить специфические свойства Maven (мы заинтересованы именно в scmBranch собственности (то есть, текущая ветвь мерзавец)
  • Используйте build-helper-maven-plugin, чтобы проверить, являются ли мы в эту ветку или нет (через regex, за исключением хорошо известные ветви, как master, develop и т.д.) и заполнения (или нет) новое свойство Maven, скажем branch.classifier
  • Используйте maven-jar-plugin для установки классификатора на сгенерированных артефактах на основе того, что было установлено предыдущим шагом, то есть с использованием нового свойства branch.classifier: если оно пустое, классификатор не будет применяться (поведение по умолчанию применяется к ветви develop, для пример); в противном случае классификатор, названный в честь текущей ветви, будет динамически применяться.

Вот минимальный пример:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>buildnumber-maven-plugin</artifactId> 
      <version>1.4</version> 
      <executions> 
       <execution> 
        <phase>validate</phase> 
        <goals> 
         <goal>create</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>build-helper-maven-plugin</artifactId> 
      <version>1.10</version> 
      <executions> 
       <execution> 
        <id>regex-property</id> 
        <goals> 
         <goal>regex-property</goal> 
        </goals> 
        <configuration> 
         <name>branch.classifier</name> 
         <value>${scmBranch}</value> 
         <regex>(^develop)|(^master)|(^release.*)</regex> 
         <replacement></replacement> 
         <failIfNoMatch>false</failIfNoMatch> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
     <plugin> 
      <artifactId>maven-jar-plugin</artifactId> 
      <version>3.0.2</version> 
      <configuration> 
       <classifier>${branch.classifier}</classifier> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

Сниппает ниже, в основном наполнении scmBranch свойства динамически, то установке branch.classifier в значение только в том случае, отличную develop, master или release*, а затем установить его как классификатор.

Основные преимущества этого подхода:

  • будет применяться Нет POM изменения, следовательно, никаких проблем объединяющиеся на всех
  • Нет столкновений на Nexus, работающих на одной и той же версии проекта, но по разным отраслям : классифицированный артефакт будет иметь разные Maven coordinates, то есть GAV (groupId, artifactId, version) становится уникальным GAVC (+ классификатор)
  • Это фактически значимое использование атрибута артефакта classifier:

    Классификатор позволяет различать артефакты, созданные из одного и того же ПОМ, но отличающиеся по содержанию.

  • Сформированный артефакт будет динамически отличаться в Nexus, в зависимости от его исходной ветви, следовательно, не имея неявную прослеживаемость: никакого вмешательства со стороны разработчиков (нет ошибки склонной, неявная конвенции), без вмешательства с CI работы (проще техническое обслуживание), полностью прозрачна
  • Использование классификаторов, будет легче использовать артефакты, сгенерированные в отрасли как Maven зависимости (например, в случае библиотечного проекта): Я хочу использовать зависимость в настоящее время в стадии разработки по отрасли ххх

Примеры
Таким образом, вы имели бы следующие артефакты генерироваться:

  • При работе на develop: например, project-1.0.0-SNAPSHOT.jar (пустой классификатор, следовательно, не применяется, как обрабатывается регулярным выражением)
  • При работе с featureA: например. project-1.0.0-SNAPSHOT-featureA.jar
  • При работе с hotfix-JIRA123: например. project-1.0.0-hotfix-JIRA123.jar
  • При работе с release-sprint42: это зависит от вас, я добавил этот случай, чтобы не применять название ветки, просто потому, что в этих случаях я предпочитаю специально назначить специальный классификатор RC<number> для кандидатов на выпуск, но это вопрос условностей/вкуса/привычек, вы можете применить тот же подход и к этой ветке, если на Nexus не будет создано никаких столкновений. Также обратите внимание: при использовании интеграции JIRA/Stash/Git название ветки выпуска обычно имеет значение release/v0.1.0, где символ / может вызывать проблемы в некоторой операционной системе (все же что-то исправляемое с помощью дальнейшего регулярного выражения, если это действительно необходимо).
  • При работе на master: эй, никто не должен работать на master :) случая есть так же, как двойная проверка, но это на самом деле не требуется

Предупреждение об этом подходе:

  • Как поясняется в нижеследующем обсуждении с помощью комментариев, если заинтересованный проект Maven уже использует классификаторы и даже больше через зависимости между модулями (например, зависимости от классов области проверки от другой модуль), то этот подход должен быть тщательно проверен, так как он может иметь некоторые недостатки.
  • Публикация файлов <artifactId>.pom, содержащих классификатор ветвей, может привести к конфликтам с строкой mainline (т. перекрывая его)
+0

спасибо. это очень пятно. Я буду экспериментировать с небольшим проектом и посмотреть, что я могу сделать. Сложные биты будут секцией tcho eclipse RCP моей сборки, но я, вероятно, могу использовать плагин ресурсов для обработки тега для замены свойств в этих файлах. –

+0

@PeterKahn FYI: в компании, где я работаю, мы фактически используем ее прямо сейчас в нашем конвейере поставки и отлично работаем, никаких конфликтов в Nexus и разработчики также могут импортировать в качестве зависимостей maven артефакты, генерируемые определенной ветвью (редкий случай, но теперь возможно) без необходимости изменения версии проекта и проблем с его объединением. –

+0

Что относительно источников, тестовых источников, javadoc и других классификаторов, которые обычно используют определенное имя? Продолжают ли они работать в командной строке и в среде IDE? Я ожидаю, что источники и тестовые источники не будут работать и будут тянуть/использовать значение по умолчанию для версии, а не для конкретной ветви. –

0

Это не работает Результатов в предупреждениях по всей ошибке сборки и ОЙ при запуске из верхнего родителя.

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

Поскольку maven может использовать переменные среды для свойств, и мы уже инициализируем среду сборки сценарием (у нас также есть скрипты git hook, которые могут устанавливать переменные среды из имен ветвей), мы можем использовать env для управления версией.

<groupID>my.project</groupId> 
<artifactID>database</artifactId> 
<version>1.2.0${env.BRANCHMODIFIER}-SNAPSHOT</version> 

Если на развитие наших сценариев набор BRANCHMODIFIER к ""
Если на функции/JIRA-30495 наши сценарии набор BRANCHMODIFIER в»0,30495"

Как это работает в затмении или Intellij? Пока не знаю.

+0

A_Di-Matteo наше комплексное использование классификаторов быстро стало беспорядком. Использование #nexus #staging приводит к локальным репозиториям с тем, что похоже на разработку артефакта, но которые не были. Добавление модификатора artifactId было также беспорядочным. Манипулирующая версия кажется самым чистым подходом. –

+0

Этот вид работ, но приводит к предупреждению о проблеме кучи при запуске с вершины дерева. –

+0

Возможно, этот подход может возникнуть при выполнении сборки с локальных машин, не так ли? –

1

Мы используем аналогичную технику, как Питер Кан, изменяя версию ветки перед зданием. У нас есть три шага в нашем "Pre шагов":

  1. Execute оболочка: echo VERSION=$(echo ${GIT_BRANCH} | sed 's_^.*\/__') > env.properties
  2. INJECT переменных сред: env.properties
  3. Invoke верхних цели уровня Maven: versions:set -DgenerateBackupPoms=false -DnewVersion=${VERSION}-SNAPSHOT

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

Причина, по которой мы не изменяем версию в файлах pom.xml в ветке напрямую, действительно сливается. С SVN это было возможно (слияние с --accept-mine-conflict. С GIT этого больше не существует, поэтому мы прекратили изменять версии и создали эти этапы предварительной сборки.

Смежные вопросы