Linear Release — релізний менеджмент, який видно лише коли він працює

Технічний огляд нової фічі Linear Release з нотатками про міграцію реального маркетплейс-проєкту з лейбл-схеми.

Релізний менеджмент — це з тих речей, які непомітні, коли все працює добре, і нестерпні, коли ні. Роками користувачі Linear обходили відсутність нормального release-примітиву — версійні лейбли, групи, кастомні статуси, саморобні скрипти. Це працювало. І тихо ламалося: лейбл не перейменували в одній з команд, issue застрягло в "Awaiting Release" на три спринти, а стейкхолдер питає "то що насправді зараз у проді?" — і ніхто впевнено не відповідає.

Тоді Linear випустили Linear Release — повноцінну сутність із pipelines, stages, версіями та CI-інтеграцією. Це огляд фічі з нотатками про міграцію реального маркетплейс-проєкту з лейбл-схеми.

Як було раніше

Без об'єкту релізу кожна команда вигадує свій протокол. У мене він був такий. Кожне issue, яке йшло в реліз, отримувало версійний лейбл — next_v1.5.0_marketplace — який жив у label-групі Versions. Group exclusivity не давав одному issue нести два версійних лейбли водночас. Після деплою next_* перейменовувався в current_*, а попередній current_* — в old_*. Окреме issue "Release vX.Y.Z" тримало QA-чеклист для задеплоєного білда.

Кастомна CI-частина закривала прогалини: dispatch-тригернутий GitHub Actions workflow аналізував коміти, визначав чи це major/minor/patch, генерував CHANGELOG, відкривав release PR у main. Кастомний скіл проходив по лейблах, створював milestone, готував QA issue, публікував project update — це pre-deploy. Після merge той самий скіл перейменовував лейбли, переводив issues в In Prod, оновлював releases-документ, постив post-deploy update.

Воно працювало. Мінус очевидний: кожна частина — це обхідний шлях. Система несла сенс, якого платформа не бачила. Новачкам потрібен був written runbook, щоб зрозуміти що означає next_ vs current_ vs old_. І єдине місце, де сам деплой відбивався в Linear, — це ручний статус-апдейт, який хтось мав не забути написати.

Що таке Linear Release

Linear Release вводить три примітиви, які стара лейбл-схема апроксимувала вручну:

  • Pipeline — один незалежний стрім релізів. Веб-апп, який шипиться на merge, — один pipeline; iOS-апп на 2-тижневому потязі — інший; нічний dogfood білд — третій. Кожен має власну історію версій і власний access key.
  • Stage — фаза всередині одного релізу на pipeline'і: code freeze, in QA, RC soak. Стейджі — це гейти на тому самому білді, а не окремі стріми.
  • Версія — те, що реально продукує деплой. Її створює CI, а не людина, що вводить значення в лейбл.

Pipeline'и бувають двох типів: continuous (кожен деплой завершає реліз — типово для веб-аппів, що шипляться на merge) і scheduled (релізи збирають зміни, проходять через стейджі, потім шипляться — типово для версіонованого mobile та on-prem). Вибір між ними важливий: неправильний робить модель незручною, правильний — змушує її зникнути.

Сама інтеграція — невеликий action у workflow:

- uses: linear/linear-release-action@v0
  with:
    access-key: ${{ secrets.LINEAR_ACCESS_KEY }}
    command: sync

Все. Action читає коміти, мапить їх на Linear issues, оновлює активний реліз на pipeline'і. Жодних webhook-вигадок, MCP-скриптів і перейменування лейблів.

Кілька слів про Jira

У Jira є fixVersion уже два десятиліття. Те, що Linear доганяє лише зараз, — справедлива критика: трекінг релізів — це release-management 101. Але як саме Linear до цього дійшов — відрізняється так, що це важливо.

Релізний об'єкт у Jira — це запис у каталозі: ти створюєш його заздалегідь, чіпляєш issues, шипиш. Система не знає твого CI. Зв'язок Jira-CI — це той плагін, що ти прикручуєш (Bitbucket, Jenkins, GitLab — вибери свій інтеграційний податок).

Реліз у Linear — це CI-артефакт: action запускається на кожному деплої, версія — те, що каже твоя гілка чи тег, а зв'язок з issues обчислюється з комітів. Каталог тут нижче за течією від деплою, а не вище. Для команд, які реально деплоять кілька разів на тиждень, ця інверсія і робить різницю.

Зворотний бік чесний: якщо твій реліз-процес нерегулярний і керується вручну — модель Jira з каталогом досі відчувається природніше. Linear Release хоче, щоб ти деплоїв з CI.

Як я це налаштовую у себе

У моєму маркетплейс-проєкті це виглядає так. Dispatch-тригернутий release-prepare workflow досі робить version bump + changelog + release PR — це pre-deploy механіка, ортогональна Linear. Що змінилось — те, що відбувається після merge у main.

Vercel auto-deploy досі біжить. Auto-tag і GitHub Release досі створюються. Але тепер другий job у тому ж workflow ще й кличе Linear Release Action. Pipeline — continuous (шипимось на merge), версія береться з package.json, action робить решту: знаходить коміти з останнього релізу, резолвить їх issue keys і завершає реліз на відповідному pipeline'і.

Що залишилось — і це важливо — це шар business update. Linear дає тобі релізи; він не дає тобі stakeholder-зрозумілого опису того, що задеплоїлось. Це досі моя відповідальність — генерувати, але вже зі структурованого release-об'єкта, а не з лейблів.

Ручних операцій з лейблами на реліз

0

Cross-team sync-кроків

0

Додано CI-рядків

~15

Розмір кастомного скіла

-50%

Що це дає

Нудна відповідь — видимість. Цікавіша — видимість для людей, які не сидять у Linear щодня.

Нетехнічні стейкхолдери ставлять три питання: що зашипилось, коли і що далі. До Linear Release ці відповіді жили у трьох різних місцях — лейбли, статус-апдейти, project-документ. Тепер вони на самому релізі: версія, час деплою, issues, стейдж. У кожного релізу є стабільний URL, який можна вкинути куди завгодно.

Для розробки більший виграш — автоматичний зв'язок деплоїв з issues. Якщо хоч раз доводилось вручну переводити 14 issues з "Awaiting Release" у "In Prod" тому що хтось зашипив під час твоєї обідньої перерви — ти знаєш ціну старого підходу. Тепер це робить CI.

Чого ще не вистачає

Дві прогалини помітні.

Перша — Slack-доставка. У Linear є інтеграція зі Slack загалом, але release-сповіщення досі вимагають Zap/workflow, щоб запостити в канал гарне "v1.5.0 щойно вийшов — ось що в ньому". Для фічі, чий весь сенс — нетехнічна видимість, це дивне упущення.

Друга — генерація business update. Release-об'єкт знає список issues, але перетворити це на stakeholder-summary — згрупувати subtasks по parent-фічах, прибрати внутрішні tech-debt items, виділити feature-flagged роботу — це досі кастомна логіка. Тримаю її в скілі. Було б непогано, якби Linear дав template-хук тут.

Третя дрібна претензія — генерація changelog. Action знає коміти, GitHub Release має changelog, але деталь релізу в Linear не показує сам текст changelog прямо. Можна перейти за лінком, але це зайвий клік.

Підсумок

Епоха лейблів-і-груп у релізах Linear була довгим обхідним шляхом до відсутнього примітиву. Кастомний CI і скіли, які я навколо нього збудував, — не дарма: вони кодували знання, які тепер платформа виражає нативно. Але це різниця між тим, щоб пояснювати runbook кожному новому інженеру, і тим, щоб показати пальцем на URL.

Linear Release — не найамбітніша фіча, яку випустили Linear, але та, яку я найменше помічаю. А для релізного менеджменту — це найвищий комплімент, який можна зробити.