Desarrollo y CI¶
Guía operativa: discovery de plugins, variables de entorno, jobs de CI y smoke pip.
Discovery de plugins¶
Orden de precedencia (el último gana en sideload):
flowchart LR
EP[entry_points cortex.plugins]
WS[PLUGINS_ROOT workspace]
SL[PLUGIN_DIRS sideload]
EP --> Merge[PluginSpec merged]
WS --> Merge
SL --> Merge | Fuente | Variable / mecanismo | Uso |
|---|---|---|
| Entry points | pip / uv sync | Producción y monorepo local |
| Workspace | PLUGINS_ROOT (default: plugins/ si existe) | Desarrollo con submódulos |
| Sideload | PLUGIN_DIRS (lista separada por :) | Override por id en dev |
Código: framework/cortex_framework/plugins/discovery.py.
Paneles dedicados: entry point cortex.panels — ver ADR 011 y Namespaces y paneles.
Activación y hot reload¶
| Paso | Comportamiento |
|---|---|
| Instalación | Plugin en catálogo (entry point), desactivado por defecto |
| Activación | Superadmin en /control/plugins → PostgreSQL platform_plugin_state |
| Boot | load_plugins() — solo plugins habilitados + builtins |
| Hot enable | activate_pending_plugins() — repite register_resources / register_forms en paneles habilitados |
Detalle: Activación de plugins.
Variables de entorno relevantes¶
Referencia completa: Configuración y .env.example.
| Variable | Descripción |
|---|---|
DATABASE_URL | PostgreSQL async (obligatorio en despliegue) |
REDIS_URL | Redis — rate limit, idempotencia, checkpoints ai-agents |
REDIS_REQUIRED | Si true, /ready falla cuando Redis no responde |
RATE_LIMIT_ENABLED | Activa rate limit (requiere Redis o fallback memoria) |
AUTH_MODE | optional | required | internal | external |
JWT_SECRET | Secreto HS256 (obligatorio si required/internal) |
WEBHOOK_SECRET | Firma HMAC en entregas webhook (X-Cortex-Signature) |
PLUGINS_ROOT | Directorio workspace para scan (vacío en smoke pip) |
PLUGIN_DIRS | Sideload adicional (solo dev) |
RATE_LIMIT_PER_MINUTE | Límite por cliente/minuto (default 120) |
APP_ENV | development añade panel developer |
Los nombres CORTEX_* están deprecados (dual-read temporal en runtime).
CI — .github/workflows/python-ci.yml¶
| Job | Qué valida |
|---|---|
test | Ruff, pytest plataforma, rate limit+Redis, manifests, stateless gate, composition doc-gate, MkDocs, wheels, smoke pip, operations-core bundle |
test-product-composition | pytest products/unosportclub/tests -m product_composition |
test-postgres | Tests que requieren PG con migraciones |
Submódulos en CI¶
Checkout con submodules: recursive y secrets.SUBMODULES_TOKEN para repos privados cortex-plugin-* y cortex-docs.
Smoke pip¶
Simula instalación pip aislada (sin workspace plugins/):
- Build wheels con
deploy/build-wheels.sh - Venv limpio instala
cortex,cortex_ubl,booking,panel,resources PLUGINS_ROOT=/tmp/cortex-smoke-plugins(vacío)cd /tmpy arrancarcortex-apicurl/api/v1/healthy/api/v1/panels/routes
Redis en CI y degradación local¶
| Modo | Comportamiento |
|---|---|
| Sin Redis | Rate limit usa memoria; idempotencia se omite si Redis no responde |
RATE_LIMIT_ENABLED=true + Redis | Tests 429 en job test |
REDIS_REQUIRED=true | /ready retorna 503 si Redis cae |
En tests de integración que usan Idempotency-Key, usar claves únicas (uuid) para evitar respuestas cacheadas entre ejecuciones cuando Redis local persiste datos.
Validación local antes de merge¶
git submodule update --init --recursive
uv run pytest -m "not product_composition"
uv run pytest products/unosportclub/tests -m product_composition
uv run ruff check core framework products/unosportclub
./scripts/validate-plugin-manifests.sh
./scripts/validate-composition-docs.sh
bash docs/scripts/build-pages-staging.sh
npm run build:web-shadcn # si hay cambios UI