# Git-flow: ветки, теги и автодеплой

Единый процесс для репозиториев приложений в Gitea:

| Репозиторий Gitea | Локальная папка | CI по тегам |
|-------------------|-----------------|-------------|
| `sova/backend` | `sova-backend/` | да |
| `sova/adminpanel` | `sova-adminpanel/` | да |
| `sova/cabinet` | `sova-cabinet/` | да |
| `sova/docs` | `sova-docs/` | да |
| `sova/sova-mocks` | `sova-mocks/` | нет (Helm chart, ArgoCD sync) |

`sova/sova-deploy` — GitOps-репозиторий: CI пишет в **`main`**, ArgoCD читает `values-{env}.yaml`. Отдельные ветки prod/test/stage для deploy **не нужны**.

---

## Глоссарий веток

| Ветка | Назначение | Откуда создаём feature | Куда мержим задачу |
|-------|------------|------------------------|-------------------|
| **`prod`** | Актуальный продакшн-код (бывш. `main`/`master`) | — | После успешного stage-тестирования: **stage → prod** |
| **`test`** | Test-контур (k3s песочница) | feature от **`prod`** | После code review задачи |
| **`stage`** | Stage-контур (регресс / нагрузка) | feature от **`prod`** | После успешного test QA |

**Правило:** feature-ветки **всегда** ответвляются от `prod`, не от `test` и не от `stage`.

```mermaid
flowchart TB
  prod([prod])
  test([test])
  stage([stage])
  feat[feature/TASK-123]

  prod -->|ветка от prod| feat
  feat -->|PR merge| test
  feat -->|PR merge — не test| stage
  stage -->|release PR| prod
```

### ⚠️ Частая ошибка

**Нельзя** мержить ветку `test` в `stage`. В `test` могут лежать чужие незавершённые задачи — они «прицепом» уедут на stage.

**Правильно:** мержить **конкретную feature-ветку** (которая прошла test) в `stage`.

---

## Формат тегов (без изменений)

```
{component}-v{semver}-{env}
```

| Суффикс `env` | Контур | Пример |
|---------------|--------|--------|
| `test` | Test (k3s) | `backend-v1.0.2-test` |
| `stage` | Stage (будущее) | `backend-v1.0.2-stage` |
| `prod` | Production (будущее) | `backend-v1.0.2-prod` |

Компоненты: `backend`, `adminpanel`, `cabinet`, `docs`.

Тег создаётся **на ветке с тем же именем**, что и суффикс env:

- тег `backend-v1.0.2-test` → ветка **`test`**
- тег `backend-v1.0.2-stage` → ветка **`stage`**
- тег `backend-v1.0.2-prod` → ветка **`prod`**

CI парсит суффикс и обновляет `sova-deploy/apps/{app}/values-{env}.yaml` → ArgoCD sync.

Подробнее: [Система тегов CI/CD](./tags.md).

---

## Жизненный цикл задачи (пошагово)

### 1. Разработка

```bash
git checkout prod
git pull origin prod
git checkout -b feature/SOVA-123-add-widget
# ... commits ...
git push origin feature/SOVA-123-add-widget
```

### 2. Code review → test

1. В Gitea: **Pull Request** `feature/SOVA-123-add-widget` → **`test`**
2. Review, approve, merge
3. **Создать тег на ветке `test`** → автодеплой на test-контур (см. ниже)

### 3. QA на test

Тестировщик проверяет на test-URL (например http://api.test.sova.local).

### 4. Промоушен на stage

1. **Pull Request** `feature/SOVA-123-add-widget` → **`stage`** (не `test` → `stage`!)
2. Merge после approve
3. **Тег на ветке `stage`**, например `backend-v1.0.2-stage`
4. Регресс / нагрузочное тестирование на stage-контуре *(контур — в планах)*

### 5. Релиз в prod

1. Когда все задачи в `stage` проверены: **Pull Request** `stage` → **`prod`**
2. Merge (минимум 1 approval на `prod`)
3. **Тег на ветке `prod`**, например `backend-v1.0.2-prod`
4. Деплой на production *(контур — в планах)*

---

## Как создать тег в Gitea (UI)

Пример: выкатить backend `v1.0.2` на **test** после merge PR в `test`.

### Способ A — Releases (рекомендуется)

1. Откройте http://git.sova.local/sova/backend
2. **Releases** → **New Release**
3. **Tag name:** `backend-v1.0.2-test`
4. **Target branch:** выберите **`test`** (не prod!)
5. **Release title:** `Test release 1.0.2` (произвольно)
6. **Publish Release**

Gitea создаст тег и отправит push → запустится workflow **backend-ci-cd**.

### Способ B — Create tag на ветке

1. **Code** → выпадающий список веток → **`test`**
2. Коммит, который нужно выкатить → **⋯** → **Create tag**
3. **Tag name:** `backend-v1.0.2-test`
4. **Create**

### Способ C — CLI (локально)

```bash
cd k3s-test
./scripts/release-tag.sh backend backend-v1.0.2-test
# checkout test, tag, push — автоматически
```

### Проверка после тега

1. http://git.sova.local/sova/backend/actions — jobs **success**
2. http://argocd.sova.local — `backend-test` **Synced**
3. `kubectl get deploy backend -n sova-test` — образ `git.sova.local/sova/backend:backend-v1.0.2-test`

---

## Пример полного flow (backend, задача SOVA-123)

| Шаг | Действие | Gitea / CLI |
|-----|----------|-------------|
| 1 | Ветка от prod | `git checkout -b feature/SOVA-123 prod` |
| 2 | PR → test | UI: New Pull Request → base: **test** |
| 3 | Merge PR | Merge Pull Request |
| 4 | Тег test | Release: `backend-v1.0.2-test` на ветке **test** |
| 5 | QA OK | — |
| 6 | PR → stage | UI: feature/SOVA-123 → base: **stage** |
| 7 | Тег stage | `backend-v1.0.2-stage` на ветке **stage** |
| 8 | Регресс OK | — |
| 9 | PR stage → prod | UI: base: **prod** |
| 10 | Тег prod | `backend-v1.0.2-prod` на ветке **prod** |

---

## Hotfix (срочный фикс в prod)

1. Ветка от **`prod`:** `hotfix/SOVA-999-critical`
2. Fix → PR → **`test`** → тег `*-test` → быстрая проверка
3. PR **`hotfix/SOVA-999`** → **`stage`** → тег `*-stage` *(или skip stage для critical — по решению лида)*
4. PR **`hotfix/SOVA-999`** → **`prod`** → тег `*-prod`
5. **Back-merge:** PR `prod` → `stage` и `prod` → `test`, чтобы ветки не разъехались

Hotfix **не** мержится через `test` → `stage` целиком — только своя ветка.

---

## Защита веток (Branch Protection)

Настроено скриптом `./scripts/setup-gitea-branch-protection.sh`:

| Ветка | Direct push | Merge | Approvals |
|-------|-------------|-------|-----------|
| `prod` | запрещён | через PR | 1 |
| `stage` | запрещён | через PR | 0 |
| `test` | запрещён | через PR | 0 |

Изменения попадают в `prod` / `stage` / `test` **только через Pull Request**.

---

## CI/CD по контурам

### Test — **работает сейчас**

| Триггер | Тег `*-test` на ветке `test` |
| Pipeline | test → build-and-push → deploy-gitops |
| GitOps | `apps/{app}/values-test.yaml` в `sova-deploy` |
| ArgoCD | `backend-test`, `cabinet-test`, … |
| URLs | `*.test.sova.local`, `docs.sova.local` |

Bootstrap веток (один раз):

```bash
./scripts/setup-git-flow-branches.sh
./scripts/setup-gitea-branch-protection.sh
```

### Stage — **описано, внедрение позже**

| План | |
|------|---|
| Триггер | Тег `*-stage` на ветке `stage` |
| GitOps | `values-stage.yaml` (заготовки уже в `sova-deploy`) |
| ArgoCD | `backend-stage`, `cabinet-stage`, … *(Applications не созданы)* |
| Namespace | `sova-stage` |
| Ingress | `*.stage.sova.local` |
| Кластер | отдельная VM / namespace group |

CI **уже поддерживает** суффикс `-stage` — достаточно поднять stage-кластер и ArgoCD apps.

### Prod — **описано, внедрение позже**

| План | |
|------|---|
| Триггер | Тег `*-prod` на ветке `prod` |
| GitOps | `values-prod.yaml` *(создать при внедрении)* |
| ArgoCD | `backend-prod`, … + RBAC |
| Secrets | SealedSecrets / external secrets |
| Ingress | боевые домены |

---

## sova-mocks

Репозиторий `sova-mocks` участвует в git-flow (**ветки prod/test/stage**), но **без tag CI**.

Обновление моков на test-контуре:

1. PR изменений → `test`
2. ArgoCD app `mocks-test` следит за `sova-mocks` **`main`** сегодня — при миграции на ветки: `targetRevision: test`
3. Sync в ArgoCD UI или автосync

---

## Первичная настройка (админ)

```bash
cd k3s-test

# 1. Ветки prod / test / stage во всех app-репах
./scripts/setup-git-flow-branches.sh

# 2. Branch protection
./scripts/setup-gitea-branch-protection.sh

# 3. CI secrets (если ещё не делали)
./scripts/bootstrap-gitea-ci-secrets.sh
./scripts/configure-k3s-registry.sh

# 4. Пример релиза на test
./scripts/release-tag.sh backend backend-v1.0.1-test
```

После `setup-git-flow-branches.sh` default branch в Gitea = **`prod`**, legacy **`main`** удаляется с remote.

---

## Связанные документы

- [Система тегов CI/CD](./tags.md)
- [Gitea: теги и CI/CD (скриншоты)](./guides/gitea-ci.md)
- [ArgoCD: приложения test-контура](./guides/argocd.md)
