Как стать автором
Обновить

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

Время на прочтение4 мин
Количество просмотров2K


Маленькой команде не составляет труда поддерживать историю изменений приложения в ручном режиме. Но, когда команда начинает расширяться, такой файл как 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 репозиторию, по умолчанию - пустой
    userName = "my_user_name"                     // Опциональное имя пользователя для доступа к приватному Git репозиторию(требуется для 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 культуры команды.

Теги:
Хабы:
Всего голосов 4: ↑3 и ↓1+2
Комментарии4

Публикации

Истории

Работа

DevOps инженер
42 вакансии
Java разработчик
347 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань