docs: Gitea — основной репозиторий и трекер, SourceCraft — зеркало (ADR-010)
Refs #22 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,14 @@
|
|||||||
set -a; . ./.env 2>/dev/null; set +a
|
set -a; . ./.env 2>/dev/null; set +a
|
||||||
```
|
```
|
||||||
|
|
||||||
`SOURCECRAFT_TOKEN` — токен SourceCraft API (секрет — **в чат не печатать**). Репозиторий:
|
Переменные: `GITEA_URL`, `GITEA_TOKEN`, `GITEA_USER`, `GITEA_REPO`, `SOURCECRAFT_TOKEN` (токены — секрет, **в чат не печатать**).
|
||||||
[`rogachevegorushka/tgit`](https://sourcecraft.dev/rogachevegorushka/tgit). API → [`docs/dev/SOURCECRAFT_API.md`](docs/dev/SOURCECRAFT_API.md).
|
|
||||||
|
| Где | Что | Remote |
|
||||||
|
|---|---|---|
|
||||||
|
| [Gitea `HSE/tgit`](https://gitea.24studbank.ru/HSE/tgit) | **основной:** код, issues, PR, ревью | `origin` |
|
||||||
|
| [SourceCraft `rogachevegorushka/tgit`](https://sourcecraft.dev/rogachevegorushka/tgit) | зеркало (push-mirror из Gitea) + CI/CD | `sourcecraft` (только чтение) |
|
||||||
|
|
||||||
|
⛔ В SourceCraft ничего не пушим и не мержим — зеркало перезапишет (ADR-010).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -31,7 +37,7 @@ Telegram-бот (учебный проект НИУ ВШЭ, курс Python): п
|
|||||||
|
|
||||||
## Карта документации
|
## Карта документации
|
||||||
|
|
||||||
> Задачи — в Issues на SourceCraft, не в файлах.
|
> Задачи — в [Gitea Issues](https://gitea.24studbank.ru/HSE/tgit/issues), не в файлах.
|
||||||
|
|
||||||
| Файл | О чём |
|
| Файл | О чём |
|
||||||
|------|-------|
|
|------|-------|
|
||||||
@@ -41,14 +47,15 @@ Telegram-бот (учебный проект НИУ ВШЭ, курс Python): п
|
|||||||
| [`docs/QUESTIONS_IDEAS.md`](docs/QUESTIONS_IDEAS.md) | Открытые вопросы, бэклог идей |
|
| [`docs/QUESTIONS_IDEAS.md`](docs/QUESTIONS_IDEAS.md) | Открытые вопросы, бэклог идей |
|
||||||
| [`docs/dev/WORKFLOW.md`](docs/dev/WORKFLOW.md) | Регламент: ветки, коммиты, PR, жизненный цикл задачи |
|
| [`docs/dev/WORKFLOW.md`](docs/dev/WORKFLOW.md) | Регламент: ветки, коммиты, PR, жизненный цикл задачи |
|
||||||
| [`docs/dev/ISSUE_TEMPLATE.md`](docs/dev/ISSUE_TEMPLATE.md) | Шаблон тела issue |
|
| [`docs/dev/ISSUE_TEMPLATE.md`](docs/dev/ISSUE_TEMPLATE.md) | Шаблон тела issue |
|
||||||
| [`docs/dev/SOURCECRAFT_API.md`](docs/dev/SOURCECRAFT_API.md) | SourceCraft API: curl-шпаргалка (issue, метки, PR) |
|
| [`docs/dev/GITEA_API.md`](docs/dev/GITEA_API.md) | Gitea API: issue, PR, зависимости, зеркало |
|
||||||
|
| [`docs/dev/SOURCECRAFT_API.md`](docs/dev/SOURCECRAFT_API.md) | SourceCraft API: CI-прогоны, логи, секреты |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## TL;DR — работа
|
## TL;DR — работа
|
||||||
|
|
||||||
1. **Задача = Issue.** Нет issue — нет кода.
|
1. **Задача = Issue в Gitea.** Нет issue — нет кода.
|
||||||
2. **Ветка от `dev`:** `<type>/<issue#>-<slug>`. PR в `dev`; `dev → main` — только человек.
|
2. **Ветка от `dev`:** `<type>/<issue#>-<slug>`. PR в `dev` (в Gitea); `dev → main` — только человек.
|
||||||
3. **Гейт зелёный:** lint + тесты перед PR.
|
3. **Гейт зелёный:** lint + тесты перед PR.
|
||||||
4. **Завершил → push + PR** сразу.
|
4. **Завершил → push + PR** сразу.
|
||||||
5. **Лог выполнения** — в issue (`### YYYY-MM-DD`), архитектурные решения — в `DECISIONS.md`.
|
5. **Лог выполнения** — в issue (`### YYYY-MM-DD`), архитектурные решения — в `DECISIONS.md`.
|
||||||
|
|||||||
@@ -10,3 +10,5 @@
|
|||||||
- ТЗ: [`docs/SPEC.md`](docs/SPEC.md)
|
- ТЗ: [`docs/SPEC.md`](docs/SPEC.md)
|
||||||
- Архитектура: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
|
- Архитектура: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
|
||||||
- Как работаем: [`docs/dev/WORKFLOW.md`](docs/dev/WORKFLOW.md)
|
- Как работаем: [`docs/dev/WORKFLOW.md`](docs/dev/WORKFLOW.md)
|
||||||
|
|
||||||
|
Основной репозиторий и задачи — [Gitea `HSE/tgit`](https://gitea.24studbank.ru/HSE/tgit); [SourceCraft](https://sourcecraft.dev/rogachevegorushka/tgit) — зеркало с CI/CD.
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
| Репозиторий | Что внутри | CI/CD |
|
| Репозиторий | Что внутри | CI/CD |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `tgit` | код бота | PR/push `dev`: lint + types + tests; push `main`: + деплой бота на хост |
|
| `tgit` (Gitea → зеркало в SourceCraft) | код бота | push в любую ветку: lint + types + tests; push `main`: + деплой бота на хост |
|
||||||
| `tgit-uploads` | `projects/<name>/…` от пользователей | push `main`: проверки проекта; успех → `ssh tgit-runner deploy <project> <sha>` |
|
| `tgit-uploads` | `projects/<name>/…` от пользователей | push `main`: проверки проекта; успех → `ssh tgit-runner deploy <project> <sha>` |
|
||||||
|
|
||||||
## 2. Компоненты
|
## 2. Компоненты
|
||||||
@@ -142,9 +142,12 @@ docker run -d --name tgit-app-<project> --label tgit.project=<project> --label t
|
|||||||
## 5. CI/CD
|
## 5. CI/CD
|
||||||
|
|
||||||
### 5.1 Репозиторий бота (`tgit/.sourcecraft/ci.yaml`)
|
### 5.1 Репозиторий бота (`tgit/.sourcecraft/ci.yaml`)
|
||||||
|
|
||||||
|
Код живёт в Gitea, SourceCraft получает его push-зеркалом и запускает CI/CD (ADR-010).
|
||||||
|
|
||||||
| Триггер | Workflow | Шаги |
|
| Триггер | Workflow | Шаги |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| PR в `dev`/`main`, push в `dev` | `check` | `uv sync --frozen` → `ruff check` + `ruff format --check` → `mypy app` → `pytest --cov=app --cov-fail-under=70` |
|
| push в любую ветку (через зеркало Gitea; PR живут в Gitea — ADR-010) | `check` | `uv sync --frozen` → `ruff check` + `ruff format --check` → `mypy app` → `pytest --cov=app --cov-fail-under=70` |
|
||||||
| push в `main` | `check` + `deploy` | → `infra/deploy/deploy.sh` по SSH (секреты `DEPLOY_SSH_KEY`, `DEPLOY_HOST`) → smoke: healthcheck контейнера |
|
| push в `main` | `check` + `deploy` | → `infra/deploy/deploy.sh` по SSH (секреты `DEPLOY_SSH_KEY`, `DEPLOY_HOST`) → smoke: healthcheck контейнера |
|
||||||
|
|
||||||
### 5.2 Репозиторий загрузок (`tgit-uploads/.sourcecraft/ci.yaml`)
|
### 5.2 Репозиторий загрузок (`tgit-uploads/.sourcecraft/ci.yaml`)
|
||||||
|
|||||||
+13
-1
@@ -15,7 +15,7 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
## ADR-001: Хостинг кода и задач — SourceCraft
|
## ADR-001: Хостинг кода и задач — SourceCraft
|
||||||
**Дата:** 2026-10-12 · **Статус:** принято
|
**Дата:** 2026-10-12 · **Статус:** заменено ADR-010
|
||||||
|
|
||||||
**Контекст:** нужен репозиторий проекта, трекер задач и CI.
|
**Контекст:** нужен репозиторий проекта, трекер задач и CI.
|
||||||
**Решение:** код бота, issues и CI — на SourceCraft. Загрузки пользователей — в отдельный репозиторий там же.
|
**Решение:** код бота, issues и CI — на SourceCraft. Загрузки пользователей — в отдельный репозиторий там же.
|
||||||
@@ -84,3 +84,15 @@
|
|||||||
**Решение:** Python 3.12, uv, aiogram 3, httpx, pydantic-settings, SQLAlchemy 2 async + Alembic, PostgreSQL 16, `regex`, pytest (+ pytest-asyncio, respx), ruff, mypy. Контейнеризация — Docker Compose.
|
**Решение:** Python 3.12, uv, aiogram 3, httpx, pydantic-settings, SQLAlchemy 2 async + Alembic, PostgreSQL 16, `regex`, pytest (+ pytest-asyncio, respx), ruff, mypy. Контейнеризация — Docker Compose.
|
||||||
**Альтернативы:** python-telegram-bot — синхронное наследие в API; SQLite в проде — проще, но Postgres ближе к реальным сервисам и уже привычен по Vobot/meditron.
|
**Альтернативы:** python-telegram-bot — синхронное наследие в API; SQLite в проде — проще, но Postgres ближе к реальным сервисам и уже привычен по Vobot/meditron.
|
||||||
**Последствия:** тесты на SQLite через тот же SQLAlchemy.
|
**Последствия:** тесты на SQLite через тот же SQLAlchemy.
|
||||||
|
|
||||||
|
## ADR-010: Gitea — основной репозиторий и трекер, SourceCraft — зеркало + CI/CD
|
||||||
|
**Дата:** 2026-10-12 · **Статус:** принято (заменяет ADR-001)
|
||||||
|
|
||||||
|
**Контекст:** веб-интерфейс SourceCraft работает нестабильно и часть функций отображает плохо; API периодически рвёт соединения. При этом CI/CD на SourceCraft — часть постановки преподавателя.
|
||||||
|
**Решение:** код, issues, PR и ревью — в Gitea [`HSE/tgit`](https://gitea.24studbank.ru/HSE/tgit) (как Vobot/meditron). Встроенный push-mirror Gitea синхронизирует репозиторий в SourceCraft на каждый push (+ раз в 8 ч); CI/CD бота и репозиторий загрузок `tgit-uploads` остаются в SourceCraft.
|
||||||
|
**Альтернативы:** только SourceCraft — неудобно работать; только Gitea (Gitea Actions) — уходим от постановки; зеркало по SSH — на этом Gitea SSH-зеркала отключены, поэтому HTTPS + токен SourceCraft.
|
||||||
|
**Последствия:**
|
||||||
|
- В SourceCraft ничего не пушим и не мержим — зеркало перезаписывает его целиком.
|
||||||
|
- Триггер `pull_request` в SourceCraft не срабатывает (PR живут в Gitea) → CI бота запускается на `push` во все ветки.
|
||||||
|
- Токен SourceCraft хранится в настройках зеркала Gitea → нужен отдельный токен с доступом только к `tgit`.
|
||||||
|
- Issues #1–#21 перенесены из SourceCraft с теми же номерами; в SourceCraft закрыты со ссылкой.
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
| Термин | Значение |
|
| Термин | Значение |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Репозиторий бота** | [`rogachevegorushka/tgit`](https://sourcecraft.dev/rogachevegorushka/tgit) — код самого бота |
|
| **Репозиторий бота** | Gitea [`HSE/tgit`](https://gitea.24studbank.ru/HSE/tgit) (основной) → зеркало [`rogachevegorushka/tgit`](https://sourcecraft.dev/rogachevegorushka/tgit) в SourceCraft, где работает CI/CD |
|
||||||
| **Репозиторий загрузок** | `rogachevegorushka/tgit-uploads` — сюда бот коммитит файлы пользователей |
|
| **Репозиторий загрузок** | `rogachevegorushka/tgit-uploads` — сюда бот коммитит файлы пользователей |
|
||||||
| **Проект** | Папка `projects/<name>/` в репозитории загрузок; единица запуска и мониторинга |
|
| **Проект** | Папка `projects/<name>/` в репозитории загрузок; единица запуска и мониторинга |
|
||||||
| **Загрузка** | Один отправленный файл → один коммит |
|
| **Загрузка** | Один отправленный файл → один коммит |
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# Gitea API — шпаргалка
|
||||||
|
|
||||||
|
Gitea — основной репозиторий и трекер: [`HSE/tgit`](https://gitea.24studbank.ru/HSE/tgit). SourceCraft — зеркало (ADR-010).
|
||||||
|
|
||||||
|
> **Кириллица в JSON:** не собирать тело в `curl -d '{...}'` руками — ломается кодировка и экранирование.
|
||||||
|
> Тело собираем в Python (`json.dumps(..., ensure_ascii=False)`) в файл и отправляем `--data @file.json`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -a; . ./.env; set +a # GITEA_URL, GITEA_TOKEN, GITEA_USER, GITEA_REPO
|
||||||
|
G="$GITEA_URL/api/v1/repos/$GITEA_REPO"
|
||||||
|
A="Authorization: token $GITEA_TOKEN"
|
||||||
|
J="Content-Type: application/json; charset=utf-8"
|
||||||
|
alias curl='curl --retry 4 --retry-all-errors --retry-delay 2'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Сервер иногда рвёт SSH (`Connection closed … port 2222`) и медленно отвечает на запись — повторять, перед повторным
|
||||||
|
> POST проверять, не создалась ли сущность.
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# мои открытые
|
||||||
|
curl -s -H "$A" "$G/issues?state=open&type=issues&assigned_by=$GITEA_USER"
|
||||||
|
|
||||||
|
# создать: {"title","body","labels":[id…],"milestone":id,"assignees":["$GITEA_USER"]}
|
||||||
|
curl -s -X POST -H "$A" -H "$J" "$G/issues" --data @issue.json
|
||||||
|
|
||||||
|
# обновить тело / закрыть
|
||||||
|
curl -s -X PATCH -H "$A" -H "$J" "$G/issues/NN" --data @body.json # {"body": "..."}
|
||||||
|
curl -s -X PATCH -H "$A" -H "$J" "$G/issues/NN" -d '{"state":"closed"}'
|
||||||
|
|
||||||
|
# комментарий
|
||||||
|
curl -s -X POST -H "$A" -H "$J" "$G/issues/NN/comments" --data @comment.json # {"body": "..."}
|
||||||
|
|
||||||
|
# метки и вехи — по id
|
||||||
|
curl -s -H "$A" "$G/labels"
|
||||||
|
curl -s -H "$A" "$G/milestones?state=all"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Зависимости (только через API, не текстом в теле)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# #NN зависит от #MM (MM блокирует NN)
|
||||||
|
curl -s -X POST -H "$A" -H "$J" "$G/issues/NN/dependencies" -d "{\"owner\":\"${GITEA_REPO%%/*}\",\"repo\":\"${GITEA_REPO##*/}\",\"index\":MM}"
|
||||||
|
curl -s -H "$A" "$G/issues/NN/dependencies"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pull requests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# PR в dev (не в main!); тело — с "Closes #NN"
|
||||||
|
curl -s -X POST -H "$A" -H "$J" "$G/pulls" --data @pr.json # {"head":"feat/NN-slug","base":"dev","title":"…","body":"…"}
|
||||||
|
|
||||||
|
# ветка ещё есть? пусто → PR смержен, не пушить
|
||||||
|
git ls-remote --heads origin <ветка>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Зеркало в SourceCraft
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s -H "$A" "$G/push_mirrors" # статус: last_update, last_error
|
||||||
|
curl -s -X POST -H "$A" "$G/push_mirrors-sync" # синхронизировать сейчас
|
||||||
|
```
|
||||||
|
|
||||||
|
Зеркало — HTTPS (`git.sourcecraft.dev`) с токеном SourceCraft: SSH-зеркала на этом Gitea отключены.
|
||||||
|
Синхронизация — на каждый push + раз в 8 часов. Зеркало перезаписывает SourceCraft целиком (`--mirror`):
|
||||||
|
**в SourceCraft ничего не пушим и не мержим** — изменения пропадут.
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
# SourceCraft API — шпаргалка
|
# SourceCraft API — шпаргалка
|
||||||
|
|
||||||
|
> Issues и PR ведём в Gitea ([`GITEA_API.md`](GITEA_API.md), ADR-010). Здесь нужны в основном CI-прогоны, логи и секреты;
|
||||||
|
> разделы про issues/метки/PR — справочно (бот и скрипты могут работать с `tgit-uploads`).
|
||||||
|
|
||||||
Справочник: [методы](https://sourcecraft.dev/portal/docs/en/api-ref/index.md) ·
|
Справочник: [методы](https://sourcecraft.dev/portal/docs/en/api-ref/index.md) ·
|
||||||
[интерактивный](https://api.sourcecraft.tech/docs/index.html) ·
|
[интерактивный](https://api.sourcecraft.tech/docs/index.html) ·
|
||||||
[swagger.json](https://api.sourcecraft.tech/sourcecraft.swagger.json)
|
[swagger.json](https://api.sourcecraft.tech/sourcecraft.swagger.json)
|
||||||
|
|||||||
+13
-1
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
## Откуда задачи
|
## Откуда задачи
|
||||||
|
|
||||||
- Только из Issues на SourceCraft. Нет issue → завести → потом код. API: [`SOURCECRAFT_API.md`](SOURCECRAFT_API.md).
|
- Только из [Gitea Issues](https://gitea.24studbank.ru/HSE/tgit/issues). Нет issue → завести → потом код. API: [`GITEA_API.md`](GITEA_API.md).
|
||||||
|
- Зависимости между issue — через API Gitea, не текстом в теле.
|
||||||
- Атрибуты issue: исполнитель, метка зоны (`bot` / `ci` / `infra` / `llm` / `docs`),
|
- Атрибуты issue: исполнитель, метка зоны (`bot` / `ci` / `infra` / `llm` / `docs`),
|
||||||
тип (`feature` / `fix` / `refactor` / `docs`), размер (`size/0.5` ≈ 2ч · `size/1` ≈ 4ч · `size/2` ≈ 1д).
|
тип (`feature` / `fix` / `refactor` / `docs`), размер (`size/0.5` ≈ 2ч · `size/1` ≈ 4ч · `size/2` ≈ 1д).
|
||||||
- Тело — по [`ISSUE_TEMPLATE.md`](ISSUE_TEMPLATE.md).
|
- Тело — по [`ISSUE_TEMPLATE.md`](ISSUE_TEMPLATE.md).
|
||||||
@@ -20,6 +21,17 @@
|
|||||||
8. Мерж → ветку удалить
|
8. Мерж → ветку удалить
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Репозитории
|
||||||
|
|
||||||
|
```
|
||||||
|
Gitea HSE/tgit (origin) ──push-mirror (на каждый push)──► SourceCraft rogachevegorushka/tgit
|
||||||
|
код · issues · PR · ревью CI/CD (.sourcecraft/ci.yaml)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Работаем только с `origin` (Gitea). Remote `sourcecraft` — для чтения/сверки.
|
||||||
|
- ⛔ В SourceCraft не пушим, не мержим, PR не открываем: зеркало перезаписывает его целиком.
|
||||||
|
- CI SourceCraft запускается пушем зеркала; результат смотрим там же (ссылка — в PR вручную или через бота, когда будет).
|
||||||
|
|
||||||
## Ветки
|
## Ветки
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user