Что такое semantic-release и как с ним работать

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Привет! Я — Алексей Бондаренко, работаю в команде Платформа Банки.ру. Сегодня хочу рассказать о semantic-release и его практическом применении на примере упрощения разработки и внедрения библиотеки в проект. 

План такой: 

  • начну с определений и принципов версионирования, которые нужны для понимания темы;

  • расскажу, что дает использование semantic-release;

  • разберу, как работает инструмент, в чем его особенности и ограничения. 

В конце статьи будет ссылка на репозиторий. Его можно использовать в качестве стартовой точки для работы с semantic-release

Что такое версионирование

Хотя с этим понятием большинство знакомо, напомнить считаю нелишним.

С версионированием мы встречаемся часто. Будь-то модель автомобиля в разных поколениях и модификациях или литературное произведение в разных изданиях. 

С кодом похожая история. Пишем код, начинаем его использовать — одна версия. Делаем доработки, включаем новый функционал — появляется другая.
Встает вопрос — а как называть эти версии? Словами, которые передают смысл изменений, нумеровать по порядку или как-то еще?

В разработке используют разные варианты присваивания версий коду. Например, Calendar Versioning (CalVer), zer0ver. Подробнее о них можно почитать в этой статье.

Но самый популярный, пожалуй, это семантическое версионирование или semver

Принципы семантического версионирования

Семантическое версионирование —  это набор правил и требований, которые определяют, как назначаются и увеличиваются номера версий. 

Версия в семантическом версионировании — это три числа, разделенные точкой.

где:

Z — патч-версия, когда меняется что-то внутри и публичное API остается прежним. Например, поменялся метод сортировки в одном из элементов, библиотека стала быстрее работать.

Y — минорная версия, когда добавлена новая функциональность и не нарушена обратная совместимость API. К публичному методу добавился дополнительный необязательный параметр.

X — мажорная версия, когда нарушена обратная совместимость API . Например, переименовали публичный метод.

Приведу аналогию из жизни автомобилиста.
Z — поменяли лампочки в фарах автомобиля: свет как был, так и остался, просто стали ярче гореть фары.
Y —  появился новый режим у кондиционера: добавили обдув заднего стекла.
Z —  поменяли органы управления: кнопку перенесли из одного места в другое. Тут без прочтения инструкции не обойтись.

Что дает semver

Корректная схема управления версиями помогает разработчикам легко идентифицировать текущий выпуск, внесенные изменения, а также совместимость версии с предыдущими. Конкретно семантическое версионирование имеет смысл только при разработке библиотек: кодовая база одна, а потребителей много. 

Как писал мои коллега в одной из статей, мы прошли долгий путь от монолита с сабмодулями, до микрофронтендов с большим количеством общих библиотек. Наша команда разрабатывает и поддерживает внутренний UI-KIT компонентов, которые используют в проектах всех продуктовых вертикалей компании. С этой библиотекой внутри компании мы работаем как с open-source проектом: каждая команда может внести изменения и прислать их на ревью.

Раньше библиотека компонентов подключалась к основному монолитному проекту сабмодулем (git submodule). В такой схеме были риски: можно было установить указатель не на тот коммит и сломать код. Чтобы этого избежать, приходилось использовать скрипт, который проверял, что в релизе хеш сабмодуля указывает на коммит из мастера. 

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

Как начать использовать семантическое версионирование

Допустим, мы поняли, что семантическое версионирование это здорово, и решили его использовать. Что для этого нужно?
Начнем с минимума — ручного управления версиями и изменениями без деплоя.
Представим, что у нас есть репозиторий, где мы храним код.

Один из вариантов — добавить к коду тег, он же — версия:

git tag 1.0.0

и отправить в репозиторий (со всеми тегами):

git push --tags

Потом установить оттуда:

npm i <путь к репозиторию>#<тег> 
// например npm i https://github.com/shakacode/bootstrap-loader.git#v1.0.10

Присвоить тег можно и через веб-интерфейс git репозитория.

С этим минимумом работать можно, но неудобно. Не хватает одного важного момента. Как было написано выше, семантическое версионирование помогает понять, какие изменения были сделаны. А значит, где-то нужно хранить информацию об этих изменениях. Обычно их фиксируют в файле changelog.md.

Как это всё синхронизировать? И тег проставить, и написать, какие изменения были сделаны конкретно в этой версии.

Устанавливать пакет напрямую из git репозитория — хорошее решение для начала, но для production разработки не очень подходит. Так как исходный код пакета, как правило, отличается от поставляемого кода

Всем хочется простоты: устанавливать уже готовые к работе библиотеки, используя их имена. Обычно для этого используют реестр пакетов npm. Код готовят и публикуют в этом реестре. Здесь важно следить за правильностью версии в package.json. Если нужно, присваивать тэг.

Задача опять усложняется: нужно синхронизировать git репозиторий, информацию о внесенных изменениях (changelog.md) и реестр пакетов

Делать это руками можно, но сложно. Человеческий фактор часто приводит к ошибкам. Semantic-release позволяет всю эту рутину автоматизировать и ошибок избежать. 

Как работает semantic-release

Semantic-release — это npm пакет, который полностью автоматизирует большой объем работы.

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

Самое важное для корректной работы semantic-release — писать коммит-сообщения в определенном формате. Для этого есть правила, описанные в cоглашениях о коммитах. По умолчанию используются Angular коммит-сообщение.

Когда мы пишем коммиты в соответствии с соглашениями, мы тем самым решаем проблему «добавления информации о внесенных изменениях» (changelog). В коммитах указываем, какие изменения были внесены в код. Semantic-release будет анализировать эти сообщения и формировать список изменений для определенной версии кода: какие изменения попадают в мажор, минор и патч-версию. 

Шаблон коммит-сообщения выглядит следующим образом:

<тип>[необязательный контекст]: <описание>

[необязательное тело]

[необязательная(ые) сноска(и)]

Пример такого сообщения:

feat: Добавлена возможность отображения виджета вертикально

Добавлена пропса direction отвечающая за направление отображения виджета.

Task: #WIDGETS-32

Настройка semantic-release

Semantic-release работает по принципу плагинов и включает в себя девять шагов. На каждом шаге управление передается плагинам для выполнения определенных действий.

В semantic-release по умолчанию включены следующие плагины:

  • @semantic-release/commit-analyzer

  • @semantic-release/release-notes-generator

  • @semantic-release/npm

  • @semantic-release/github

@semantic-release/commit-analyzer — анализирует коммит-сообщения.
@semantic-release/release-notes-generator  — генерирует список изменений (changelog) от последнего релиза до текущего коммита.
@semantic-release/npm — публикует пакет в npm.
@semantic-release/github — работает с github релизами и комментирует в issues.

Стартовать можно с конфигом и плагинами по умолчанию.

Semantic-release можно запустить локально с помощью команды (написана ниже). Предварительно нужно сделать коммит в соответствии с соглашениями о коммитах.

NPM_TOKEN=<npm_token> GH_TOKEN=<github_token> npx semantic-release --no-ci --dry-run

Эта команда с ключиком --dry-run совершит тестовый запуск semantic-release (без шагов: подготовка, публикация, добавление канала, успех и сбой). Флаг --no-ci позволяет запустить semantic-release с локальной машины (пропускает проверку среды непрерывной интеграции).

Если хотите, чтобы эта команда отработала по-настоящему, уберите флаг --dry-run.

Как создать github персональный токен (<github_token>) можно узнать — тут. А npm токен (<npm_token>)  —  тут. Строчки, которые будут сгенерированы, надо добавить в команду выше.

В результате мы должны получить опубликованный пакет в npm и запись в релизах

Для того, чтобы было совсем хорошо не хватает еще двух плагинов:

  • @semantic-release/changelog

  • @semantic-release/git

@semantic-release/changelog  — вносит изменения в changelog файл, из которого потом можно получить информацию о внесенных в код изменениях (не все же используют github для пакетов).
@semantic-release/git  — коммитит изменения в git репозиторий.

Здесь нам уже не обойтись без конфигурационного файла. В простом варианте он будет выглядеть следующим образом:

// .releaserc
{
    "branches": ["master"],
    "plugins": [
        "@semantic-release/commit-analyzer",
        "@semantic-release/release-notes-generator",
        "@semantic-release/changelog",
        "@semantic-release/npm",
        "@semantic-release/github",
        "@semantic-release/git"
    ]
}

Подробнее о конфигурировании можно почитать тут.

После запуска semantic-release мы должны увидеть запись в changelog файле и коммит с изменениями в git репозитории. Нужно помнить, что бот делает коммит в ветке, которая у вас указана для деплоя. В нашем случае это master. Следовательно, этому пользователю нужно прописать права на пуш в мастер.

Semantic-release имеет много плагинов на разные случаи. С их перечнем можно ознакомиться на официальном сайте. Либо написать свой.

Песочница для тестирования semantic-release

Чтобы поиграться с semantic-release, используйте подготовленный для этих целей github repo. Там есть более подробная инструкция. А здесь можно увидеть npm пакет результата.

Ограничения подхода 

  1. Не получится откатить изменения. Если выпустили версию и в ней обнаружились проблемы, решить это можно только выпуском новой версии. 

  2. Коммит-сообщения должны быть сделаны по правилам  соглашений о коммитах. Эту задачу можно автоматизировать. Например, с помощью commitlint.

  3. К процессу нужно подходить ответственно. Делить коммиты на законченные порции изменений. Любителей коммитов типа «fix fix fix» точно ждут разочарования. 

  4. На ревью следите, чтобы коммит-сообщения отражали изменения в коде.

  5. Для любителей сквош коммитов тоже будут разочарования: соглашение будет нарушено и семантик релиз не увидит изменения.

Альтернативы

  • go-semantic-release

  • release-please

  • standard-version

  • release-it

  • GitVersion

  • release-me

  • changesets

Вывод

Обкатали новый подход. Да, поймали много проблем, но нам понравилось! Сейчас 10+ библиотек деплоятся с помощью semantic-release в полностью автоматическом режиме. Скорость деплоя увеличилась в разы. Не надо никого обучать публиковать пакеты руками и тратить на это время.

Источник: https://habr.com/ru/companies/banki/articles/805653/


Интересные статьи

Интересные статьи

Начнем немного издалека: так уж сложилось, что наш глаз видит яркости окружающего мира в нелинейной кривой. Там, где в реальном мире яркость одного объекта может быть больше другого в 2 раза, для наше...
Привет, Хабр! Меня зовут Андрей, в Selectel я руковожу отделом продуктов клиентской безопасности. Мы предоставляем и развиваем защищенную IT-инфраструктуру, помогаем клиентам хранить данные в соотве...
По разным данным, за февраль и март из России уехало от 50 до 70 тысяч работников ИТ. Насколько точна эта информация, пока сказать сложно. По словам главы группы InfoWatch Натальи Касперской, страну п...
Друзья, всех приветствую!В этой статье мы поговорим о том, что такое Netcat и с помощью него реализуем Bind и Reverse Shell соответственно.NetcatNetcat, впервые выпущенный в 1995 году (!), является од...
Что делать с данными в 2021 году, если вы финансовая компания с традиционной инфраструктурой и не смотрели дальше BI? Как и зачем договариваться разным бизнесам в B2B и ч...