Skip to content

Commit 8a22fdb

Browse files
committed
docs: Added CI/CD pipelines docs
1 parent 6cd29b3 commit 8a22fdb

1 file changed

Lines changed: 229 additions & 0 deletions

File tree

README.md

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
# Visión general
2+
3+
Este repositorio implementa una aplicación de registro y validación de tickets con una estrategia de ramas basada en trunk (trunk-based development), dos entornos (`stg` y `prd`), y una automatización CI/CD en GitHub Actions. La infraestructura se gestiona con Terraform sobre GCP (Cloud SQL para PostgreSQL y Cloud Run para el servicio API).
4+
5+
# Estrategia de ramas
6+
7+
- **Trunk-based development**: ramas cortas `feature/**`, `feat/**`, `fix/**` que se integran a `main` vía Pull Request.
8+
- **Mapeo de entornos**:
9+
- **staging (`stg`)**: despliegue automático al fusionar a `main`.
10+
- **producción (`prd`)**: promoción manual y condicionada al éxito de `stg`.
11+
12+
# Entornos
13+
14+
- **Staging (`stg`)**: objetivo de pruebas para commits en `main`. Durante CD se aplica infraestructura, se inicializa la base de datos con SQLs de `src/db/scripts/init`, se ejecutan pruebas de integración y luego se limpian los datos de prueba con `src/db/scripts/cleanup`.
15+
- **Producción (`prd`)**: despliegue manual; requiere que el último despliegue a `stg` haya sido exitoso.
16+
17+
# Pipelines de CI/CD
18+
19+
Los workflows viven en `.github/workflows/`.
20+
21+
- **Validaciones en ramas de desarrollo** (`ci-dev-branches.yml`)
22+
- **Disparo**: push a `feature/**`, `feat/**`, `fix/**`.
23+
- **Propósito**: feedback rápido de calidad.
24+
- **Flujo**: análisis estático reutilizable (pre-commit, unit tests con cobertura en consola).
25+
26+
- **Validaciones de Pull Request** (`pr-validations.yml`)
27+
- **Disparo**: `pull_request``main`.
28+
- **Propósito**: proteger integraciones a `main`.
29+
- **Flujo**:
30+
- Análisis estático (pre-commit, unit tests, artefacto de cobertura).
31+
- Pruebas de integración en modo local (Docker Compose).
32+
- Build y push de la imagen Docker a GHCR (`latest` y `sha`).
33+
34+
- **CD a Staging** (`cd-stg.yml`)
35+
- **Disparo**: push a `main` y manual.
36+
- **Propósito**: desplegar imagen verificada a `stg` y validar con pruebas de integración.
37+
- **Flujo**: llama al workflow base `cd-base.yml` con `deployment_env=stg` e imagen `ghcr.io/.../register-ticket-api:latest`.
38+
39+
- **CD a Producción** (`cd-prod.yml`)
40+
- **Disparo**: manual.
41+
- **Propósito**: promover a `prd` sólo si el último despliegue a `stg` fue exitoso.
42+
- **Flujo**: verifica último run de `cd-stg.yml` y, si fue exitoso, llama a `cd-base.yml` con `deployment_env=prd`.
43+
44+
- **Base de CD reutilizable** (`cd-base.yml`)
45+
- **Propósito**: estandarizar despliegues `stg`/`prd`.
46+
- **Flujo**:
47+
1. Promoción de imagen: pull desde GHCR → re-tag → push a DockerHub.
48+
2. Terraform: `init`/`workspace` por entorno, `plan`/`apply` con variables de entorno y `image_uri`.
49+
3. Salidas: `db_host` (IP pública de Cloud SQL) y `api_url` (URL de Cloud Run).
50+
4. Seed de base de datos: ejecutar `src/db/scripts/init/*.sql`.
51+
5. Pruebas de integración contra el entorno desplegado.
52+
6. Limpieza: ejecutar `src/db/scripts/cleanup/*.sql` (siempre, salvo entornos locales).
53+
54+
- **Teardown de emergencia** (`teardown.yml`)
55+
- **Disparo**: manual, requiere escribir “DESTROY”.
56+
- **Propósito**: destruir toda la infraestructura de `stg` o `prd` con Terraform.
57+
58+
## Estrategia de despliegue
59+
60+
### Despliegue de la API
61+
62+
- La imagen se construye en las validaciones de PR y se publica en GHCR con tags `latest` y el `sha` del commit.
63+
- Los pipelines de CD promueven esa imagen: se re-etiqueta y publica en DockerHub (p. ej. `<dockerhub_user>/register-ticket-api:<tag>`).
64+
- Terraform despliega la imagen en Cloud Run, exponiendo una URL pública y enroutando 100% del tráfico a la última revisión.
65+
66+
### Despliegue de la Base de Datos
67+
68+
- Terraform crea una instancia de Cloud SQL (PostgreSQL 15) con IP pública, base de datos y usuario por entorno.
69+
- Durante el despliegue, se ejecutan los scripts SQL de `src/db/scripts/init` para crear esquema, SPs y datos iniciales.
70+
- Tras las pruebas de integración, se ejecutan los scripts de `src/db/scripts/cleanup` para eliminar datos de prueba.
71+
72+
## Infraestructura con Terraform
73+
74+
- **Estado**: backend en GCS (`event-access-tfstate`).
75+
- **Workspaces**: uno por entorno (`stg`, `prd`).
76+
- **Recursos**:
77+
- Cloud SQL (PostgreSQL 15), base de datos y usuario.
78+
- Cloud Run para el servicio `register-ticket-api`, con acceso público (invoker `allUsers`).
79+
- Salidas: `db_host` (IP pública) y `cloud_run_service_url` (URL del servicio).
80+
81+
Archivos clave en `terraform/`:
82+
83+
- `main.tf`: define Cloud SQL y Cloud Run (inyecta `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`).
84+
- `variables.tf`: variables requeridas (`project_id`, `environment`, `db_*`, `image_uri`, etc.).
85+
- `provider.tf`: backend de estado (GCS) y provider `google`.
86+
- `outputs.tf`: `db_host`, `cloud_run_service_url`.
87+
- `environments/*.tfvars`: valores por entorno.
88+
89+
## Estrategia de pruebas
90+
91+
### Unit tests
92+
93+
- Se ejecutan en el workflow reutilizable de análisis estático (`static-code-analysis.yml`).
94+
- Herramientas: `pytest` con cobertura, gestionado con `uv`.
95+
- Alcance: lógica de servicios, comportamiento de repositorios mediante mocks, validaciones y rutas de error.
96+
- En PRs se sube artefacto de cobertura.
97+
98+
### Integration tests
99+
100+
- Dos modos de ejecución:
101+
- **Local (PR)**: levanta dependencias con `docker/docker-compose.yml`, carga variables desde `.env.test`, invoca la API local y valida efectos en DB (psycopg2).
102+
- **Remoto (CD)**: ejecuta contra `stg`/`prd` usando las salidas de Terraform (`api_url`, `db_host`) y credenciales desde secretos.
103+
- Casos cubiertos (ejemplos en `tests/integration/`):
104+
- Registro exitoso de ticket y persistencia en DB.
105+
- Error al registrar ticket duplicado.
106+
- Error por payload inválido.
107+
- Ciclo de datos (detalle):
108+
1) Tras el `apply` de Terraform, la instancia de Cloud SQL y la base de datos quedan disponibles.
109+
2) El pipeline ejecuta los SQL de `src/db/scripts/init/*.sql` (en orden):
110+
- `01_create_tables.sql`: crea tablas `users` y `tickets`, incluyendo PKs, restricciones (único seat+gate) y columnas necesarias (seed TOTP, `used_at`, `status`).
111+
- `02_create_ticket_stored_procedures.sql`: define el `PROCEDURE sp_register_ticket_to_user` para registrar tickets a usuarios, y la `FUNCTION fn_mark_ticket_as_used` para marcar el uso de un ticket.
112+
- `03_populate_tables.sql`: habilita `pgcrypto` y carga datos de prueba mínimos: dos usuarios (`spuertaf`, `juanperez`) y varios tickets con `seed` aleatorio y estado `valid`.
113+
3) Se ejecutan las pruebas de integración contra el ambiente desplegado, verificando conectividad API y DB:
114+
- La suite (p. ej. `tests/integration/test_tickets_registration.py`) hace llamadas HTTP a la API en Cloud Run (`BASE_URL`) y valida efectos en DB (`db_host`) vía `psycopg2` (fixtures `base_url` y `db_connection`).
115+
- Casos: alta de ticket para usuario; intentos duplicados; validación de errores.
116+
4) Si las pruebas de integración finalizan correctamente, se ejecutan los SQL de `src/db/scripts/cleanup/*.sql` para limpiar datos de prueba:
117+
- `01_drop_test_records.sql`: elimina tickets y usuarios insertados por los scripts de init (evita residuos entre deployments).
118+
119+
Diagrama breve del ciclo de datos:
120+
121+
```mermaid
122+
sequenceDiagram
123+
participant CD as Workflow CD (cd-base)
124+
participant TF as Terraform
125+
participant DB as Cloud SQL (DB)
126+
participant API as Cloud Run (API)
127+
participant IT as Pruebas Integración
128+
129+
CD->>TF: plan/apply (provisiona DB y API)
130+
TF-->>CD: outputs db_host, api_url
131+
CD->>DB: ejecutar init: 01_create_tables.sql
132+
CD->>DB: ejecutar init: 02_create_ticket_stored_procedures.sql
133+
CD->>DB: ejecutar init: 03_populate_tables.sql
134+
CD->>IT: correr tests contra API (api_url) y DB (db_host)
135+
IT-->>CD: resultados OK
136+
CD->>DB: ejecutar cleanup: 01_drop_test_records.sql
137+
```
138+
139+
## Flujo extremo a extremo (E2E)
140+
141+
1. Push a rama `feature/**` → análisis estático y unit tests.
142+
2. Pull Request a `main` → análisis estático + integración local + build & push de imagen a GHCR.
143+
3. Merge a `main` → CD a `stg`: promoción de imagen, Terraform apply, seed DB, integración remota, cleanup.
144+
4. Despliegue a `prd` (manual) → valida último run de `stg` y aplica el mismo proceso.
145+
146+
### Diagramas de secuencia
147+
148+
#### CI desde ramas/PR + CD a Staging y Producción
149+
150+
```mermaid
151+
sequenceDiagram
152+
actor Dev as Developer
153+
participant GH as GitHub Actions
154+
participant CI as Workflows CI
155+
participant PR as PR Validations
156+
participant GHCR as GitHub Container Registry
157+
participant DH as DockerHub
158+
participant CD as Workflows CD
159+
participant TF as Terraform
160+
participant GSQL as GCP Cloud SQL (PostgreSQL)
161+
participant CR as GCP Cloud Run (API)
162+
participant TRT as Test Runner (pytest)
163+
164+
Dev->>GH: push a feature/** | feat/** | fix/**
165+
GH->>CI: ejecutar ci-dev-branches.yml
166+
CI->>CI: pre-commit + unit tests (coverage consola)
167+
168+
Dev->>GH: abrir Pull Request -> main
169+
GH->>PR: ejecutar pr-validations.yml
170+
PR->>PR: análisis estático + unit tests (coverage artifact)
171+
PR->>PR: integración local (docker-compose)
172+
PR->>GHCR: build & push imagen :latest y :sha
173+
174+
Dev->>GH: merge PR -> main
175+
GH->>CD: ejecutar cd-stg.yml
176+
CD->>CD: llamar cd-base.yml (deployment_env=stg, image=GHCR:latest)
177+
CD->>GHCR: pull imagen
178+
CD->>DH: re-tag y push a DockerHub
179+
CD->>TF: init, workspace stg, plan/apply con image_uri
180+
TF->>GSQL: crear instancia + DB + usuario
181+
TF->>CR: desplegar servicio Cloud Run (100% tráfico)
182+
TF-->>CD: outputs db_host, api_url
183+
CD->>GSQL: ejecutar scripts init/*.sql (seed)
184+
CD->>TRT: ejecutar tests integración remotos (usa api_url, db_host)
185+
TRT-->>CD: resultados
186+
CD->>GSQL: ejecutar scripts cleanup/*.sql
187+
188+
Note over CD: Despliegue a stg completo
189+
190+
Dev->>GH: disparo manual cd-prod.yml
191+
CD->>CD: validar último run exitoso de cd-stg
192+
CD->>CD: llamar cd-base.yml (deployment_env=prd, image=GHCR:latest)
193+
CD->>GHCR: pull imagen
194+
CD->>DH: re-tag y push a DockerHub
195+
CD->>TF: init, workspace prd, plan/apply con image_uri
196+
TF->>GSQL: crear instancia + DB + usuario (prd)
197+
TF->>CR: desplegar servicio Cloud Run (prd)
198+
TF-->>CD: outputs db_host, api_url (prd)
199+
```
200+
201+
#### Teardown / Destroy de infraestructura
202+
203+
```mermaid
204+
sequenceDiagram
205+
actor Ops as Operador
206+
participant GH as GitHub Actions
207+
participant TD as Teardown Workflow (teardown.yml)
208+
participant TF as Terraform
209+
participant GSQL as GCP Cloud SQL
210+
participant CR as GCP Cloud Run
211+
212+
Ops->>GH: workflow_dispatch (inputs: env=stg|prd, confirmation="DESTROY")
213+
GH->>TD: ejecutar teardown.yml
214+
TD->>TD: validar confirmation == "DESTROY"
215+
TD->>TF: init, seleccionar workspace (env)
216+
TF->>GSQL: destruir instancia/DB/usuario
217+
TF->>CR: destruir servicio Cloud Run/policy
218+
TF-->>TD: destroy completado
219+
```
220+
221+
## Secretos y configuración
222+
223+
En GitHub Actions (por entorno):
224+
225+
- `GCP_SA_KEY`, `GCP_PROJECT_ID`
226+
- `DB_NAME`, `DB_USER`, `DB_PASSWORD`
227+
- `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`
228+
229+
Variables de Terraform por entorno en `terraform/environments/*.tfvars` (p. ej. `environment`, tamaños, etc.).

0 commit comments

Comments
 (0)