Подтвердить что ты не робот

Получение версии артефакта maven из ветки git

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

т.е. если мы находимся на главной ветки в git, мне нужно <version>master-...</version>, и если мы находимся в ветке bugfixX, мне нужен <version>bugfixX-....</version> для сгенерированного артефакта для этого pom.xml.

Ранее я обнаружил, что https://github.com/koraktor/mavanagaiata может предоставить хэш SHA-1 как свойство, и из документации видно, что он также может предоставить ветку, поэтому возможно, если бы это можно было запустить достаточно рано, мы могли бы установить свойство и просто положить <version>${our.version}</version> в pom. Если это возможно, я бы очень хотел увидеть рабочий pom.xml(и вознаградить за него 500 очков).

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

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

Любые предложения о том, как это решить?

4b9b3361

Ответ 1

Действительно, Maven не может изменить версию своего собственного проекта за один проход с другими целями. Кроме того, насколько я знаю, Maven не поддерживает произвольные свойства в теге <version>. Поэтому для выполнения цели требуется отдельное выполнение, которое изменит версию POM. Существуют различные плагины, которые могут это сделать - для этого случая можно использовать цель versions:set из плагина versions - http://mojo.codehaus.org/versions-maven-plugin/set-mojo.html

Итак, можно выполнить его, например, следующим образом:

mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$branch-SNAPSHOT

где переменная $branch должна содержать текущее имя ветки Git; его можно извлечь с помощью git rev-parse, например:

branch=$(git rev-parse --abbrev-ref HEAD)

Но все-таки нужно его каким-то образом выполнить. Вы можете делать это вручную, но это громоздко. Итак, я думаю, что самым надежным решением было бы приблизиться к этому со стороны Git. То есть - крюк Git. Вот полный крюк Git post-checkout, который выполнит задание (тот же код, что и выше, с некоторой фильтрацией для запуска крюка только тогда, когда ветвь проверена, а не только отдельные файлы):

#!/bin/bash

echo 'Will change the version in pom.xml files...'

# check if the checkout was to checkout a branch
if [ $3 != '1' ]
    then echo 'git checkout did not checkout a branch - quitting';exit
fi

# get current branch name
branch=$(git rev-parse --abbrev-ref HEAD)
version=$branch-SNAPSHOT

# run maven versions plugin to set new version
mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$version

echo 'Changed version in pom.xml files to $version'

Поместите это содержимое в файл PROJECTDIR\.git\hooks\post-checkout. Обратите внимание, что файл hook должен быть исполняемым для его запуска (chmod +x post-checkout).

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

Плюсы:

  • Robust
  • Не нужно ничего менять в файлах pom.xml, чтобы сделать эту работу.
  • Эта "функциональность" может быть отключена просто путем деактивации крюка (удалить или сделать не исполняемым) - снова, никаких изменений не требуется в pom.xml

Минусы:

  • Нельзя заставить других использовать крючок - он должен быть установлен вручную после клонирования репо (или вы можете предоставить script для установки крюка, если предполагается, что Git пользователи боятся касаться материала внутри .git).

UPDATE

В дальнейшем это более сложная версия hook, которая не только установит версию в название ветки, но также сохранит суффикс старой версии. Например, при старой версии master-1.0-SNAPSHOT переход на ветку feature1 изменит версию проекта на feature1-1.0-SNAPSHOT. Этот bash script страдает от нескольких проблем (требуется имя ветки без символа тире (-) в имени и принимает только версию корневого помпы), но может дать представление о том, как можно увеличить крючок: учитывая сочетание команд mvn и bash, вы можете извлекать и обновлять довольно много информации в POM.

#!/bin/bash

echo 'Will change the version in pom.xml files...'

# check if the checkout was to checkout a branch
if [ $3 != '1' ]
    then echo 'git checkout did not checkout a branch - quitting';exit
fi

# get current branch name
branch=$(git rev-parse --abbrev-ref HEAD)

# get current version of the top level pom
current_version=$(mvn help:evaluate -Dexpression=project.version | grep -v '\[.*')

# extract version suffix
suffix=$(echo $current_version | cut -d \- -f 2)

# build new version
version=$branch-$suffix

# run maven versions plugin to set new version
mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$version

echo 'Changed version in pom.xml files to $version'

Ответ 2

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

Проект, который делает это jgitver-maven-plugin (отказ от ответственности, я автор), он использует jgitver библиотека на основе jgit, чтобы получить версию проекта maven из git.

введите описание изображения здесь

Он очень прост в использовании в качестве расширения maven

...
  <build>
      <extensions>
          <extension>
              <groupId>fr.brouillard.oss</groupId>
              <artifactId>jgitver-maven-plugin</artifactId>
              <version>0.1.0</version>
          </extension>
      </extensions>
     ...
  </build>
...

Расширение также можно использовать в качестве расширения плагина, а затем позволяет больше конфигурации, например, если вы не хотите использовать SNAPSHOTS. См. Страницу для описания сценариев полного использования.

Существует также gradle плагин, который делает более или менее то же самое.


[править 1]: ответ на комментарий Торбьорна Равна Андерсена

Плагин не изменяет исходные файлы pom или файлы build.gradle.
Для плагина maven модификации выполняются как в памяти в Maven Object Model, так и записываются во временный файл в каталоге temp. Расчет основан только на метаданных git (теги, коммиты,...).
Эта не модификация позволяет не загрязнять историю git. Если вы удовлетворены фиксацией git, отметьте тегами git tag -a x.y.z и mvn deploy: все.
Версия в ваших файлах проекта теперь бесполезна и может быть установлена, например, на 0.

На сегодняшний день, и благодаря IDEA-155733, только последние версии EAP IntelliJ работают с плагином maven. Eclipse и Netbeans не имеют проблем.


Ответ 3

Отказ от ответственности: я автор

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

https://github.com/qoomon/maven-branch-versioning-extension

Пример формата версии enter image description here

Ответ 4

Если достаточно указать тег и версию git в имени файла артефакта, вы можете использовать maven-jgit-buildnumber-plugin:

<build>
  <finalName>${artifactId}-${git.buildnumber}</finalName>
  <plugins>
    <plugin>
      <groupId>ru.concerteza.buildnumber</groupId>
      <artifactId>maven-jgit-buildnumber-plugin</artifactId>
      <version>1.2.7</version>
      <executions>
        <execution>
          <id>git-buildnumber</id>
          <goals>
            <goal>extract-buildnumber</goal>
          </goals>
          <phase>prepare-package</phase>
        </execution>
      </executions>
    </plugin>
    <!-- more plugins -->
  </plugins>
</build>

Ответ 5

Вы пробовали использовать этот плагин?: https://github.com/ktoso/maven-git-commit-id-plugin. Вы можете настроить его для создания файла свойств со всей необходимой информацией о состоянии вашего репо:

  • филиал
  • описывают
  • commitId
  • buildUserName
  • buildUserEmail
  • buildTime
  • commitUserName
  • commitUserEmail
  • commitMessageShort
  • commitMessageFull
  • commitTime

Ответ 6

Вы проверили buildnumber-maven-plugin, который дает вам возможность использовать номер версии git. Но вам нужно было что-то другое. Кроме того, я бы предложил сделать что-то вроде:

   1.0.0-SNAPSHOT 
   1.0.0-SNAPSHOT 

beeing on master

на ветке вы можете просто изменить версию на

  1.0.0-BF-SNAPSHOT 

Ответ 7

Начиная с maven-3.5.0, в теге версии есть поддержка свойств $ {revision}, $ {sha1} и $ {changelist}. Эта функция может быть достаточной для ваших целей, если, например, вы хотите включить фирменное имя Git в версию для задания сборки CI. Посмотреть версии Maven CI Friendly

По сути, в вашем pom.xml замените фиксированную версию на:

<version>${revision}${changelist}</version>

Установите значения по умолчанию для ревизии и списка изменений в корневом .mvn/maven.config проекта, создав файл .mvn/maven.config содержащий:

-Drevision=1.2.3
-Dchangelist=-SNAPSHOT

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

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

BRANCHNAME=$(git rev-parse --abbrev-ref HEAD | sed -E -e '[email protected][^0-9A-Za-z.-][email protected]@g')
mvn clean install -Dchangelist="-${BRANCHNAME}"

(Вы можете предпочесть git symbolic-ref --short HEAD для извлечения ответвления, YMMV)

Ваш артефакт, созданный системой CI для feature/branchname ветки feature/branchname будет иметь суффикс версионной ветки, например:

yourproject-1.2.3-feature-branchname.jar

в то время как разработчики, которые не используют переопределения, все равно будут создавать его как:

yourproject-1.2.3-SNAPSHOT.jar