# DEV TASK — добавить Gitea Actions CI workflow для orchestrator (закрыть дыру self-hosting) **Проект:** orchestrator | **Сервер:** slin@82.22.50.71 | **Репо (хост):** /home/slin/repos/orchestrator | **Контейнер:** orchestrator (порт 8500) **Ветка:** `ci/add-gitea-workflow` из свежего main (`git fetch origin main && git checkout -B ci/add-gitea-workflow origin/main`). ## Контекст / зачем Оркестратор готовится пилить **сам себя** через свой конвейер (ORCH-7 self-hosting). Гейт `development → review` опирается на `check_ci_green` (читает статус Gitea Actions через webhook). У проекта **enduro-trails** есть `.gitea/workflows/ci.yml` (540 успешных прогонов, lint/test/build), а у **orchestrator** — НЕТ ни одного workflow (`workflow_runs total: 0`). Значит для задач самого оркестратора CI-гейт **отсутствует** → задача либо застрянет на development, либо пройдёт без проверки тестами. Это главный блокер self-hosting. Нужно добавить orchestrator свой `.gitea/workflows/ci.yml` — по образцу enduro, но адаптированный под структуру orchestrator (нет pyproject/.[dev], зависимости в requirements.txt + pytest уже там). ## ФАКТЫ окружения (проверены, НЕ перепроверять заново) - Тесты: 24 файла в `tests/*.py`, запускаются `pytest`. conftest.py глушит Telegram (autouse) — тесты безопасны, реальных сообщений не шлют. - Зависимости: `requirements.txt` (fastapi, uvicorn[standard], pydantic-settings, httpx, pytest==8.3.3). `PYTHONPATH=/app` в рантайме; в CI запускать из корня репо с `PYTHONPATH=.`. - НЕТ `pyproject.toml`, `setup.py`, `Makefile`, ruff-конфига. **Lint опционален** — см. ниже. - act_runner: systemd-сервис на хосте, label **`self-hosted:host`** (тот же, что у enduro). Workflow ДОЛЖЕН использовать `runs-on: self-hosted`. - Ветки задач orchestrator: `feature/ORCH-N-slug` (создаются в plane.py:473). Триггер `feature/**` их ловит. - Эталон триггера enduro: `on: push branches [feature/**, bugfix/**, hotfix/**]` + `pull_request branches [main]`. ## Что сделать — ОДИН новый файл ### `.gitea/workflows/ci.yml` (создать) ```yaml name: CI on: push: branches: ["feature/**", "bugfix/**", "hotfix/**", "fix/**", "ci/**"] pull_request: branches: [main] jobs: test: runs-on: self-hosted steps: - uses: actions/checkout@v4 - name: Install dependencies run: | python3 -m pip install --user --upgrade pip python3 -m pip install --user -r requirements.txt - name: Test env: PYTHONPATH: ${{ github.workspace }} run: | export PATH="$HOME/.local/bin:$PATH" python3 -m pytest tests/ -q ``` ### Замечания по реализации (важно, грабли) - **runs-on: self-hosted** — обязательно (label раннера `self-hosted:host`). НЕ `ubuntu-latest` (это docker-образ node, не подходит для python-тестов так же удобно). - Добавила `fix/**` и `ci/**` в push-триггеры (у orchestrator реальные ветки правок именно `fix/...`, в отличие от enduro), чтобы CI гонялся и на этой ветке тоже — проверишь, что workflow сам себя прогонит. - Если pytest требует доп. модули, которых нет в requirements.txt (проверь `python3 -m pytest tests/ -q` локально в чистом venv ИЛИ через `docker run --rm`): НЕ добавляй их вслепую — сначала установи список фактически нужного и добавь РОВНО недостающее в requirements.txt отдельным минимальным изменением, упомяни в PR. - **Lint-job НЕ добавляй** (нет ruff-конфига, добавление линта — отдельная задача, чтобы не плодить ложные провалы). Только `test`-job. - НЕ трогай Dockerfile, src/, stages.py, qg/checks.py, gitea.py — только новый workflow-файл. ## Проверка (выполнить и приложить в отчёт) 1. Локально тесты зелёные перед push: `docker run --rm -v /home/slin/repos/orchestrator:/code -w /code -e PYTHONPATH=/code --entrypoint python3 $(docker inspect orchestrator --format '{{.Config.Image}}') -m pytest tests/ -q` — должно быть **все passed** (учти 9 off-limits HMAC/401-тестов — они должны проходить как и раньше; если их окружение требует переменных, зафиксируй, НЕ меняй сами тесты). 2. После push ветки `ci/add-gitea-workflow`: убедись, что Gitea Actions запустил workflow: ``` docker exec orchestrator python3 -c "import os,json,urllib.request; \ r=urllib.request.Request('http://localhost:3000/api/v1/repos/admin/orchestrator/actions/tasks', \ headers={'Authorization':'token '+os.environ['ORCH_GITEA_TOKEN']}); \ d=json.load(urllib.request.urlopen(r,timeout=15)); print('runs:',d['total_count']); \ [print(x['name'],x['status'],x['conclusion']) for x in d['workflow_runs'][:3]]" ``` — `total_count` должен стать > 0, job `test` → `success`. 3. `git log origin/main..origin/ci/add-gitea-workflow` показывает коммит ДО отчёта «PR готов». ## Ограничения / правила - ⚠️ **PR в Gitea, push в main ЗАПРЕЩЁН** (pre-receive hook). Dev НЕ мержит сам — мержит ревьюер (Стрим). - Conventional Commits, один коммит: `ci: add Gitea Actions workflow (pytest) for orchestrator self-hosting`. - Токен Gitea: `docker exec orchestrator printenv ORCH_GITEA_TOKEN`. - НЕ трогать off-limits тесты (9 HMAC/401), check_reviewer_verdict, check_deploy_status, merge-gate, PLANE_STATES, queue, stages.py mapping. - Если что-то в фактах ТЗ разошлось с реальностью — СТОП, отчёт с вопросом, не импровизируй. ## Результат - PR с одним файлом `.gitea/workflows/ci.yml`, workflow реально прогнался на ветке (job test = success), отчёт с пруфом (total_count > 0 + conclusion success).