Автоматизация changelog в системе сборки Gradle

от автора

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

На помощь, как всегда, приходит автоматизация. Если интересно узнать о том, как автоматизировать генерацию changelog в gradle проекте, добро пожаловать под кат.

Как было в маленькой команде?

Для того, чтобы тестировщик всегда знал, что было сделано в конкретной сборке приложения, в системе контроля версий находился специальный файл с названием changelog.md, в который каждый разработчик в Pull Request обязан был добавить короткую суть своих изменений. Обычно, у каждой записи в этом файле есть свой номер, который берется из Task Tracker. Выглядит это примерно так:

# Changelog  ## 3.7.3 - PRJ-2982: Убрать кнопку конвертации с экрана рублевого счета - PRJ-3021: Поменять навигацию после обмена валюты на главный экран /* другие записи */

Этот файл прикладывался к каждой сборке в CI/CD при выкладке сборки в сервис доставки сборок тестировщикам.

Естественно, с ростом количества членов команды, в этом файле начали постоянно появляться merge-конфликты, что приводило к нездоровой атмосфере в команде, когда психологически разработчику хочется замержить свои изменения первым без конфликтов, а если не успел, то придется разруливать эти конфликты самому и опять ждать, когда пройдут стадии pipeline CI/CD.

Также сервисы доставки сборки обычно имеют ограничения на длину changelog.md, что приводило еще к обязанности разработчику следить за удалением из этого файла устаревших записей. А удаленные ID записей складывать в специальную секцию под названием Folded

# Changelog  ## 3.7.3 - PRJ-2982: Убрать кнопку конвертации с экрана рублевого счета - PRJ-3021: Поменять навигацию после обмена валюты на главный экран /* много записей */  ## Folded PRJ-2834 PRJ-2835 /* другие ID */

Решено было убрать этот файл из системы контроля версий и генерировать его автоматически из истории комитов. Так родился плагин для Gradle, который занимается генерацией changelog.md с учетом GitFlow, который практиковался в нашей команде.

Почему свой велосипед?

Быстрое изучение готовых решений не увенчалось успехом. Каким бы хорошим решение ни было, чего-то в нем не хватало и никак не «натягивалось» на наш процесс разработки. А нам нужны были такие фичи:

  • Плагин должен уметь собирать историю комитов от вершины текущей релизной ветки, до корня предыдущей, либо от вершины текущей ветки до корня предыдущей релизной ветки
  • Плагин должен уметь пропускать комиты без номеров задач, т.е. комиты без «№: » не должны попадать в changelog.md
  • Плагин должен уметь автоматически следить за лимитом файла и схлопывать устаревшие записи в секцию Folded
  • Плагин должен давать возможность задать свой шаблон рендеринга changelog.md
  • Плагин должен уметь работать с приватными репозиториями Azure, Github и GitLab

Как пользоваться плагином?

Для начала добавьте плагин в build.gradle

plugins {     id 'com.a65apps.changelog' version '1.1.10' }

Теперь нам остается только настроить плагин:

changelog {     def token = System.getenv().get("TOKEN")      // PAT токен для доступа к приватному Git репозиторию(требуется для Azure, Github и GitLab)      currentVersion = '1.1'                        // Текущее имя релиза, по умолчанию - 'Unreleased'     lastReleaseBranch = "releases/1"              // Последняя ветка релиза, обязательное поле     templateFile = "template/changelog.mustache"  // Шаблон для рендеринга changelog.md, обязательное поле     accessToken = token                           // Токен для доступа к приватному Git репозиториюy, по умолчанию - пустой     userName = "my_user_name"                     // Опциональное имя пользователя для доступа к приватному Git репозиториюy(требуется для GitLab), по умолчанию - пустой     developBranch = 'master'                      // Общая ветка разработки, по умолчанию - 'develop' }

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

# Changelog  ## {{title}} {{#entries}} {{message}} {{/entries}}  ## Folded {{#shortEntries}} {{foldId}} {{/shortEntries}}

Описание полей для шаблона:

Поле Описание
title значение поля currentVersion
entries лист записей
message короткая запиись из Git комита
shortEntries лист схлопнутых записей
foldId ID задачи(первые 8 символов хэша комита)

Для корректной работы плагина есть еще дополнительное условие — в системе CI/CD, на задачи, требующие генерацию changelog.md, должна быть выставлена опция для git — вытягивать историю всех веток проекта. Иначе плагин не сможет определить путь от головы текущей ветки до корня последней релизной ветки в проекте.

Теперь мы можем запускать генерацию changelog.md одной командой:

./gradlew changelog

Сгенерированный файл changelog.md будет по умолчанию в $buildDir/outputs/changelog.md

Дополнительные параметры настройки

Для более точной настройки можно воспользоваться дополнительными параметрами плагина:

changelog {     currentReleaseBranch = "releases/2"  // Определяет текущую ветку релиза     local = true             // Только для локальной отладки(если у Вас уже склонирован репозиторий)     characterLimit = 10_000  // Ограничивает лимит файла до этого значения, когда количество записей выйдет за пределы лимита, старые записи будут отправляться в Folded секцию     outputFile = "$buildDir/path/to/changelog.md" // Можно определить свой путь, куда будет сохраняться сгенерированный файл     entryDash = "*"          // Свой символ записи в буллет листе, по умолчанию - '-'     templateExtraCharactersLength = 29  // В шаблоне есть статические символы - их можно посчитать и прописать здесь, для более точной работы лимитов     order = LogOrder.LAST_TO_FIRST  // Порядок записей. По умолчанию LogOrder.FIRST_TO_LAST     minEntryCount = 10      // Минимальное количество полных записей в логе, нужно на случай если релиз очень большой и даже схлопнутые записи уже отъедают все возможные лимиты для changelog }

Исходники плагина можно посмотреть здесь

Резюме

Благодаря автоматизации и удобной системе плагинов Gradle, нам удалось решить проблему со скучностью поддержания в ручном режиме такого важного файла как changelog.md.

Это уменьшило вероятность ошибиться при обновлении лога изменений, т.к. убрало человеческий фактор из этого порцесса.

Уже несколько лет плагин успешно применяется на проектах и стал неотъемлемой частью DevOps культуры команды.


ссылка на оригинал статьи https://habr.com/ru/post/659399/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *