All checks were successful
Deploy Trade-In / changes (push) Successful in 10s
Deploy Trade-In / build-browser (push) Successful in 34s
Deploy Trade-In / test (push) Successful in 1m38s
Deploy Trade-In / build-backend (push) Successful in 1m29s
Deploy Trade-In / build-frontend (push) Successful in 3m21s
Deploy Trade-In / deploy (push) Successful in 1m18s
135 lines
6.7 KiB
YAML
135 lines
6.7 KiB
YAML
name: CI Trade-In
|
||
|
||
# Forgejo Actions pre-merge gate for the SUBPROJECT tradein-mvp/.
|
||
# WHY THIS FILE EXISTS (#2208): основной .forgejo/workflows/ci.yml гейтит
|
||
# ТОЛЬКО backend/** + frontend/** главного стека — tradein-PR проходили на
|
||
# пусто-зелёных чеках (paths-filter no-op), а pytest tradein жил лишь в
|
||
# post-merge deploy-tradein.yml. Итог: сломанный tradein-код мержился в main
|
||
# и обнаруживался только на деплое. Этот workflow добавляет РЕАЛЬНЫЙ pre-merge
|
||
# gate: tradein-backend pytest + tradein-frontend type-check/lint ДО мержа.
|
||
on:
|
||
# ТОЛЬКО pull_request — НЕТ push-триггера на feature-ветки (CI-шторм #1709,
|
||
# см. подробное обоснование в ci.yml). Кратко: раньше push+pull_request на один
|
||
# SHA давали разный github.ref → разные concurrency-группы → 2× прогон на
|
||
# дефицитных раннерах. В bot-пайплайне каждый коммит идёт через PR, так что
|
||
# pull_request гейтит его полностью; push-прогон был чистым дублем.
|
||
pull_request:
|
||
branches: [main]
|
||
|
||
concurrency:
|
||
# github.ref стабилен на весь PR (refs/pull/<N>/merge) → новый push в ветку PR
|
||
# отменяет предыдущий незавершённый прогон ЭТОГО PR вместо накопления.
|
||
group: ci-tradein-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
# Paths-filter: гейт бежит ТОЛЬКО когда поменялся tradein-код.
|
||
# PR не трогающий tradein-mvp/ → оба job'а no-op'ятся → дёшево.
|
||
changes:
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
backend: ${{ steps.filter.outputs.backend }}
|
||
frontend: ${{ steps.filter.outputs.frontend }}
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: dorny/paths-filter@v3
|
||
id: filter
|
||
with:
|
||
filters: |
|
||
backend:
|
||
- 'tradein-mvp/backend/**'
|
||
- 'tradein-mvp/packages/**'
|
||
# workspace root: lock-only bump (uv lock --upgrade) или правка
|
||
# [tool.uv.workspace] меняют реальные зависимости → гейт обязан бежать.
|
||
- 'tradein-mvp/uv.lock'
|
||
- 'tradein-mvp/pyproject.toml'
|
||
- '.forgejo/workflows/ci-tradein.yml'
|
||
frontend:
|
||
- 'tradein-mvp/frontend/**'
|
||
- '.forgejo/workflows/ci-tradein.yml'
|
||
|
||
backend-tests:
|
||
runs-on: ubuntu-latest
|
||
needs: changes
|
||
if: needs.changes.outputs.backend == 'true'
|
||
defaults:
|
||
run:
|
||
working-directory: ./tradein-mvp/backend
|
||
env:
|
||
# psycopg v3 требует parseable URL на импорте; реального коннекта нет —
|
||
# DB-тесты мокаются (mirror deploy-tradein.yml test-job).
|
||
DATABASE_URL: postgresql+psycopg://test:test@localhost:5432/test
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- 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: Cache uv packages
|
||
# Кросс-прогонный кэш скачанных/собранных wheel'ов (~/.cache/uv).
|
||
# continue-on-error чтобы сбой cache-бэкенда раннера НИКОГДА не ронял gate.
|
||
# Ключ по workspace-локу tradein-mvp/uv.lock (tracked с воркспейса #2137).
|
||
uses: actions/cache@v4
|
||
continue-on-error: true
|
||
with:
|
||
path: ~/.cache/uv
|
||
key: uv-tradein-${{ runner.os }}-${{ hashFiles('tradein-mvp/uv.lock') }}
|
||
restore-keys: |
|
||
uv-tradein-${{ runner.os }}-
|
||
|
||
- name: Sync deps (incl. dev group — pytest)
|
||
# Workspace-лок tradein-mvp/uv.lock TRACKED (с воркспейса #2137; gitignored
|
||
# только старый backend/uv.lock) → --frozen детерминирован и зеркалит
|
||
# Dockerfile (uv sync --frozen --no-dev там). uv находит workspace root
|
||
# вверх от cwd.
|
||
run: uv sync --frozen
|
||
|
||
- name: Run pytest (tradein-mvp/backend)
|
||
# DESELECT (актуализировано 2026-07-02, #2208): test_search_cache_hit падает
|
||
# ТОЛЬКО в whole-suite ordering (401 vs 200; в изоляции проходит) — global-state
|
||
# leak из другого test-модуля, pre-existing. Второй исторический deselect
|
||
# (test_cian_valuation::test_cache_hit_returns_cached) убран — проходит в
|
||
# полном прогоне (проверено локально: 2947 passed / 1 failed). Список обязан
|
||
# совпадать с test-job в deploy-tradein.yml.
|
||
run: |
|
||
uv run pytest -q \
|
||
--deselect "tests/test_search_api.py::test_search_cache_hit"
|
||
|
||
frontend-checks:
|
||
runs-on: ubuntu-latest
|
||
needs: changes
|
||
if: needs.changes.outputs.frontend == 'true'
|
||
defaults:
|
||
run:
|
||
working-directory: ./tradein-mvp/frontend
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Set up Node
|
||
# Node 20 — major из tradein-mvp/frontend/Dockerfile (node:20-alpine).
|
||
# npm-кэш setup-node НЕ настраиваем: в tradein-mvp/frontend нет
|
||
# package-lock.json (Dockerfile ставит через npm install), а cache=npm
|
||
# без lockfile падает. Кэш wheels/node тут не критичен для type-check/lint.
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: "20"
|
||
|
||
- name: Install deps (npm install, no lockfile)
|
||
# ТОЧНЫЕ флаги из tradein-mvp/frontend/Dockerfile (deps stage):
|
||
# --legacy-peer-deps — Tailwind/React 19 peer-dep mismatches;
|
||
# --no-audit --no-fund — тише и быстрее в CI. `install` (не `ci`):
|
||
# в tradein-mvp/frontend НЕТ package-lock.json (есть pnpm-lock.yaml, но
|
||
# Dockerfile ставит именно npm install) → `npm ci` упал бы.
|
||
run: npm install --legacy-peer-deps --no-audit --no-fund
|
||
|
||
- name: Type-check (tsc --noEmit)
|
||
# Blocking: любая TS-ошибка → job RED.
|
||
run: npm run type-check
|
||
|
||
- name: Lint (next lint)
|
||
# Blocking: любая ESLint-ошибка → job RED.
|
||
run: npm run lint
|