Jose Salazar Claude Opus 5 commited on
Commit
523cb7e
·
1 Parent(s): eaa81c2

CI: puerta de código en todos los PR (ruff, pytest, tsc, eslint)

Browse files

Antes, un PR que tocara sólo `backend/app/security/` o `backend/app/routers/` no
disparaba NINGÚN workflow: el único que existía filtraba por rutas y nombraba
`backend/app/ai/**` y `backend/app/rag/**`. Toda la superficie de autenticación,
sesiones, CSRF e ingesta de laboratorio se fusionaba sin que nadie ejecutara
`backend/tests/`, que nunca ha corrido en CI pese a estar en `make backend-test`.

`ci.yml` corre en todos los PR, sin filtro: ruff + pytest (backend) y tsc --noEmit
+ eslint (frontend). El alcance de ruff es el de `make lint` (evals/ y bridge/
fuera a propósito). Sin `--group rag`: las dos suites que lo necesitan ya se
auto-omiten y los grupos pesados costarían GBs por una prueba sintética.

`evals.yml` conserva su filtro —es la puerta cara— pero se amplía a `backend/**`
y `frontend/**`: el anterior dejaba fuera `schemas.py`, que define la forma misma
que las evals puntúan, y `config.py`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

.github/workflows/ci.yml ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: ci
2
+
3
+ # Puerta de calidad del CÓDIGO (rápida). La puerta clínica —motor determinista y evals— vive
4
+ # en `evals.yml`, que sí filtra por rutas porque su coste es otro.
5
+ #
6
+ # Este workflow NO lleva filtro `paths` a propósito: antes, un PR que tocara sólo
7
+ # `backend/app/security/` o `backend/app/routers/` no disparaba NINGÚN workflow, así que toda
8
+ # la superficie de autenticación, sesiones, CSRF y ingesta de laboratorio se fusionaba sin que
9
+ # nadie ejecutara `backend/tests/`. Cualquier PR corre esto.
10
+
11
+ on:
12
+ pull_request:
13
+ push:
14
+ branches: [main]
15
+
16
+ jobs:
17
+ backend:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: astral-sh/setup-uv@v5
22
+ with:
23
+ enable-cache: true
24
+ - name: Sincronizar backend
25
+ working-directory: backend
26
+ # Sin `--group rag`: los grupos pesados son opt-in (ver pyproject) y las dos suites que
27
+ # dependen de LanceDB/sentence-transformers ya se auto-omiten
28
+ # (`test_retriever_integracion.py`, `test_alcance_corpus.py`). Instalarlos aquí añadiría
29
+ # GBs y minutos a cambio de una prueba de integración sintética. Si algún día la
30
+ # recuperación regresa sin que nadie se entere, ese es el momento de añadirlos.
31
+ run: uv sync
32
+ - name: Ruff (backend + scripts)
33
+ working-directory: backend
34
+ # Mismo alcance que `make lint`: evals/ y bridge/ quedan fuera a propósito, aún no
35
+ # están saneados bajo estas reglas.
36
+ run: uv run ruff check . ../scripts
37
+ - name: Pruebas del backend
38
+ working-directory: backend
39
+ run: uv run pytest -q
40
+
41
+ frontend:
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ - uses: actions/setup-node@v4
46
+ with:
47
+ node-version: "22"
48
+ cache: npm
49
+ cache-dependency-path: frontend/package-lock.json
50
+ - name: Instalar frontend
51
+ working-directory: frontend
52
+ run: npm ci
53
+ - name: Tipos (tsc --noEmit)
54
+ working-directory: frontend
55
+ # `npm run build` ya lo corría, pero nada ejecutaba el build en CI.
56
+ run: npm run typecheck
57
+ - name: ESLint
58
+ working-directory: frontend
59
+ run: npm run lint
.github/workflows/evals.yml CHANGED
@@ -1,14 +1,20 @@
1
  name: evals
2
 
3
- # Puerta de calidad: bloquea el merge si el motor determinista regresa o si la suite
4
- # de evaluación clínica cae bajo sus umbrales o registra violaciones de seguridad.
 
 
 
 
 
 
 
5
 
6
  on:
7
  pull_request:
8
  paths:
9
- - "frontend/src/**"
10
- - "backend/app/ai/**"
11
- - "backend/app/rag/**"
12
  - "evals/**"
13
  - "data/**"
14
  push:
@@ -44,6 +50,13 @@ jobs:
44
  - name: Instalar deps del motor (para el puente Node)
45
  working-directory: frontend
46
  run: npm ci
 
 
 
 
 
 
 
47
  # En CI real, sustituir --simular por --modelo medgemma apuntando a un endpoint,
48
  # o subir un archivo de predicciones generado en un job con GPU.
49
  #
 
1
  name: evals
2
 
3
+ # Puerta de calidad CLÍNICA: bloquea el merge si el motor determinista regresa o si la suite
4
+ # de evaluación cae bajo sus umbrales o registra violaciones de seguridad.
5
+ #
6
+ # Este sí filtra por rutas —es el workflow caro— pero el filtro anterior era demasiado
7
+ # estrecho: nombraba `backend/app/ai/**` y `backend/app/rag/**`, dejando fuera `schemas.py`
8
+ # (que define `InterpretacionClinica`, la forma misma que las evals puntúan) y `config.py`
9
+ # (umbrales y ruta de modelo por defecto). Un cambio ahí alteraba la salida evaluada sin
10
+ # disparar la puerta. Las puertas de código —ruff, pytest, tsc, eslint— viven en `ci.yml`,
11
+ # que corre en TODOS los PR sin filtro.
12
 
13
  on:
14
  pull_request:
15
  paths:
16
+ - "frontend/**"
17
+ - "backend/**"
 
18
  - "evals/**"
19
  - "data/**"
20
  push:
 
50
  - name: Instalar deps del motor (para el puente Node)
51
  working-directory: frontend
52
  run: npm ci
53
+ # Antes de la puerta, la puerta misma: métricas, rúbrica, umbrales y esquema del dataset
54
+ # son código sin cobertura de nadie más. Si el medidor está roto, el resultado de la
55
+ # puerta no significa nada (visto: el simulador dejaba `fuera_de_alcance` sin declarar y
56
+ # suspendía una métrica de tolerancia cero por su cuenta).
57
+ - name: Pruebas unitarias de los scripts de evals
58
+ working-directory: backend
59
+ run: uv run pytest -q ../evals/tests
60
  # En CI real, sustituir --simular por --modelo medgemma apuntando a un endpoint,
61
  # o subir un archivo de predicciones generado en un job con GPU.
62
  #