Files
coopops 532e34c53b
Typecheck / desktop (pull_request) Has been cancelled
Typecheck / controller (pull_request) Has been cancelled
ci(release): promote по умолчанию шлёт текущий HEAD (не последний тег)
Дефолт promote.sh — текущий HEAD чекаута; второй аргумент по-прежнему задаёт явный
ref (ветка/тег/sha). Типичный путь: cut на dev → promote testnet → promote main,
все три от того же HEAD. testnet/main остаются независимыми FF-указателями.

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

6.5 KiB
Raw Permalink Blame History

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

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

Как релизить (типичный путь)

# стоишь на dev
pnpm run cut          # бамп версии lerna + тег + push dev (деплой НЕ запускает)
pnpm run testnet      # текущий HEAD (= свежий cut) → testnet (staging), деплой пошёл
pnpm run production   # тот же HEAD → main (production), деплой пошёл

promote по умолчанию шлёт текущий HEAD в указанный контур, поэтому после cut оба промоута идут «оттуда же» (с dev). Контуры независимы — можно гнать прод и тест разным темпом:

scripts/promote.sh main v2026.6.16     # конкретную версию (тег) в прод
scripts/promote.sh main testnet        # ровно то, что сейчас на testnet, в прод
# на другой ветке: promote main → улетит HEAD этой ветки (FF-гард не пустит, если
# 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: по умолчанию HEAD, иначе указанный ветка/тег/sha. Рабочее дерево не трогается. Только вперёд (FF). Деплой стартует только если в улетающем коммите есть бамп lerna.json, которого ещё нет в целевой ветке — то есть нужен свежий cut.

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

.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-указатели на теги одной линии.