ci(forgejo): add pytest gate for the main backend suite (CI-rehab 3/3)
Forgejo runs only .forgejo/workflows/* — the .github pytest gate never executed here, so backend changes merged + deployed untested (live bug #994 district 500 shipped uncaught). Add a real gate: ruff check + the full backend pytest suite (1687 passed) on PRs to main and feature-branch pushes, scoped to backend/** + data/sql/** via paths-filter. Mock-only lane (no postgres service): the one real-DB test self-skips via a connectivity probe; WeasyPrint PDF tests RUN thanks to installed libpango. uv via official installer (not setup-uv, PEP 668), uv sync --frozen against the committed lock, TESTING=1 to activate the test-mode RBAC bypass. NOTE: making this a HARD required check + having the auto-merge bot consult check status needs Forgejo branch-protection config (human action) — until then the gate is visible but advisory. Refs #944.
This commit is contained in:
parent
a87a69af7c
commit
37837e72f4
1 changed files with 118 additions and 0 deletions
118
.forgejo/workflows/ci.yml
Normal file
118
.forgejo/workflows/ci.yml
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
# Forgejo Actions pytest gate for the MAIN backend (backend/).
|
||||||
|
# WHY THIS FILE EXISTS: Forgejo runs ONLY .forgejo/workflows/* — the
|
||||||
|
# .github/workflows/ci.yml pytest gate does NOT execute on git.gendsgn.ru
|
||||||
|
# (proven: Forgejo Actions runs показывают только deploy/build jobs). Без этого
|
||||||
|
# backend-изменения мержились + деплоились БЕЗ автотестов → live-баг #994
|
||||||
|
# (district 500) уехал в прод необнаруженным. Этот workflow добавляет реальный
|
||||||
|
# gate: backend-сьют GREEN (1687 passed / 0 failed) после CI-rehab 1+2.
|
||||||
|
#
|
||||||
|
# Lane = MOCK-ONLY (day 1): нет postgres service-контейнера — сьют мокает БД,
|
||||||
|
# единственный real-Postgres тест (tests/sql/ mv_layout) self-skip'ается через
|
||||||
|
# connectivity-probe. PDF-тесты (WeasyPrint) РЕАЛЬНО ИДУТ здесь (libpango
|
||||||
|
# установлен ниже), тогда как на macOS-dev они runtime-skip'аются.
|
||||||
|
# FUTURE: добавить `postgis/postgis:16-3.4` service + гонять mv_layout — см.
|
||||||
|
# .github/workflows/ci.yml как образец service-блока.
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
# Mirror the bot-PR / feature-branch flow в .claude/rules/git-pr.md:
|
||||||
|
# PR получает gate, прямые пуши в feature-ветки — тоже.
|
||||||
|
- "feat/**"
|
||||||
|
- "fix/**"
|
||||||
|
- "refactor/**"
|
||||||
|
- "chore/**"
|
||||||
|
- "docs/**"
|
||||||
|
- "perf/**"
|
||||||
|
- "test/**"
|
||||||
|
- "ci/**"
|
||||||
|
- "hotfix/**"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ci-${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Paths-filter: gate бежит ТОЛЬКО когда поменялся backend-код или SQL,
|
||||||
|
# которые этот backend читает (mirror deploy.yml changes-job). На чисто
|
||||||
|
# frontend/docs PR job no-op'ится → дёшево.
|
||||||
|
changes:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
backend: ${{ steps.filter.outputs.backend }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dorny/paths-filter@v3
|
||||||
|
id: filter
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
backend:
|
||||||
|
- 'backend/**'
|
||||||
|
- 'data/sql/**'
|
||||||
|
- '.forgejo/workflows/ci.yml'
|
||||||
|
|
||||||
|
backend-tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: needs.changes.outputs.backend == 'true'
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: backend
|
||||||
|
env:
|
||||||
|
# TESTING=1 активирует RBAC-bypass (app/main.py rbac_guard пропускает
|
||||||
|
# запросы при settings.testing=True) — иначе 401 на всём /api/v1.
|
||||||
|
TESTING: "1"
|
||||||
|
# Stub DSN: psycopg v3 требует parseable URL на импорте; реального коннекта
|
||||||
|
# нет — DB-тесты мокаются, real-DB тест (tests/sql/) self-skip'ается через
|
||||||
|
# connectivity-probe к этому хосту (5432 недоступен → skip).
|
||||||
|
DATABASE_URL: postgresql+psycopg://test:test@localhost:5432/test
|
||||||
|
REDIS_URL: redis://localhost:6379/0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
|
||||||
|
- name: Install uv
|
||||||
|
# Официальный standalone-инсталлер. НЕ astral-sh/setup-uv — он ломается
|
||||||
|
# на Forgejo-runner с PEP 668 externally-managed-environment (#666 CI).
|
||||||
|
run: |
|
||||||
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||||
|
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||||
|
|
||||||
|
- name: Install system deps for geo + WeasyPrint
|
||||||
|
# libpq/gdal/proj/geos — geo-стек (geopandas/shapely/pyproj).
|
||||||
|
# libcairo2/libpango* — нативные либы WeasyPrint: с ними PDF-тесты
|
||||||
|
# (tests/test_layout_tz_pdf.py) РЕАЛЬНО ИДУТ на CI (на macOS-dev они
|
||||||
|
# module-skip'аются probe'ом native-libs). Mirror .github ci.yml:55-57.
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libpq-dev libgdal-dev libproj-dev libgeos-dev \
|
||||||
|
libcairo2 libpango-1.0-0 libpangoft2-1.0-0
|
||||||
|
|
||||||
|
- name: Install Python deps (incl. dev group — ruff, pytest)
|
||||||
|
# backend/uv.lock закоммичен → --frozen (детерминированно, fail при
|
||||||
|
# дрейфе lock vs pyproject). dev-группа ставится по умолчанию (ruff/pytest).
|
||||||
|
run: uv sync --frozen
|
||||||
|
|
||||||
|
- name: Lint (ruff check)
|
||||||
|
# Дешёвый fail-fast. NB: `ruff format --check` НАМЕРЕННО НЕ в gate —
|
||||||
|
# на момент создания 17 файлов repo-wide дали бы day-1 red. Отдельный
|
||||||
|
# format-pass = future enhancement. `ruff check .` сейчас green.
|
||||||
|
run: uv run ruff check .
|
||||||
|
|
||||||
|
- name: Test (pytest)
|
||||||
|
# --ignore=tests/smoke: prod-smoke бьёт по live https://gendsgn.ru
|
||||||
|
# (помечены @pytest.mark.prod_smoke; pyproject addopts уже их deselect'ит,
|
||||||
|
# но --ignore — belt-and-suspenders на случай сбора фикстур).
|
||||||
|
# tests/integration self-skip'ается через requires_test_db (skipif на
|
||||||
|
# TEST_DATABASE_URL, который тут не задан) → НЕ игнорим, оно чисто skip'ается.
|
||||||
|
# tests/sql/ mv_layout self-skip'ается через Postgres-connectivity probe
|
||||||
|
# (5432 недоступен в этом mock-lane) → SKIP. Это intended.
|
||||||
|
# PDF-тесты ИДУТ (libpango выше). Target: 0 failed, skips OK.
|
||||||
|
run: uv run pytest -q --ignore=tests/smoke
|
||||||
Loading…
Add table
Reference in a new issue