From 83ff76b0f4bfab6582c73650aec9de973691f06d Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sat, 17 Oct 2026 14:03:51 +0300 Subject: [PATCH] chore: adopt linear git model in backend docs (#111) --- .ai/conventions/engineering.md | 7 ++++- README.md | 50 ++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/.ai/conventions/engineering.md b/.ai/conventions/engineering.md index 4c641a7..69ecdb4 100644 --- a/.ai/conventions/engineering.md +++ b/.ai/conventions/engineering.md @@ -89,4 +89,9 @@ Commits и PR titles — Conventional Commits с parser-recognized Issue referen `spec:`. Каждый commit содержит одну задачу. Исключения release и правила ссылки — в Engineering Workflow из AGENTS. Root другого checkout не управляет этим repo. Прямой push в `main`, force-push и перенос опубликованных тегов не входят в -обычную работу. Перед release/hotfix прочитай местный README, раздел «Релизы». +обычную работу. PR сливается squash или rebase-merge; merge-коммит не +используется. `main` обновляется только fast-forward из `develop`, поэтому +`origin/main` всегда предок `origin/develop`: +`git merge-base --is-ancestor origin/main origin/develop`. Срочный fix — +обычная ветка `fix/*` от `develop`; пути hotfix от `main` нет. +Перед релизом прочитай местный README, раздел «Релизы». diff --git a/README.md b/README.md index 622b183..73dd653 100644 --- a/README.md +++ b/README.md @@ -307,35 +307,57 @@ Durability оставляет временные DB, логи и `result.json` Репозиторий выпускается независимо. `develop` — интеграция, `main` — принятые релизы. Обычная работа: issue-linked ветка от актуального `develop`, PR в `develop`; общие правила — в Engineering Workflow по ссылке из AGENTS. -Обычные PR допускают squash; release и обратная синхронизация сохраняют историю. +PR сливается squash или rebase-merge; merge-коммит не используется. `main` +обновляется только fast-forward из `develop`, поэтому история линейна: + +```text +/- --squash--> develop --ff-only--> main --> tag vX.Y.Z +``` + +Инвариант: `origin/main` всегда предок `origin/develop`. Проверка: + +```bash +git fetch -q origin +git merge-base --is-ancestor origin/main origin/develop && echo ok || echo BROKEN +``` + Commits и PR titles — Conventional Commits со ссылкой на Issue (кроме release), включая `spec:`. Версии вручную не повышай. -1. Получи `main`, `develop` и теги: `git fetch origin --tags`. Убедись, что - `develop` содержит последний релиз. Создай `release/` от проверенного - `develop`; `nvm use --silent`, `npm ci`. Hotfix начинается от `main` в - `release/hotfix-` и проходит тот же процесс. +1. Получи `main`, `develop` и теги: `git fetch origin --tags`. Проверь + инвариант. Создай `release/X.Y.Z` от проверенного `develop`; + `nvm use --silent`, `npm ci`. 2. На чистой ветке выполни `npm run release:preview`, просмотри версию/changelog, затем `npm run release:prepare`. Команда создаёт `chore(release): X.Y.Z`, обновляет manifest/lockfile/CHANGELOG; тег и push не выполняет. Не обходи guards ветки, чистого дерева, отсутствующих тегов или уже подготовленной версии. 3. Проверь diff и штатные gates этого репозитория. Отправь только release-ветку, - открой PR в `main` с заголовком `chore(release): X.Y.Z`. После зелёных - `verify`, `security`, `commits` выполни fast-forward-only merge. Если `main` - изменился, согласуй историю и повтори проверки кандидата. -4. Получи удалённый `main`, сравни его HEAD с проверенным release SHA и версией + открой PR в **`develop`** с заголовком `chore(release): X.Y.Z`. После зелёных + `verify`, `security`, `commits` выполни fast-forward-only merge. Если + `develop` изменился, обнови release-ветку и повтори проверки кандидата. +4. Открой PR `develop → main` с тем же заголовком и слей fast-forward-only. +5. Получи удалённый `main`, сравни его HEAD с проверенным release SHA и версией manifest/lockfile. Создай аннотированный `vX.Y.Z` именно на этом SHA: `git tag -a vX.Y.Z -m "Release X.Y.Z"`, затем отправь только `git push origin refs/tags/vX.Y.Z`. Не запускай release-it повторно на `main`. -5. Верни release-коммит через PR `main → develop` без squash/rebase; проверь, - что `develop` содержит тег. Опубликованные теги не перемещай. При сбое после - merge создай отсутствующий тег без нового bump; до merge исправь и проверь - существующий кандидат без повторного повышения версии. +Обратная синхронизация не нужна: release-коммит попал в `develop` на шаге 3. +Опубликованные теги не перемещай. При сбое после merge создай отсутствующий тег +без нового bump; до merge исправь и проверь существующий кандидат без +повторного повышения версии. + +Freeze релиза не поддерживается: пока открыт релизный PR, `develop` не двигают. +Срочный fix — обычная ветка `fix/*` от `develop` с последующим релизом; +пути от `main` нет, он сделал бы `main` не-предком `develop`. Исключение +требует явного решения: `release/hotfix-` от `main`, PR в `main`, тег, +затем merge `main → develop` для восстановления инварианта. `feat:` повышает minor, `fix:`/`perf:` и прочие разрешённые типы — patch; `!`/`BREAKING CHANGE:` — major, включая версии до 1.0. `chore(release):` исключён из рекомендации и changelog. Конфигурация — `.release-it.json`. В Gitea для `main`/`develop` должны быть запрещены прямой/force push и обход -администратором, обязательны `verify`, `security`, `commits`; теги `v*` защищены. +администратором, включена блокировка устаревшей ветки, обязательны `verify`, +`security`, `commits`; теги `v*` защищены. Линейность обеспечивают merge styles +репозитория: merge-коммиты и rebase `--no-ff` выключены, доступны squash, +rebase-merge и fast-forward-only; стиль по умолчанию — squash. Workflow сам не включает эти настройки. Отдельное review approval для одного владельца не требуется. Npm publishing, deploy и Gitea Releases не включены. -- 2.54.0