Files
mono/scripts/RELEASE.md
T
coopops 9c2729d243
Typecheck / desktop (pull_request) Successful in 13m58s
Typecheck / controller (pull_request) Successful in 13m15s
ci(release): независимый деплой окружений — testnet/main как FF-указатели на теги dev
Паровоз dev→testnet→main заменён независимыми указателями: каждое окружение —
самостоятельный fast-forward-указатель на выбранный релизный тег dev. Прод и тест
катятся разным темпом и на разные версии одновременно, без диверджа и конфликтов
(оба — FF-указатели на линейную историю dev).

- promote.sh <testnet|main> [ref]: FF выбранного тега (по умолчанию — последний на
  origin/dev) на ветку окружения; main больше не зависит от testnet; только вперёд.
- release.yaml: workflow_dispatch получил inputs environment+ref — откат на старую
  версию / редеплой без бампа / hotfix в один контур (то, что FF не умеет). Сборка
  идёт из вычекнутого ref, окружение — из inputs.environment. Авто-триггер по
  изменению lerna.json сохранён.
- RELEASE.md: модель и инварианты переписаны под независимые указатели.

Принципы деплоя сохранены: бамп версии один раз на dev, образы по версии,
BUILD_MODE по окружению, webhooks per env, npm publish/доки только на main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 06:49:12 +00:00

6.5 KiB
Raw Blame History

Релизный флоу: независимый деплой окружений (FF-указатели на теги dev)

Линейная модель без merge и без конфликтов. Версию бампает lerna один раз на dev (вешает тег vYYYY.M.D), и дальше каждое окружение — самостоятельный fast-forward-указатель на выбранный релизный тег. testnet и main не несут собственных коммитов и не образуют паровоз: это два независимых указателя на ЛИНЕЙНУЮ историю dev, поэтому ветки не диверджатся и merge-конфликтов не бывает, и при этом прод и тест можно катить разным темпом и на разные версии одновременно.

Как релизить

# 1. Нарезать релиз на dev (бамп версии lerna + тег, БЕЗ деплоя)
pnpm run cut                       # = scripts/cut-release.sh

# 2. Выкатить в окружения — НЕЗАВИСИМО, в любом порядке и темпе
pnpm run testnet                   # последний тег → testnet (staging)
pnpm run production                # последний тег → main    (production)

# Точечно: конкретную версию в конкретный контур
scripts/promote.sh main v2026.6.16     # эту версию в прод
scripts/promote.sh main testnet        # ровно то, что сейчас на testnet, в прод

Рекомендуемая практика (не обязательная): сначала promote.sh testnet, проверить на staging, затем promote.sh main <та же версия>. Это уже не топологический гард (как в старом паровозе), а ваш процесс — контуры независимы.

  • cut-release.sh — строго на dev. Считает версию vYYYY.M.D (повторный релиз того же дня → суффикс -N), вызывает lerna version (бамп всех package.json + lerna.json, коммит chore(release): publish, тег, push dev). Деплой не запускает — CI не слушает dev.
  • promote.sh <testnet|main> [<версия|ref>] — server-side fast-forward push выбранного релизного тега на ветку окружения. REF по умолчанию — последний тег на линии origin/dev. Рабочее дерево не трогается. Только вперёд (FF).

Что триггерит деплой

.github/workflows/release.yaml:

  1. Авто — push в testnet/main с изменением lerna.json. lerna.json меняется только при релизном бампе (на dev), и этот коммит входит в диапазон FF-промоушна — поэтому деплоятся именно релизы, а не обычные feature-пуши. Это путь promote.sh.
  2. Ручной (workflow_dispatch) — выбрать environment (testnet/main) и опционально ref (тег/коммит). Для того, что FF не умеет: откат на старую версию, редеплой без бампа, hotfix в один контур. Запуск — кнопкой в Gitea (Actions → Release → Run workflow) или через tea/API.

Окружение определяет выбранный контур (ветка push'а или inputs.environment), не суффикс версии:

Контур Окружение Деплой-webhook npm publish / доки
testnet staging TESTNET_WEBHOOK_URL нет
main production PRODUCTION_WEBHOOK_URL да (main)

Версия для образов (dicoop/*:vX), webhook-payload и lerna publish from-package читается из закоммиченного lerna.json вычекнутого дерева — она «приезжает» с тегом. Для приёмника деплоя (playbooks) ничего не меняется.

Инварианты (не нарушать)

  • В testnet/main — только FF на тег dev, никаких прямых коммитов. Прямой коммит сделает ветку не-FF; promote.sh тогда отвергнется push'ем (гард, не баг — выровняй ветку на нужный тег).
  • Версия бампается только на dev (cut-release.sh). Никаких повторных бампов на testnet/main — иначе вернутся расхождение и конфликты.
  • promote.sh двигает только вперёд. Откат назад на старую версию — через workflow_dispatch (environment + ref), а не force-push ветки окружения.
  • Тег (vX) — маркер версии и основа для GitHub Release (scripts/publish-release.sh); сам по себе триггером деплоя он не является.

Откуда ушли (история)

  • Старые publish-alpha.sh/publish-prod.sh бампали версию на каждой ветке через git merge -X theirs + back-merge → два бампа за цикл плодили расхождение и 20 конфликтов package.json. FF-модель это устранила конструктивно.
  • Затем был паровоз dev → testnet → main: один тег ехал строго линейно, main мог получить только то, что уже на testnet. Безопасно, но неудобно — нельзя катить прод и тест разным темпом, нет независимого отката/hotfix. Заменён на независимые указатели: main промоутится из dev (а не из testnet), оба контура — самостоятельные FF-указатели на теги одной линии.