Maven, вероятно, единственный универсальный инструмент сборки, который я когда-либо действительно ценится . Я, вероятно, придет к сделать
в конце концов и цементный статус статус старого до-до того времени * Nix Crola, но у меня еще не было причины действительно копаться Так что Maven это. И я вернулся в магазин в основном-Java, поэтому давайте повеселимся!
Цель этой недели: автоматизация выбросов из нашего экземпляра Circleci. Звучит достаточно просто, верно? Поднять версию, отрежьте тег, опубликуйте. Как трудно это может быть?
Ну, во-первых, мы используем Git-flow или, по крайней мере, мы сохраняем Мастер
Для выпусков и отработка отдельных проверить
ветвь. Бюджетный поток Git, если вы будете. Это одно осложнение, поскольку релиз должен быть помечен на Мастер
Но проверить
Также необходимо обновить, поэтому два не расходятся.
Если вы знакомы с Maven, вы, возможно, уже угадали второе осложнение. Это слоется. Maven не работает в приятных, простых СЕМВЕР : Maven принимает несколько различных схем версий и имеет специальную Снимок
Квалификатор для не высвобождения. Если вы работаете в направлении Release 1.0, ваш номер версии 1,0 — снимок. После того, как вы сократите выпуск, вы возобновите развитие с 1.1-Snapshot (или 2.0-Snapshot, если он действительно нуждается в переделке уже). И так далее. Это не имел в виду быть автоматическим, потому что релизы являются большое дело В мире Maven, и вы должны иметь план для того, что вы собираетесь делать дальше, а не реагируете на то, не закреплены ли вы ошибки, представленные функции или сломали совместимость. И, честно говоря, есть некоторые убедительные аргументы для этого таким образом.
Я не собираюсь уходить в них, потому что я сам подойдет одна половина команды программного обеспечения, и они менее применимы, работая над запатентованными материалами в этом масштабе. Так что давайте перейдем к автоматизации!
Рабочий процесс
Мы используем круг V2 и его функцию рабочего процесса для организации сборки. Каждая ветвь построен: проверить
и Мастер
Развернуты для артефактирования, а Выпуск
Запускает свою собственную работу, которая последняя — это линхпин всей структуры.
workflows: version: 2 build-and-deploy: jobs: - build - deploy: requires: - build filters: branches: only: /^(master|verify)$/ - release: requires: - build filters: branches: only: /^release$/
Просто построить
Я буду честен, я скопировал и вставил большую часть этого определения работы прямо из документов:
steps: - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "pom.xml" }} # fallback to using the latest cache if no exact match is found - v1-dependencies- - run: mvn clean install - save_cache: paths: - ~/.m2 key: v1-dependencies-{{ checksum "pom.xml" }} - persist_to_workspace: <<: *source
Мы кэшируем наши зависимости, потому что это то, как это делает; MVN чистая установка
Вероятно, наполнен (нам, вероятно, не нужно беспокоиться с установкой зависимости от локального кэша Maven), но он создает и запускает наши тесты и генерирует артефакт. Единственная действительно интересная часть вот в том, что мы сохраняем важные файлы на рабочую область, чтобы мы могли восстановить его позже — * Источник
Относится к другому блоку YAML с root
Строка и список путь
.
А также Развертывать
steps: - attach_workspace: at: . - run: name: Deploy to Artifactory command: mvn deploy
Вот где мы используем это рабочее пространство. Всякий раз, когда эта работа работает, она будет присоединиться к структуре файла, которую мы сохранили с работы по сборке. MVN Развертывание
Все еще управляет всеми промежуточными этапами жизненного цикла, потому что это то, как Maven Rolls, но нам не нужно снова проверить код.
У нас есть наши помпы, настроенные с Artifactory-Maven-плагин Так что все, что мы должны сделать, чтобы опубликовать, это выпуск MVN Развертывание
. Это делает это просто, по крайней мере; Есть артефактория CLI, если вы предпочитаете, но всю сделку Maven управляется всем, насколько я понимаю, мы должны позволить этому.
Есть только одна кусочка, хотя: как мы на самом деле выпустим новый Версия артефакта и начнутся на начало следующего?
Триггер выпуска
Одним из представлений о потере GIT — это то, что когда вы готовитесь к выпуску, вы обрезаете новую ветвь, которая содержит только работу по этому выпуску. Это отлично, если вы работаете над несколькими версиями кода одновременно, и выпуски могут принять некоторое время, поэтому вы можете сделать Cherry-pick avfix из текущей разработки в устаревшую отрывную ветку, чтобы гарантировать, что она не влияет на подмножество ваших пользователей. Поскольку мы не продуктивная компания, нам не нужно беспокоиться об этом. Мы всегда работаем над следующим выпуском, и он падает, когда он готов к упасть.
Это будет сложно. Вот …| Выпуск Построить шаги в полном объеме:
steps: - checkout - run: name: Cut new release command: | # assemble current and new version numbers OLD_VERSION=$(mvn -s .circleci/settings.xml -q \ -Dexec.executable="echo" -Dexec.args='${project.version}' \ --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) NEW_VERSION="${OLD_VERSION/-SNAPSHOT/}" echo "Releasing $OLD_VERSION as $NEW_VERSION" # ensure dependencies use release versions mvn -s .circleci/settings.xml versions:use-releases # write release version to POM mvn -s .circleci/settings.xml versions:set -DnewVersion="$NEW_VERSION" # setup git git config user.name "Release Script" git config user.email "builds@understoryweather.com" # commit and tag git add pom.xml git commit -m "release: $NEW_VERSION" git tag "$NEW_VERSION" # land on master and publish git checkout master git merge --no-edit release git push origin master --tags # increment minor version number MAJ_VERSION=$(echo "$NEW_VERSION" | cut -d '.' -f 1) MIN_VERSION=$(echo "$NEW_VERSION" | cut -d '.' -f 2) NEW_MINOR=$(($MIN_VERSION + 1)) DEV_VERSION="$MAJ_VERSION.$NEW_MINOR-SNAPSHOT" # ready development branch git checkout verify git merge --no-edit release mvn -s .circleci/settings.xml versions:set -DnewVersion="$DEV_VERSION" git add pom.xml git commit -m "ready for development: $DEV_VERSION" git push origin verify # clean up release branch git push origin :release
Это не грязный , но это … много скрипта Bash. Но, как и любая достаточно сложная задача базы данных, включает в себя запись SQL, любая достаточно сложная задача OPS включает в себя Bash. Давайте сломаемся:
Получение номеров версий
# assemble current and new version numbers OLD_VERSION=$(mvn -s .circleci/settings.xml -q \ -Dexec.executable="echo" -Dexec.args='${project.version}' \ --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) NEW_VERSION="${OLD_VERSION/-SNAPSHOT/}" echo "Releasing $OLD_VERSION as $NEW_VERSION"
Обратите внимание на -scircleci/settings.xml
: Поскольку кружок просто спиннирует основное изображение OpenJDK, у нас есть settings.xml
проверено в контроль источника. Учетные данные интерполированы через переменные среды, но это все еще не большой ; В какой-то момент я захочу вернуться и создать пользовательский документ Docker, чтобы централизовать нашу конфигурацию.
Maven хранит номера версий в POM. Мы могли бы вытащить их с XPath, но поскольку это Maven, для этого есть плагин. Old_Version
это текущее значение; Так как мы всегда выпускаем из проверить
Филиал, это гарантированно является версией снимков, и нам нужно раздеть эту квалификацию, чтобы получить New_version
для выпуска.
Обновлять версии
# ensure dependencies use release versions mvn -s .circleci/settings.xml versions:use-releases # write release version to POM mvn -s .circleci/settings.xml versions:set -DnewVersion="$NEW_VERSION"
У нас нет тонны библиотек Java, но достаточно, чтобы управление выпуском — это (очевидно). Первое утверждение здесь гарантирует, что когда мы выпустим, мы не в зависимости от версии снимки другого из наших библиотек. Второе на самом деле на самом деле устанавливает поле версии в POM к версии выпуска, которую мы создали только сейчас.
Вы можете спросить: почему я не просто псевдоним МВН
к mvn -s .circleci/settings.xml
? И ответ: я сделал, и потратил пол дня, пытаясь выяснить, почему это не сработало. Я не знаю, является ли это конкретное изображение или круг в целом или что, но псевдоним просто игнорируются.
Выпускать!
# setup git git config user.name "Release Script" git config user.email "builds@understoryweather.com" # commit and tag git add pom.xml git commit -m "release: $NEW_VERSION" git tag "$NEW_VERSION" # land on master and publish git checkout master git merge --no-edit release git push origin master --tags
Поскольку мы собираемся совершать код кода, нам нужно сделать немного больше GIT конфигурацию, чтобы правильно приписать коммиты. Это другой элемент, который я мог бы упростить с помощью пользовательского изображения сборки позже.
Далее мы совершаем обновленный POM и создать тег. Когда мы объединяемся (с --no - редактировать
поскольку скрипт не может изменить сообщение COMMING), релиз-коммит и тег приземляется на Мастер
ветвь. Тогда это просто вопрос толкания в начало происхождения.
Следующий…
Мы выпустили, но мы не совсем сделаны. Если мы оставили это здесь, следующий выпуск из проверить
Филиал вступит в конфликты слияния с Мастер
Имеет обновленную версию в POM. Чтобы предотвратить это, мы должны объединиться вернуться в проверять
. Предпочтительно с квалификатором версии снимка, потому что Maven.
# increment minor version number MAJ_VERSION=$(echo "$NEW_VERSION" | cut -d '.' -f 1) MIN_VERSION=$(echo "$NEW_VERSION" | cut -d '.' -f 2) NEW_MINOR=$(($MIN_VERSION + 1)) DEV_VERSION="$MAJ_VERSION.$NEW_MINOR-SNAPSHOT"
Я включал нас в двух частях номеров версий строго из удобства. Поскольку Maven ожидает, что вы узнаете, что вы работаете, собираясь от 1,0 до 1,1 гораздо более реалистично, чем пытаться выйти, вы смотрите на 1,0,1 или 1.1,0 следующий. Мы всегда можем обновить версию себя, если решать следующий релиз, на самом деле должен быть 2.0, но я пытаюсь минимизировать участие человека здесь.
# ready development branch git checkout verify git merge --no-edit release mvn -s .circleci/settings.xml versions:set -DnewVersion="$DEV_VERSION" git add pom.xml git commit -m "ready for development: $DEV_VERSION" git push origin verify
Слияние Выпуск
в проверить
Сохраняет нас от любых потенциальных конфликтов слияния вниз по линии, поскольку в том же выпуске Commite теперь существует как на Мастер
и в проверить
Отказ Сценарий затем добавляет второй фиксацию на проверить
С новой версией Snapshot и отправляет все это вплоть до начала.
# clean up release branch git push origin :release
Наконец: когда триггер уходит, он сбрасывает. Мы не хотим Выпуск
ветвь, чтобы повесить вокруг долгосрочного. Если бы мы сделали, нам пришлось бы оттолкнуть освобождение от начала, чтобы избежать слияния конфликтов в будущем, и делать это забивает бесконечный петля с момента выпускать
работа смотрит эту ветку. Таким образом, вместо этого мы просто удалите его от происхождения, так как все это нужно сделать, чтобы сделать.
Отключение его
git checkout -b release git push origin release
Это выплата. Всякий раз, когда мы готовы бросить новую версию, все, что должно произойти, это новая филиал имени Выпуск
Отказ Вы даже можете сделать это через пользовательский интерфейс GitHub, если вы настолько наполнены, в два клика и семь букв. Однажды Выпуск
Создается и удаляет себя, обычное сборка и развертывание рабочих мест захватывают как обновленные Мастер
и проверить
ветви. В течение нескольких минут у нас есть релиз и первый снимок на следующую посадку в артефактировании!
Оригинал: «https://dev.to/dmfay/automating-maven-releases-with-circleci-1gmc»