Keep a Changelog, реально внедрённый
5 мин чтения обновлено
Keep a Changelog — это конвенция на одну страницу для CHANGELOG.md: самая новая версия первая,
один раздел на версию с номером и датой ISO, записи, сгруппированные под шестью типами (Added,
Changed, Deprecated, Removed, Fixed, Security), и раздел Unreleased сверху для записей между
релизами. Большинство команд, ссылающихся на неё, внедряют около двух третей, а треть, которую
они оставляют, — это та треть, что защищает их пользователей.
Оливье Лакан опубликовал Keep a Changelog в 2014 году с фразой, которая состарилась лучше большинства прозы о софте: don’t let your friends dump git logs into changelogs. Десять лет спустя это ближайшее к стандарту, что есть в этом уголке софта. Стоит прочитать источник, а не пересказ; этот текст о частях, которые оставляют в стороне.
Что требует Keep a Changelog?
CHANGELOG.md в корне репо, самая новая версия первая, с одним разделом на версию. Каждая версия
несёт номер и дату ISO, и группирует свои записи под шестью типами:
| Тип | Для | Цена его оставления в стороне |
|---|---|---|
| Added | Новые функции | Ничего; никто это не оставляет |
| Changed | Изменения в существующем поведении | Читатели узнают об изменении поведения из ошибки |
| Deprecated | Функции на пути к удалению | Удаление становится инцидентом вместо запланированного события |
| Removed | Функции, удалённые в этом релизе | Никто не отличает удаление от бага |
| Fixed | Исправления багов | Ничего; никто это тоже не оставляет |
| Security | Уязвимости | Единственная читательница, искавшая это, не находит |
Плюс раздел Unreleased сверху, чтобы было место для записи в момент её merge, и чтобы каждый
мог увидеть, что грядёт.
Это почти всё. Остальное — обоснование: записи для людей, одна запись на изменение, и файл — документ, а не лог.
Какие части Keep a Changelog оставляют в стороне?
Раздел Unreleased, затем четыре из шести типов, Security в их числе, в этом порядке.
Unreleased исчезает первым. Это раздел без дедлайна, поэтому его поддержка прекращается
первой, и как только он исчезает, записи пишутся в момент релиза из истории коммитов. Это именно
тот сброс git-лога, о котором спецификация предупреждает с самого начала, достигнутый постепенно.
Автоматизация changelog в основном о том, как поддерживать этот
раздел живым без того, чтобы кто-то должен был помнить об этом.
Шесть типов схлопываются в два. Большинство реальных changelog заканчиваются с Added и Fixed, потому что Changed и Deprecated требуют суждения о том, на что кто-то полагался. Это суждение — ценная часть. Deprecated в частности — единственный тип, являющийся обещанием о будущем, и его пропуск — это как удаление превращается в инцидент; механика соблюдения этого обещания — в как деприкейтить API.
Security перестаёт быть отдельным. Исправление безопасности, помещённое под Fixed, невидимо для единственной читательницы, искавшей его. Держите его отдельно, даже когда исправление тривиально, и особенно когда вы предпочли бы не привлекать к нему внимание.
На что не отвечает спецификация?
Это формат файла. Он ничего не говорит о вопросах, с которыми вы сталкиваетесь сразу после её принятия:
- Как кто-то узнаёт? Файл в репо достигает контрибьюторов. Он не достигает клиентку, которая никогда не открывала GitHub.
- А продукты без версий? Непрерывно развёртываемый сервис не имеет v4.2.0, по которой можно группировать. Большинство команд заменяют это датами, что работает, и спецификация это ни благословляет, ни запрещает.
- Кто пишет запись? Спецификация предполагает, что это делает человек. Она не говорит когда.
- А множество аудиторий? Один файл обслуживает разработчиков. Он не обслуживает тем же содержимым нетехническую администраторку, и ручное переформатирование для неё — то, откуда начинается дублирование. Changelog vs release notes — это разделение, которое спецификация оставляет вам сделать самостоятельно.
Common Changelog, более строгий форк идеи, ужесточает часть этого: запрещает определённые формулировки записей, требует ссылку на изменение, и имеет чёткое мнение о том, кто читатель. Стоит прочитать, если свободные части Keep a Changelog — это то, о чём ваша команда постоянно спорит.
Можно ли автоматизировать Keep a Changelog без сброса git-логов?
Да: выводите черновик из структурированных коммитов, помещайте его в Unreleased с предзаполненным типом, и требуйте, чтобы человек редактировал формулировку перед выпуском релиза. Предупреждение спецификации о результате, а не об инструменте. Выведение черновика из коммитов — это нормально. Публикация этого черновика без редактирования — то, против чего она возражает.
Машина занимается сбором и форматированием, в чём она хороша. Человек занимается отбором и формулировкой, в чём она не хороша. Conventional commits описывают то разделение на два уровня, на которое это опирается, и то, какие типы коммитов соответствуют каким из шести категорий выше. Наш обзор инструменты для changelog охватывает, что существует для половины сбора.
Где Keep a Changelog перестаёт быть достаточным?
Он останавливается на распространении. Keep a Changelog — хороший ответ на «как должен выглядеть этот файл». Это не ответ на «как наши пользователи узнают, что изменилось», потому что файл Markdown в репо — это стратегия распространения, работающая только если ваши пользователи — контрибьюторы.
Это препятствие, с которым большинство команд сталкивается вторым: файл в порядке, и никто вне команды его не читает. Решение этого означает, что записи должны стать данными, которые можно отобразить в другом месте, что является другой проблемой, чем форматирование файла, и причиной, по которой примеры changelog собирает публичные страницы changelog, а не файлы репозитория. Как превратить эти записи в то, к чему люди возвращаются, разбирает как сделать страницу changelog.
Всё равно примите спецификацию. Она стоит вечера, делает вторую проблему решаемой, и всё ещё лучшая страница, когда-либо написанная об этом.
FAQ
Является ли Keep a Changelog стандартом? Это широко принятая конвенция, а не спецификация органа стандартизации. Инструменты (скрипты релиза, линтеры, парсеры) достаточно часто предполагают её форму, чтобы её следование покупало совместимость.
Что попадает в раздел Unreleased? Каждая запись для изменения, которое было объединено, но ещё не выпущено в пронумерованном релизе. Когда релиз выпускается, раздел переименовывается в версию и дату, а новый, пустой раздел Unreleased идёт над ним.
Должен ли changelog использовать семантическое версионирование? Keep a Changelog рекомендует это и не требует. Библиотеки и API от этого выигрывают; непрерывно развёртываемый сервис обычно заменяет это датами, что формат допускает.
Должны ли исправления безопасности быть в changelog до того, как они публичны? Добавьте запись, когда исправление выпущено, с достаточной детализацией, чтобы оператор мог действовать, и не более. Отложить запись до даты скоординированного раскрытия нормально; опустить её — нет.
Технические утверждения в этой статье не проходили независимую проверку. Если здесь что-то не так, сообщите нам, и мы исправим.