532e34c53b
Дефолт 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>
87 lines
6.5 KiB
Markdown
87 lines
6.5 KiB
Markdown
# Релизный флоу: независимый деплой окружений (FF-указатели на теги dev)
|
||
|
||
Линейная модель без merge и без конфликтов. Версию бампает `lerna` **один раз на
|
||
`dev`** (вешает тег `vYYYY.M.D`), и дальше каждое окружение — **самостоятельный
|
||
fast-forward-указатель** на выбранный релизный тег. `testnet` и `main` не несут
|
||
собственных коммитов и не образуют паровоз: это два независимых указателя на
|
||
ЛИНЕЙНУЮ историю `dev`, поэтому ветки не диверджатся и merge-конфликтов не бывает,
|
||
**и при этом прод и тест можно катить разным темпом и на разные версии
|
||
одновременно**.
|
||
|
||
## Как релизить (типичный путь)
|
||
|
||
```bash
|
||
# стоишь на dev
|
||
pnpm run cut # бамп версии lerna + тег + push dev (деплой НЕ запускает)
|
||
pnpm run testnet # текущий HEAD (= свежий cut) → testnet (staging), деплой пошёл
|
||
pnpm run production # тот же HEAD → main (production), деплой пошёл
|
||
```
|
||
|
||
`promote` по умолчанию шлёт **текущий HEAD** в указанный контур, поэтому после
|
||
`cut` оба промоута идут «оттуда же» (с dev). Контуры независимы — можно гнать
|
||
прод и тест разным темпом:
|
||
|
||
```bash
|
||
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-указатели на теги одной линии.
|