Статьи

Выпуск проекта Gradle в GitLab с Дженкинсом в Артефактори

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

Цель

Я собираюсь показать вам, как достичь двух следующих сценариев. Первый — как сделать обычную сборку без релиза:

  1. Реализуйте что-нибудь, передайте и отправьте это в GitLab
  2. Триггер Дженкинс, созданный с помощью веб-хука от GitLab.
  3. Соберите, протестируйте, соберите, а затем опубликуйте двоичный JAR-файл в хранилище Artifactory.

Вторая и более интересная цель — когда вы хотите создать релизную версию:

  1. Запустите параметрические сборки Jenkins, использующие плагин Gradle Release, чтобы:
    1. Убедитесь, что проект соответствует определенным критериям для публикации.
    2. Создайте тег Git с номером версии релиза.
    3. Измените версию проекта Gradle для дальнейшего развития.
    4. Зафиксируйте это изменение и отправьте его в GitLab.
  2. Запустите еще одну стандартную параметрическую сборку Jenkins для публикации артефактов выпуска в Artifactory.

Ситуация

Я продемонстрирую процесс, описывающий настоящий проект Scala, который я создаю с использованием Gradle. Сервер сборки — Дженкинс . Двоичные артефакты публикуются на сервере с бесплатной версией Artifactory . Система контроля версий — это бесплатная версия сообщества GitLab . Я уверен, что вы можете следовать этому руководству для любого приложения Java . Для ясности этого руководства предположим, что ваши URL-адреса следующие:

  • GitLab репозиторий (SSH) = git@gitlab.local: com.buransky / release-example.git
  • Сервер Jenkins = http: // jenkins /
  • Артефактный сервер = http: // artifactory /

Структура проекта

Ничего особенного не нужно. Я использую общую структуру каталогов:

01
02
03
04
05
06
07
08
09
10
11
12
13
<project root>
  + build (build output)
  + gradle (Gradle wrapper)
  + src (source code)
  + main
    + scala
  + test
    + scala
  - build.gradle
  - gradle.properties
  - gradlew
  - gradlew.bat
  - settings.gradle

Gradle проект

Я использую упаковку Gradle, которая является просто удобным инструментом для загрузки и установки самой Gradle, если она не установлена ​​на машине. Это не обязательно. Но вам нужно иметь эти три файла:

settings.gradle — общие настройки Gradle для мульти-проектов, которые нам не нужны

1
rootProject.name = name

gradle.properties — содержит имя группы, название проекта и версию

1
2
3
group=com.buransky
name=release-example
version=1.0.0-SNAPSHOT

build.gradle — основное определение проекта Gradle

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
buildscript {
  repositories {
    mavenCentral()
  }
  ...
}
 
plugins {
  id 'scala'
  id 'maven'
  id 'net.researchgate.release' version '2.1.2'
}
 
group = group
version = version
 
...
 
release {
  preTagCommitMessage = '[Release]: '
  tagCommitMessage = '[Release]: creating tag '
  newVersionCommitMessage = '[Release]: new snapshot version '
  tagTemplate = 'v${version}'
}

Добавьте следующее, чтобы сгенерировать JAR-файл с исходниками:

1
2
3
4
5
6
7
8
9
task sourcesJar(type: Jar, dependsOn: classes) {
  classifier = 'sources'
  from sourceSets.main.allSource
}
 
artifacts {
  archives sourcesJar
  archives jar
}

Давайте проверим это. Запустите это из оболочки:

01
02
03
04
05
06
07
08
09
10
$ gradle assemble
:compileJava
:compileScala
:processResources
:classes
:jar
:sourcesJar
:assemble
 
BUILD SUCCESSFUL

Теперь у вас должно быть два JAR-файла в каталоге build / libs:

  • релиз-пример-1.0.0-SNAPSHOT.jar
  • релиз-пример-1.0.0-СНАПШОТ-sources.jar

Итак, если это работает, давайте попробуем выпустить его:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ gradle release
:release
:release-example:createScmAdapter
:release-example:initScmAdapter
:release-example:checkCommitNeeded
:release-example:checkUpdateNeeded
:release-example:unSnapshotVersion
> Building 0% > :release > :release-example:confirmReleaseVersion
??> This release version: [1.0.0]
:release-example:confirmReleaseVersion
:release-example:checkSnapshotDependencies
:release-example:runBuildTasks
:release-example:beforeReleaseBuild UP-TO-DATE
:release-example:compileJava UP-TO-DATE
:release-example:compileScala
:release-example:processResources UP-TO-DATE
:release-example:classes
:release-example:jar
:release-example:assemble
:release-example:compileTestJava UP-TO-DATE
:release-example:compileTestScala
:release-example:processTestResources
:release-example:testClasses
:release-example:test
:release-example:check
:release-example:build
:release-example:afterReleaseBuild UP-TO-DATE
:release-example:preTagCommit
:release-example:createReleaseTag
> Building 0% > :release > :release-example:updateVersion
??> Enter the next version (current one released as [1.0.0]): [1.0.1-SNAPSHOT]
:release-example:updateVersion
:release-example:commitNewVersion
 
BUILD SUCCESSFUL

Поскольку я не запускал задачу выпуска с необходимыми параметрами, сборка является интерактивной и сначала просит ввести (или подтвердить) версию выпуска, то есть 1.0.0. И затем позже он снова просит меня ввести следующую рабочую версию, которую плагин автоматически предлагает для 1.0.1-SNAPSHOT. Я ничего не вводил, я только подтвердил значения по умолчанию, нажав Enter.

Взгляните на историю Git, и вы должны увидеть тег v1.0.0 в вашем локальном хранилище, а также в GitLab. Также откройте файл gradle.properties, и вы должны увидеть, что версия была изменена на версию = 1.0.1-SNAPSHOT.

Задача релиза требует много вещей. Например, ваш рабочий каталог не должен содержать незафиксированные изменения. Или все ваши зависимости проекта должны быть версиями выпуска (они не могут быть снимками). Или ваша текущая ветвь должна быть главной. Также у вас должны быть права для перехода на главную ветку в GitLab, потому что плагин релиза будет делать git push.

Настройка Артефактории

На Артефакторной стороне ничего особенного не требуется. Я предполагаю, что он работает и работает, скажем, http: // artifactory /. Конечно, ваш URL, вероятно, отличается. У установки по умолчанию уже есть два репозитория, которые мы опубликуем:

  • ЛИЭС-релиз-местный
  • ЛИЭС-снимок локального

Плагин Jenkins Artifactory

Этот плагин интегрирует Jenkins с Artifactory, что позволяет публиковать артефакты из сборок Jenkins. Установите плагин, перейдите в конфигурацию Jenkins, в разделе Artifactory добавьте новый сервер Artifactory и настройте следующее:

  • URL = http: // artifactory / (ваш другой)
  • Учетные данные по умолчанию для развертывателя
    • предоставить имя пользователя и пароль для существующего пользователя Artifactory, у которого есть разрешения на развертывание

Нажмите кнопку Проверить соединение, чтобы убедиться, что эта часть работает.

Непрерывная интеграция Jenkins build

Это сборка, которая запускается после каждого коммита в master ветке и отправки в GitLab. Создайте его как новый проект в стиле фристайл и назовите его по своему вкусу. Вот список шагов и настроек для этой сборки:

  • Управление исходным кодом — Git
    • URL репозитория = git@gitlab.local: com.buransky / release-example.git (ваш другой)
    • Учетные данные = нет (по крайней мере, мне это не нужно)
    • Ветки для сборки, спецификатор ветви = * / master
  • Построить триггеры
    • Опрос SCM (это необходимо для того, чтобы веб-крючок от GitLab работал)
  • Построить среду
    • Интеграция Gradle-Artifactory (требуется плагин Artifactory)
  • Конфигурация артефакта
    • Artifactory server = http: // artifactory / (ваш другой)
    • Публикация репозитория = libs-snapshot-local (мы собираемся опубликовать снимки)
    • Захват и публикация информации о сборке
    • Опубликовать артефакты в Артефактории
      • Опубликовать дескрипторы Maven
    • Используйте Maven совместимые шаблоны
      • Шаблон плюща = [организация] / [модуль] / плющ [ревизия] .xml
      • Паттерн артефакта = [организация] / [модуль] / [ревизия] / [артефакт] — [ревизия] (- [классификатор]). [Ext]
  • Build — вызвать скрипт Gradle
    • Используйте упаковку Gradle
    • Из Root Build Script Dir
    • Задачи = чистый тест

Запустите сборку и перейдите в Artifactory, чтобы проверить, был ли снимок успешно опубликован. Я использую древовидный браузер, чтобы перейти к libs-snapshot-local / com / buransky / release-example / 1.0.1-SNAPSHOT. Там вы должны найти:

  • бинарные банки
  • исходные банки
  • POM файлы

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

Триггер Дженкинс построить из GitLab

Мы слишком ленивы, чтобы вручную запустить непрерывную интеграционную сборку Jenkins, которую мы только что создали. Мы можем настроить GitLab так, чтобы он делал это для нас автоматически после каждого нажатия. Зайдите в настройки вашего проекта GitLab, раздел Web Hooks. Введите следующее, а затем нажмите кнопку Добавить веб-крючок:

  • URL = http: // jenkins / git / notifyCommit? Url=git@gitlab.local: com.buransky / release-example.git
    • Привет! Думать. Ваш URL отличается, но шаблон должен быть таким же.
  • Триггер = Push события

Если вы попытаетесь проверить этот хук и нажать кнопку «Тестировать хук», вы можете быть удивлены тем, что сборка не запускается. Причина (очень часто) может быть в том, что механизм очень интеллектуален, и если нет новых коммитов, сборка не запускается. Поэтому внесите изменения в свой исходный код, зафиксируйте его, нажмите его, и тогда будет запущена сборка Jenkins.

Сделай перерыв, сделай себе кофе

Это уже было много работы. Мы можем сделать много вещей сейчас. Серверы работают и общаются друг с другом. Я ожидаю, что вам, возможно, понадобится настроить SSH между отдельными машинами, но это выходит за рамки этого разглагольствования. Готов продолжить? Давайте выпустим это дерьмо.

Универсальная сборка Jenkins для публикации релиза в Artifactory

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

  • Название проекта = Опубликовать релиз в Artifactory
  • Эта сборка параметризована
    • Строковый параметр
      • Имя = GIT_REPOSITORY_URL
    • Git параметр
      • Имя = GIT_RELEASE_TAG
      • Тип параметра = тег
      • Фильтр тегов = *
    • Строковый параметр
      • Имя = GRADLE_TASKS
      • Значение по умолчанию = чистая сборка
  • Управление исходным кодом — Git
    • URL репозитория = $ GIT_REPOSITORY_URL
    • Ветки для сборки, Branch Specifier = * / tags / $ {GIT_RELEASE_TAG}
  • Построить среду
    • Удалить рабочее пространство перед началом сборки
    • Gradle-Артефакторная интеграция
  • Конфигурация артефакта
    • Artifactory server = http: // artifactory / (ваш другой)
    • Публикация репозитория = libs-release-local (мы собираемся опубликовать релиз)
    • Захват и публикация информации о сборке
    • Опубликовать артефакты в Артефактории
      • Опубликовать дескрипторы Maven
    • Используйте Maven совместимые шаблоны
      • Шаблон плюща = [организация] / [модуль] / плющ [ревизия] .xml
      • Паттерн артефакта = [организация] / [модуль] / [ревизия] / [артефакт] — [ревизия] (- [классификатор]). [Ext]
  • Build — вызвать скрипт Gradle
    • Используйте упаковку Gradle
    • Из Root Build Script Dir
    • Задачи = $ GRADLE_TASKS

Универсальная сборка Jenkins для выпуска проекта Gradle

Нам также нужна повторно используемая параметрическая сборка Jenkins, которая запускает плагин релиза Gradle с предоставленными параметрами, а затем запускает общую публикацию сборки Jenkins, которую мы уже создали.

  • Название проекта = релиз Gradle проекта
  • Эта сборка параметризована
    • Строковый параметр
      • Имя = GIT_REPOSITORY_URL
    • Строковый параметр
      • Имя = RELEASE_VERSION
    • Строковый параметр
      • Имя = NEW_VERSION
  • Управление исходным кодом — Git
    • URL репозитория = $ GIT_REPOSITORY_URL
    • Ветки для сборки, Branch Specifier = * / master
  • Дополнительные Поведения
    • Проверьте к определенному местному отделению
      • Название филиала = мастер
  • Build — вызвать скрипт Gradle
    • Используйте упаковку Gradle
    • Из Root Build Script Dir
    • Switches = -Prelease.useAutomaticVersion = true -PreleaseVersion = $ RELEASE_VERSION -PnewVersion = $ NEW_VERSION
    • Задачи = релиз
  • Триггер / вызов строится на другом проекте (требуется плагин Parameterized Trigger)
    • Проекты для сборки = Опубликовать релиз в Artifactory
    • Предопределенные параметры
      • GIT_RELEASE_TAG = v $ RELEASE_VERSION
      • GIT_REPOSITORY_URL = $ GIT_REPOSITORY_URL

Финальная версия сборки

Теперь мы наконец готовы создать сборку для нашего проекта, которая создаст релиз. Он ничего не сделает, кроме как вызовет ранее созданные универсальные сборки. В последний раз создайте новый фристайл проект Jenkins, а затем:

  • Название проекта = Пример выпуска
  • Эта сборка параметризована
    • Строковый параметр
      • Имя = RELEASE_VERSION
    • Строковый параметр
      • Имя = NEW_VERSION
  • Подготовить среду для бега
    • Сохранить переменные среды Jenkins
    • Сохраняйте переменные построения Jenkins
    • Свойства Содержание
      • GIT_REPOSITORY_URL=git@gitlab.local: com.buransky / релиз-example.git
  • Управление исходным кодом — Git
    • Использовать SCM из другого проекта
      • Шаблон проекта = релиз Gradle проекта
  • Построить среду
    • Удалить рабочее пространство перед началом сборки
  • Сложение
    • Используйте строителей из другого проекта
      • Шаблон проекта = релиз Gradle проекта

Давайте попробуем выпустить наш пример проекта. Если вы следовали моим шагам, тогда проект должен быть в версии 1.0.1-SNAPSHOT. Выпустит версию 1.0.1 и продвинет текущую версию проекта до следующей версии разработки, которая будет 1.0.2-SNAPSHOT. Так что просто запустите сборку Release example и установите:

  • RELEASE_VERSION = 1.0.1
  • NEW_VERSION = 1.0.2-SNAPSHOT

Используемые инструменты

Вывод

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