CI/CD¶
Todos los repositorios del ecosistema usan GitHub Actions. Esta página describe los patrones y convenciones comunes.
Principios básicos¶
- Se comprueba en el PR, se despliega en main. Un PR ejecuta build y
pruebas, y no despliega nada. El despliegue solo arranca tras la fusión en
main. - Se construye solo lo que cambió.
paths-filterdetermina qué partes se modificaron y solo se reconstruyen esos servicios. - Sin despliegues simultáneos. Un grupo
concurrencypone los despliegues de producción en cola para que nunca coincidan. - Los secretos, solo en GitHub Secrets. Nunca se escriben en un fichero de workflow.
La forma habitual de un workflow¶
name: deploy
on:
push:
branches: [main]
paths:
- 'backend/**'
- 'frontend/**'
- '.github/workflows/deploy.yml'
workflow_dispatch: # permite lanzarlo a mano
concurrency:
group: deploy-production
cancel-in-progress: false # nunca interrumpir un despliegue a medias
cancel-in-progress: false importa
Un despliegue cortado a mitad puede dejar un estado incompleto: el contenedor nuevo sin arrancar y el viejo ya parado. Hay que dejar que el despliegue llegue hasta el final y encolar el siguiente detrás.
La fase de comprobación (PR)¶
| Comprobación | Qué hace |
|---|---|
| Build | Si el código compila |
| Pruebas unitarias | Lógica de negocio |
| Pruebas de integración | testcontainers — PostgreSQL/Redis reales |
| Lint | Estilo de código |
| Build estricto de la documentación | Detecta enlaces rotos y ficheros ausentes |
La comprobación estricta de la documentación¶
MkDocs se construye en modo --strict. En ese modo los avisos se convierten
en errores:
- enlaces internos rotos,
- ficheros declarados en
navque no existen, - ficheros que existen pero no están en
nav.
Así, la documentación rota no llega a producción.
La fase de despliegue¶
Se conecta al host por SSH. Los secretos necesarios (nomenclatura común):
| Secreto | Significado |
|---|---|
DEPLOY_HOST |
Dirección del servidor |
DEPLOY_USER |
Usuario SSH |
DEPLOY_SSH_KEY |
Clave privada |
DEPLOY_PORT |
Puerto SSH (opcional, 22 por defecto) |
DEPLOY_PATH |
Ruta en el host |
Clave SSH, no contraseña
El despliegue usa una clave SSH, no una contraseña. Una clave se revoca con facilidad, es menos probable que acabe por accidente en los registros y puede rotarse sin volver a repartirla entre muchas personas.
Builds parciales¶
En un monorepo, un cambio no debería obligar a reconstruir todos los servicios:
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
backend: 'backend/**'
frontend: 'frontend/**'
edge: 'nginx/**'
Después solo se reconstruyen los servicios modificados. Si lo que cambió fue el
edge (nginx), no hay reconstrucción completa: solo sincronizar la
configuración + nginx -t + reload.
Despliegue de la configuración del edge¶
El conf.d del edge nginx se gestiona por git. Secuencia del despliegue:
- Sincronizar el repositorio en el host con
git fetch && git reset --hard, docker exec <nginx> nginx -t— validar la configuración,- Si va bien,
nginx -s reload.
No se puede saltar nginx -t
Recargar con una configuración errónea hace que nginx no vuelva a
levantarse, y en ese momento se caen todos los dominios. nginx -t debe
ejecutarse antes del reload, y un fallo debe detener el despliegue.
Runners autoalojados¶
Los builds de iOS y Windows (firma de código, notarización, empaquetado MSIX) usan runners macOS / Windows autoalojados. Necesitan herramientas y certificados propios de la plataforma, así que no pueden ejecutarse en runners en la nube.
Versionado y rollback¶
- Las imágenes llevan tag. Con la variable
<SVC>_IMAGE_TAGen el host se puede fijar una versión concreta. - En los sitios estáticos se vuelve a desplegar el archivo de la construcción anterior.
El CI/CD de este repositorio¶
El repositorio docs-gerege-mn tiene dos workflows:
| Workflow | Cuándo | Qué hace |
|---|---|---|
ci.yml |
PR + push a main |
Build de MkDocs --strict; deja un artefacto |
deploy.yml |
Push a main + manual |
Build → copiar → actualizar el contenedor → instalar el vhost del edge → comprobar el sitio en vivo |
Véase Esta plataforma documental para el detalle.