Canales de CI/CD
CI/CD para servicios de Python ejecuta ruff, pytest, compilación de imágenes y despliegue por etapas en cada merge. Los canales fuerzan los mismos comandos que los desarrolladores ejecutan localmente con uv y fijan Python 3.14.0 en las matrices de CI.
Receta
# .github/workflows/ci.yml (extracto)
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv sync --frozen
- run: uv run ruff check .
- run: uv run pytest -qCuándo usar esto:
- Cada merge de equipo a main debe ser de calidad candidata para despliegue.
- Compilación de imagen Docker después de que las pruebas pasen.
- Promoción de dev → staging → prod con aprobaciones.
- GitOps el cambio de etiqueta activa el despliegue del clúster.
Ejemplo Funcional
GitHub Actions: prueba, compila/empuja imagen, despliega staging con OIDC a AWS.
name: ci-cd
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: "3.14"
- run: uv sync --frozen
- run: uv run ruff check .
- run: uv run pytest -q --cov=app
build:
needs: test
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/ci-ecr-push
aws-region: us-east-1
- uses: docker/build-push-action@v6
with:
push: true
tags: 123456789012.dkr.ecr.us-east-1.amazonaws.com/api:${{ github.sha }}
deploy-staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- run: echo "kubectl set image deployment/api api=...:${{ github.sha }}"Lo que esto demuestra:
uv sync --frozencoincide con el archivo de bloqueo en CI.- La suposición de rol OIDC evita claves estáticas de AWS.
- Imagen etiquetada con
github.shapara trazabilidad. - Trabajo de despliegue bloqueado por reglas de aprobación de
environment: staging.
Inmersión Profunda
Etapas del Canal
| Etapa | Puertas |
|---|---|
| Lint/prueba | ruff, mypy opcional, pytest |
| Compilación | Dockerfile, escaneo de imagen |
| Despliegue dev | automático en main |
| Despliegue prod | aprobación manual + prueba de humo |
Paridad Local/CI
uv run ruff check . && uv run pytest -q
docker build -t api:local .Notas de Python
- run: uv run python -m build # paquetes de librería
- run: uv publish # PyPI al lanzar librerías, no serviciosTrampas Comunes
- CI usa Python diferente a prod - errores sutiles. Solución: fijar 3.14 en el flujo de trabajo y la imagen Docker.
- Omitir pruebas en cambios solo de documentación - los filtros de ruta pueden pasar por alto código acoplado. Solución: activadores conservadores o reglas de monorepo.
- Etiqueta de despliegue
:latest- imposible revertir. Solución: solo etiquetas SHA inmutables. - Secretos en YAML del flujo de trabajo - usar secretos de Entornos de GitHub y OIDC.
- Sin prueba de humo post-despliegue - endpoint de salud roto en prod. Solución: paso
curl /healthdespués del despliegue.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| GitLab CI | Alojamiento en GitLab | Organización solo en GitHub |
| Buildkite | Agentes autoalojados | GitHub Actions simple suficiente |
| ArgoCD GitOps | Detección de deriva de despliegue K8s | Docker compose en VM única |
Preguntas Frecuentes
¿Qué debe ejecutarse en prebuild?
Este repositorio ejecuta lint-docs en prebuild - mantén la documentación válida al enviar contenido con código.
¿uv vs pip en CI?
uv es más rápido y nativo para archivos de bloqueo - alinea con el manifiesto uv 0.6+ fijado.
¿Cómo cacho dependencias?
setup-uv con caché habilitado o montajes de caché de compilación Docker para la capa uv sync.
¿Migraciones de base de datos en CD?
Trabajo separado antes del cambio de tráfico - nunca solo al inicio de la aplicación sin coordinación.
¿Cómo promuevo staging a prod?
Reetiqueta el SHA probado o reproduce el trabajo de despliegue con aprobación del entorno prod - el mismo artefacto, sin recompilación.
¿Flags de funcionalidad vs ramas?
Se prefiere trunk-based con flags; las ramas de entorno de larga duración se deterioran.
¿Cómo ejecuto pruebas de integración?
Marcador pytest con dependencias de servicio docker-compose en el trabajo de CI o entorno de vista previa efímero.
¿Rutas de monorepo?
Filtros paths: por paquete - pero ejecuta pruebas de humo de todo el sistema en cambios de bibliotecas compartidas.
¿Cómo encaja ruff 0.9+?
Herramienta única para lint/formato - paso rápido de CI antes de pytest.
¿Estrategia de reversión?
Vuelve a desplegar la etiqueta de imagen anterior - documenta en el Manual de Ejecución enlazado desde Mejores Prácticas de Despliegue.
Relacionado
- Dockerizando Python - compilación de imagen
- Código de Infraestructura de Pruebas - patrones de política de CI
- Despliegues sin tiempo de inactividad - seguridad de despliegue
- Configuración de pytest - diseño de pruebas
- Mejores Prácticas de Despliegue - lista de verificación del canal
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.