Привет, Хабр! Меня зовут Юрий Петров, я автор Youtube-канала «Мобильный разработчик» и Flutter Tech Lead в компании Friflex. Мы разрабатываем мобильные приложения для бизнеса и специализируемся на Flutter. 

Разработчики используют GitHub, чтобы писать и хранить свои проекты. У многих появляется вопрос: как хранить историю изменений? Конечно, вы можете заполнять файл CHANGELOG.MD самостоятельно в основной ветке после каждого пул-реквеста. Но мы любим автоматизацию. 

В этой статье рассказываю, как файл CHANGELOG.MD может заполняться автоматически. Автоматическое заполнение помогает разработчику понять, что изменилось в новых версиях без изучения исходного кода.

Соглашение о коммитах

Важный момент! Если вы хотите использовать инструменты для автоматического заполнения файла CHANGELOG.MD, вам необходимо создавать коммиты, учитывая соглашение. По сути, соглашение требует, чтобы коммиты были определенного формата.

Представьте ситуацию: Вася добавил новую кнопку для отправки письма и сделал коммит: «я — Вася, добавил новую кнопку для отправки письма». Но соглашение говорит, что коммит должен выглядеть так: «feat: добавить кнопку отправки письма».

Давайте разберем, почему это сообщение соответствует хорошим практикам.

Тип коммита. Используется тип feat, который означает новую функциональность. Он помогает быстро определить природу изменения при просмотре журнала коммитов или генерации CHANGELOG.

Описание. Краткое, но полное описание того, что было сделано. В этом случае «добавить кнопку отправки письма» точно отражает суть изменений. Описание начинается с маленькой буквы и не заканчивается точкой. 

Обязательно изучите соглашение о коммитах и постарайтесь его придерживаться.

Инструменты для создания автоматических коммитов

  • changeln — генерирует файлы журнала изменений на основе Git-тегов;

  • git-cliff — создает файлы журнала изменений из истории Git, используя обычные коммиты, а также пользовательские анализаторы на основе регулярных выражений. Шаблон журнала изменений можно настроить с помощью файла конфигурации в соответствии с нужным форматом;

  • php-conventional-changelog — создает журнал изменений на основе сообщений о фиксации проекта и метаданных, следующих за conventionalcommits.org, и автоматизации управления версиями с помощью semver.org;

  • github-changelog-generator — автоматически создает журнал изменений на основе тегов, проблем, меток и запросов на получение информации на GitHub;

  • standard-version — автоматически управляет версиями и создает списки изменений с помощью semver.org и conventionalcommits.org;

  • semantic-release — автоматически управляет версиями и публикует пакеты.

В интернете в свободном доступе можно найти и другие инструменты.

Для нашего проекта будем использовать git-cliff. Вы можете спросить, почему именно его? Тут ответа нет, просто он мне нравится. И, самое главное, он заработал сразу, без лишних танцев с бубном.

Поговорим о его сильных сторонах.

1. Поддерживает Conventional Commits. git-cliff полностью поддерживает соглашение о коммитах Conventional Commits. И позволяет автоматически классифицировать изменения по типам (например, feat, fix, chore).

2. Настраивается. Один из основных плюсов git-cliff — его конфигурационный файл, который позволяет детально настраивать вывод CHANGELOG. Вы можете выбирать, какие коммиты включать, как они должны быть оформлены, какие разделы должны быть созданы.

3. Интегрируется с системами CI/CD. git-cliff можно легко интегрировать в пайплайны CI/CD. Это позволяет автоматически генерировать и обновлять CHANGELOG при каждом новом релизе.

4. Поддерживает разные платформы. Несмотря на то, что git-cliff разработан на Rust, его можно использовать в проектах на любом языке программирования. Поэтому git-cliff — универсальный инструмент для многих разработчиков.

5. Генерирует разные форматы. git-cliff поддерживает генерацию CHANGELOG в различных форматах, включая Markdown и JSON, что обеспечивает гибкость при интеграции с другими инструментами и сервисами.

6. Управляет версиями. Инструмент может автоматически определять версию следующего релиза на основе коммитов. Управлять версиями и релизами в проекте становится проще. 

А о минусах я писать не буду. Вы можете ознакомиться с ними самостоятельно в баг-репорт.

Создаем проект

Наша основная задача — сделать так, чтобы при пуше в основную ветку появлялась соответствующая запись в файле CHANGELOG.MD. Для этого создадим новый репозиторий на GitHub. Не забываем про галочку add a README file.

После создания он пустой:

Далее выдаем разрешения github action. Для этого переходим в раздел Settings -> Actions -> General и предоставить разрешение для WorkFlows:

Добавляем специальную папку в проект, которая будет называться .github, а в нее — папку workflows, и, наконец, в папку workflows файл generate_changelog.yaml

Папки должны называться именно так, чтобы github их определил как папки с экшенами.

Добавляем в файл generate_changelog.yaml инструкции для github.

generate_changelog.yaml
# Название workflow, описывает его цель
name: Generate Changelog  


# Указывает событие, при котором будет запускаться workflow
on:
  # Событие push в репозиторий  
  push:
    # Указывает, что workflow будет запускаться только при пушах в ветку main  
    branches:
      - main  


# Определяет задачи, которые будут выполнены в рамках workflow
jobs:
  # Имя задачи, можно назвать по-другому, например, "update-changelog"  
  build:
    # Запуск задачи на последней версии Ubuntu  
    runs-on: ubuntu-latest  


    # Шаги, которые необходимо выполнить в рамках задачи
    steps:
      # Использование действия checkout для клонирования репозитория  
    - uses: actions/checkout@v2  
      # Выкачивание всей истории коммитов, необходимо для корректной работы многих инструментов генерации changelog
      with:
        fetch-depth: 0  
   
    # Название шага
    - name: Download and Install git-cliff
      # Команды, которые будут выполнены в рамках шага
      run: |  
        curl -L "https://github.com/orhun/git-cliff/releases/download/v2.2.1/git-cliff-2.2.1-x86_64-unknown-linux-gnu.tar.gz" -o git-cliff.tar.gz  # Скачивание git-cliff
        tar -xzf git-cliff.tar.gz  # Распаковка скачанного архива
        mv git-cliff-2.2.1/git-cliff /usr/local/bin/  # Перемещение исполняемого файла git-cliff в директорию /usr/local/bin
    # Шаг для генерации файла CHANGELOG.md
    - name: Generate Changelog
      # Запуск git-cliff с указанием конфигурационного файла и выходного файла
      run: git-cliff --config cliff.toml --output CHANGELOG.md  
     
    # Шаг для коммита изменений
    - name: Commit Changelog
      # Команды для выполнения  
      run: |  
        git config --global user.name 'github-actions'
        git config --global user.email 'github-actions@github.com'
        git add CHANGELOG.md
        git commit -m "Обновление CHANGELOG.md"
        git push https://github.com/${{ github.repository }}.git HEAD:main  

Отправляем в репозиторий коммит с изменением.

Теперь в репозитории появился файл CHANGELOG.md, но пока он пустой. Добавим в репозиторий первые коммиты.

Чтобы создать коммиты, которые соответствуют соглашению, можно использовать расширение Commit Message Editor.

Добавить в VSCode можно здесь

Создаем в репозитории тестовый файл test.txt. Система контроля версии сразу подсказывает, что появился новый файл. Нажимаем на иконку, чтобы запустить редактирование коммитов.

Заполняем и сохраняем:

В поле с названием коммита появляется правильное название.

Нажимаем commit и пушим в репозиторий. Чтобы проверить работу системы, переходим в репозиторий на сайте GitHub в раздел Actions.

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

В CHANGELOG.md видим, что файл заполнен корректно.

Если вы сделаете коммит, который не соответствует соглашению, то ваш экшен завершится с ошибкой. И файл CHANGELOG.md не обновится.

В логах мы видим, что git-cliff не создал новый CHANGELOG.md.

Обновляем CHANGELOG при релизе

В любом проекте всегда приходит время для релиза. Его тоже можно автоматизировать. Для этого добавим в файл generate_changelog_release.yaml

новый триггер — создание нового релиза.

Hidden text
# Название workflow, описывает его цель
name: Generate Changelog  


# Указывает событие, при котором будет запускаться workflow
on:
  # Событие push в репозиторий  
  push:
    # Указывает, что workflow будет запускаться только при пушах в ветку main  
    branches:
      - main  
  # Событие создания релиза
  release:
    types: [created]


# Определяет задачи, которые будут выполнены в рамках workflow
jobs:
  # Имя задачи, можно назвать по-другому, например, "update-changelog"  
  build:
    # Запуск задачи на последней версии Ubuntu  
    runs-on: ubuntu-latest  


    # Шаги, которые необходимо выполнить в рамках задачи
    steps:
      # Использование действия checkout для клонирования репозитория  
    - uses: actions/checkout@v2  
      # Выкачивание всей истории коммитов, необходимо для корректной работы многих инструментов генерации changelog
      with:
        fetch-depth: 0  
   
    # Название шага
    - name: Download and Install git-cliff
      # Команды, которые будут выполнены в рамках шага
      run: |  
        curl -L "https://github.com/orhun/git-cliff/releases/download/v2.2.1/git-cliff-2.2.1-x86_64-unknown-linux-gnu.tar.gz" -o git-cliff.tar.gz  # Скачивание git-cliff
        tar -xzf git-cliff.tar.gz  # Распаковка скачанного архива
        mv git-cliff-2.2.1/git-cliff /usr/local/bin/  # Перемещение исполняемого файла git-cliff в директорию /usr/local/bin
    # Шаг для генерации файла CHANGELOG.md
    - name: Generate Changelog
      # Запуск git-cliff с указанием конфигурационного файла и выходного файла
      run: git-cliff --config cliff.toml --output CHANGELOG.md
     
    # Шаг для коммита изменений
    - name: Commit Changelog
      # Команды для выполнения  
      run: |  
        git config --global user.name 'github-actions'
        git config --global user.email 'github-actions@github.com'
        git add CHANGELOG.md
        git commit -m "Обновление CHANGELOG.md"
        git push https://github.com/${{ github.repository }}.git HEAD:main  


Таким образом, когда мы создадим первый релиз, то автоматически он появится в CHANGELOG.

Переходим в раздел для создания релиза. Выбираем тег или создаем новый:

Даем название релизу и публикуем:

После этого ваш CHANGELOG будет выглядеть следующим образом: 

И все дальнейшие коммиты будут помечаться как нерелизные.

О других возможностях GitHub Action можно узнать в документации. Если у вас возникнут какие-то вопросы, напишите в комментариях. Я постараюсь всем ответить.

Комментарии (1)


  1. Apokalepsis
    10.05.2024 00:20

    Думаю стоить заменить:

    # Название шага
        - name: Download and Install git-cliff
          # Команды, которые будут выполнены в рамках шага
          run: |  
            curl -L "https://github.com/orhun/git-cliff/releases/download/v2.2.1/git-cliff-2.2.1-x86_64-unknown-linux-gnu.tar.gz" -o git-cliff.tar.gz  # Скачивание git-cliff
            tar -xzf git-cliff.tar.gz  # Распаковка скачанного архива
            mv git-cliff-2.2.1/git-cliff /usr/local/bin/  # Перемещение исполняемого файла git-cliff в директорию /usr/local/bin
        # Шаг для генерации файла CHANGELOG.md
        - name: Generate Changelog
          # Запуск git-cliff с указанием конфигурационного файла и выходного файла
          run: git-cliff --config cliff.toml --output CHANGELOG.md

    На:

    - name: Generate a changelog
      uses: orhun/git-cliff-action@v3
      with:
        config: cliff.toml
        args: --verbose
      env:
        OUTPUT: CHANGELOG.md