
Маленькой команде не составляет труда поддерживать историю изменений приложения в ручном режиме. Но, когда команда начинает расширяется, такой файл как 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/
Добавить комментарий