1. Реліз — окрема межа після merge
Коли перший PR зелений, другий зелений, а CI радісно блимає зеленим, виникає дуже людське бажання сказати: «Усе, реліз готовий». І ось тут зазвичай починається маленька інженерна магія, яка легко переходить у маленький інженерний хаос. Merge і release трапляються після одних галочок, але відповідають на різні запитання. PR → main: чи можна безпечно прийняти зміну в основну гілку. main → release: який набір прийнятих змін ми вважаємо новою версією і як це зафіксувати, щоб за тиждень не вгадувати за логами і памʼяттю команди.
Для Commerce OS це виглядає дуже життєво. Уявіть, що в main потрапили три зміни: прибрали дублікати в /api/orders, виправили порядок заявок на повернення в support inbox, оновили README з командами локального запуску. Усе пройшло review. Але доки немає версії, changelog, тегу і запису «що увійшло» — немає й відповіді менеджеру: «Що ми сьогодні викладаємо?»
Корисно тримати в голові таку коротку таблицю:
| Межа | На яке запитання відповідає | Типові артефакти |
|---|---|---|
| PR → main | Чи можна прийняти зміну в основну гілку? | diff, тести, lint, review notes |
| main → release | Що саме ми вважаємо новою версією і як це оформити? | changelog, тег, release notes, rollback note |
Звідси й головний зсув мислення: release automation — це не «зробити кнопку публікації красивішою». Це зробити момент пакування релізу перевірюваним і зрозумілим. Інакше у вас буде зелений код, але туманний реліз — а це приблизно як ідеально зібрана валіза без квитка та адреси аеропорту.
2. Артефакт і дія: головна межа релізу
На цій темі найчастіше спотикаються новачки, бо зовні здається, ніби «підготувати реліз» — це одна операція. Насправді всередині неї живуть дві дуже різні сутності. Перша — артефакт, тобто текст, файл, зведення, нотатка або пропозиція. Друга — дія, тобто операція, яка вже змінює стан репозиторію, реєстру пакетів, сторінки релізу або іншої системи.
Ця відмінність критична для роботи з Claude. Claude чудово готує артефакти. Він уміє швидко зібрати changelog із merged PR, запропонувати нову версію, написати чорновик release notes і навіть зібрати rollback note на основі історії комітів. Але щойно мова переходить до створення тегу, публікації артефакту або запуску release job, ми виходимо із зони «підготувати текст» у зону «виконати дію з наслідками».
Для Commerce OS це можна розкласти так:
| Що це | Приклад | Роль Claude |
|---|---|---|
| Артефакт | чорновик CHANGELOG.md | може підготувати |
| Артефакт | пропозиція версії 1.6.0 | може запропонувати й пояснити |
| Артефакт | релізні нотатки для сторінки релізу | може зібрати чорновик |
| Артефакт | rollback note | може підготувати основу |
| Дія | створити тег v1.6.0 | лише після погодження людиною |
| Дія | опублікувати release artifact | лише після погодження людиною |
| Дія | запустити publish job | лише після погодження людиною |
Якщо хочеться однієї короткої аналогії, то вона така: Claude може дуже швидко написати вам список речей у дорогу і навіть позначити, які документи перевірити перед виїздом. Але давати йому ключі від машини й доручати «ну ти там сам доїдь до аеропорту» — уже поганий інженерний стиль, навіть якщо список вийшов чудовий.
Саме тому в release automation завжди корисно ставити собі запитання: це зараз опис релізу чи вже операція над релізом? Поки ви відповідаєте «опис», Claude — чудовий помічник. Щойно чесна відповідь — «операція», має зʼявитися людина, яка читає, перевіряє й усвідомлено натискає кнопку.
3. Версія, changelog і тег без містики
Слова semver, tag, release notes легко звучать як щось для дорослих розробників із бородою і клавіатурою за пів зарплати. Насправді базова механіка дуже проста. Версія — це спосіб назвати конкретний стан продукту. Changelog — це людське пояснення, що в цій версії змінилося. Тег — це мітка в Git, яка вказує рівно на той коміт, який ви вважаєте релізом.
Якщо зовсім по-простому, версія 1.6.0 — це не магічне число, а домовленість команди. Зазвичай використовується така логіка:
| Зміна | Приклад | Версія |
|---|---|---|
| Patch | дрібне виправлення бага без зміни зовнішнього контракту | 1.5.2 → 1.5.3 |
| Minor | нова можливість без зворотно несумісних змін | 1.5.2 → 1.6.0 |
| Major | зворотно несумісні зміни контракту або поведінки | 1.5.2 → 2.0.0 |
Claude тут може дуже допомогти: він уміє зібрати список змін і запропонувати, чому версія схожа на patch, minor або major. Але фінальне рішення все одно залишається людським, бо саме людина розуміє, чи справді ця зміна ламає очікування зовнішніх користувачів або інших сервісів.
Із changelog усе ще простіше. Це звичайний markdown-файл, який пояснює, що потрапило в реліз. Наприклад:
## [1.6.0] - 2026-05-24
### Виправлено
- Прибрано дублікати в `/api/orders`.
- Виправлено порядок заявок на повернення в support inbox.
### Змінено
- Оновлено інструкції локального запуску Commerce OS.
А тег — це просто мітка на конкретному коміті:
git tag v1.6.0 # позначаємо конкретний коміт як реліз
git push origin v1.6.0 # надсилаємо тег до віддаленого репозиторію
Тут важливий не сам синтаксис — Git тут прямолінійний, дякуємо йому за рідкісну ввічливість. Важлива дисципліна: тег ставиться після перевірки changelog, версії та складу релізу, а не «давайте швидко проставимо, потім розберемося». Tag — це дія, а не нотатка на полях.
Ще одна корисна тонкість: CHANGELOG.md і release notes схожі, але це не одне й те саме. CHANGELOG.md живе в репозиторії. Release notes — це текст для сторінки релізу, листа, картки в хостингу. Claude може зібрати одне з іншого, але перевіряються обидва однаково: без вигаданих пунктів і «красиво звучних» покращень, яких у PR не було.
4. Claude готує реліз, а не випускає його
Коли команда вперше вмикає Claude у release workflow, дуже хочеться попросити: «Підготуй реліз». Формулювання красиве, але небезпечне — межі в ньому немає. Корисніше маленькі задачі: зібрати зміни між тегами, згрупувати PR, запропонувати версію, підготувати rollback note.
У Commerce OS це зручно будувати на вже вивченому Workflow Kit. Skill release-notes не «вміє випускати реліз», а вміє рівно одне: перетворювати історію merged PR на чорновик нотаток. Claude тут не автопілот, а швидкий редактор і аналітик.
Ось приклад нормального запиту для такої задачі:
Збери чорновик релізних нотаток за змінами між тегами v1.5.0 і HEAD.
Згрупуй пункти на:
- зміни для користувачів
- виправлення
- внутрішні покращення
Для кожного пункту вкажи джерело: PR або commit.
Не вигадуй змін, яких немає в історії.
Окремо запропонуй нову версію і коротко поясни вибір.
Чому такий запит добрий? У нього обмежений вхід, обмежений вихід і зрозумілий критерій перевірки. Claude не створює теги, нічого не публікує і не вдає, ніби знає історію проєкту краще, ніж реально бачить у Git. За історією Commerce OS він поверне щось на кшталт такого:
### Запропонована версія
`1.6.0`
Причина: є виправлення помилок і одне невелике функціональне покращення без зворотно несумісних змін API.
### Виправлення
- PR #418: усунено дублікати в `/api/orders`
- PR #421: виправлено порядок заявок на повернення в support inbox
### Внутрішні покращення
- PR #423: оновлено інструкції локального запуску в README
Якщо такий чорновик потрібен регулярно, питання зміщується з тексту на форму інструмента: де вистачає skill, а де команда ось-ось побудує зайву автоматизацію.
Це вже корисний чорновик. Але саме чорновик. Тут часто роблять дуже зрозумілу помилку: раз текст виглядає переконливо, значить, його можна не читати. Ні, читати все одно треба. Claude може згрупувати не туди або пропустити приховану зворотно несумісну зміну: PR виглядає як «внутрішнє покращення», а всередині тихо змінює формат зовнішньої відповіді — і minor перетворюється на major. У моделі немає відчуття корпоративного болю, у команди — є.
Тому добра формула звучить так: Claude збирає, людина затверджує. І чим небезпечніший крок, тим жорсткіша межа.
5. Release-логіка в QUALITY_GATES.md
До цього моменту QUALITY_GATES.md уже описував рух change через PR і merge, поруч могли зʼявитися docs-правила. Тепер у нього зʼявляється ще один розділ — не PR → main, а main → кандидат на реліз. Той самий артефакт, дві різні межі ухвалення рішення.
## main -> release candidate
### Claude готує
- чорновик `CHANGELOG.md`
- зведення merged PR із минулого тегу
- пропозицію нової версії
- чорновик rollback note
### Потребує погодження людини
- створення тегу релізу
- публікація release artifact
- запуск publish job
### Не автоматизуємо на цьому рівні
- production deploy
- destructive DB migration
- force-push і видалення тегів
Так в одному місці живуть і правила merge, і правила release candidate — без відчуття, що команда живе за трьома різними шаблонами. Зверніть увагу на корисну дрібницю: тут немає спроби сказати «AI review тепер сам вирішує, чи випускати реліз».
Корисно також памʼятати звʼязок із docs-as-code, він тут прямий. Changelog і release notes — документація, отже, їх перевіряють проти реальної історії PR, комітів і тегів. Написано «додано новий фільтр для операторів підтримки», а такого PR у релізі немає — це не «косметична неточність». Це помилка релізного артефакту, виправляти її треба як неправильний README.
Невелика схема процесу виглядає так:
flowchart TD
A[Злиті PR у main] --> B[Claude збирає чорновик changelog і версії]
B --> C[Людина перевіряє текст і склад релізу]
C --> D[Створюється тег релізу]
D --> E[Публікується release artifact]
На схемі навмисно немає production deploy. Не тому що його не існує, а тому що сьогодні ми свідомо тримаємо межу раніше: вчимося пакувати реліз і не плутати текстову підготовку з небезпечними діями.
6. Rollback note економить нерви
З release automation майже завжди відбувається одна й та сама історія. Поки все добре, rollback note здається нудним бюрократичним додатком. Але в той день, коли реліз пішов не туди, він стає найулюбленішим документом усієї команди. Тому краще подружитися з ним заздалегідь — поки ніхто не бігає по дзвінках із «на який тег ми відкотилися?»
Величезним він бути не повинен. Для Commerce OS на рівні developer literacy вистачає мінімального шаблону:
## Нотатка про відкат
- останній стабільний тег: `v1.5.2`
- шлях відкату: відкотити merge-коміт PR #421 і повернути реліз на `v1.5.2`
- вплив на дані: міграцій немає
- відповідальний: черговий інженер релізу
Чому це важливо саме в сьогоднішній темі? Тому що rollback note — ідеальний приклад релізного артефакту. Claude допоможе його зібрати. Але відповідальність за коректність тексту без людини він не візьме: лише людина знає, чи не було в одному з merged PR прихованої зміни конфігурації, залежностей або зовнішнього сервісу, неочевидної зі summary.
Тут часто виникає спокуса махнути рукою: «Ну в нас же невеликий сервіс, якщо що — відкотимо». Насправді саме невеликі команди страждають без rollback note сильніше за все: знання живуть у головах, а не в документах. Одна відпустка, одне звільнення, один важкий спринт — і знання «як повернути попередню стабільну версію» випаровується швидше за каву на мітапі DevOps.
Якщо сформулювати зовсім коротко, хороший rollback note робить реліз не тільки випускаємим, а й зворотним. А зворотність — одна з найбільш недооцінених форм інженерного спокою.
7. Цілісний сценарій релізу в Commerce OS
Корисно наприкінці зібрати все в один живий сценарій, щоб тема не розпалася на терміни. Звичайний тиждень Commerce OS: ті самі три PR у main, перевірки пройшли, готуємо реліз. Claude через skill на кшталт release-notes збирає зміни між останнім тегом і HEAD, пропонує версію 1.6.0, пише чорновик changelog і rollback note. Далі важливе: людина звіряє пункти з merged PR, ловить приховану зворотно несумісну зміну, перевіряє, що changelog не бреше, — і лише тоді погоджується з версією. Потім тег, потім публікація. Не навпаки.
І ось у цей момент release automation стає нормальною інженерною системою. У команди є відповідь на чотири запитання. Що увійшло в реліз? Чому версія саме така? Де зафіксовано стан? Як відкотитися, якщо все пішло не за планом? Поки відповісти швидко й спокійно не можна — реліз ще не зібрано, навіть якщо CI давно зелений.
І коли в QUALITY_GATES.md є розділ про release candidate, а поруч живуть чесний changelog, акуратний tag і короткий rollback note, реліз перестає бути лотереєю. Він стає ще однією керованою інженерною межею — майже без магії, зате з куди меншою кількістю раптових пригод.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ