Módulo 7: CI Integration con GitHub Actions

Proyecto del Módulo: CI Pipeline Funcional

Proyecto del Módulo: CI Pipeline Funcional

Descripción del proyecto

Tienes tests que corren localmente. Ahora vas a automatizarlos. Configurarás un pipeline de CI completo con GitHub Actions que corra toda tu test suite en cada push y PR, genere reportes de coverage, use matrix testing para múltiples versiones de Python, y bloquee merges inseguros.

Este proyecto toma un repositorio existente (puedes usar cualquier proyecto de los módulos anteriores) y le agrega CI profesional. Claude Code te ayuda a generar el workflow YAML basándose en el contexto de tu proyecto.


Objetivo del Proyecto

Configurar un pipeline de CI funcional con GitHub Actions para un repositorio con tests.

Al completar este proyecto:

  • ✅ Tu repositorio tendrá .github/workflows/tests.yml funcional
  • ✅ Los tests correrán automáticamente en push y PR
  • ✅ Matrix testing validará en Python 3.10, 3.11, 3.12
  • ✅ Coverage report se publicará como artifact
  • ✅ Caching de pip reducirá tiempos de build
  • ✅ Branch protection bloqueará merges si tests fallan

Especificaciones Técnicas

Prerequisitos

  • Cuenta de GitHub
  • Repositorio con al menos 10 tests (puedes usar el proyecto de cualquier módulo anterior)
  • requirements.txt con dependencias

Estructura Objetivo

your-project/
├── .github/
│   └── workflows/
│       └── tests.yml          ← El pipeline (tú creas)
├── src/ o module/             ← Tu código
├── tests/                     ← Tu test suite existente
├── requirements.txt
├── pyproject.toml             ← Configuración de pytest y coverage
└── README.md                  ← Badge de CI

El Pipeline Paso a Paso

Paso 1: Workflow básico

Crea .github/workflows/tests.yml:

name: Tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      
      - name: Run tests
        run: pytest tests/ -v

Commit, push, y verifica que corre en GitHub.

Paso 2: Agregar matrix testing

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12"]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      
      - name: Run tests
        run: pytest tests/ -v

Paso 3: Agregar caching

      - name: Cache pip packages
        uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-

Paso 4: Agregar coverage

      - name: Run tests with coverage
        run: pytest tests/ -v --cov=src --cov-report=term-missing --cov-report=html
      
      - name: Upload coverage report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report-${{ matrix.python-version }}
          path: htmlcov/

Paso 5: pyproject.toml

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v --tb=short"

[tool.coverage.run]
source = ["src"]
omit = ["tests/*"]

[tool.coverage.report]
fail_under = 85
show_missing = true

Paso 6: Badge en README

![Tests](https://github.com/YOUR-USERNAME/YOUR-REPO/actions/workflows/tests.yml/badge.svg)

Paso 7: Branch protection (manual en GitHub)

  1. Settings → Branches → Add rule
  2. Branch name pattern: main
  3. ✅ Require status checks to pass before merging
  4. ✅ Select "test" job
  5. Save changes

Generar con Claude Code

Prompt para generar el workflow completo:

Genera un workflow de GitHub Actions (.github/workflows/tests.yml) 
para mi proyecto Python.

Contexto:
- Tests en tests/ (unit, integration)
- Dependencias en requirements.txt
- Coverage con pytest-cov, target: ≥85%
- Python versions: 3.10, 3.11, 3.12

Incluye: matrix testing, pip caching, coverage report como artifact.

Criterios de Éxito

Tu proyecto está completo cuando:

  • ✅ git push dispara el workflow automáticamente
  • ✅ Los tests corren en 3 versiones de Python (matrix)
  • ✅ El pipeline usa caching (verificable en logs: "Cache restored")
  • ✅ Coverage report se genera como artifact descargable
  • ✅ Un push con un test que falla → pipeline falla (verificable)
  • ✅ El README tiene el badge de CI

Rúbrica de Evaluación (100 puntos)

Workflow Funcional (35 puntos)

  • (15 pts) Workflow ejecuta pytest exitosamente en CI
  • (10 pts) Triggers configurados (push y pull_request)
  • (10 pts) Workflow YAML válido y sin errores

Matrix y Caching (25 puntos)

  • (15 pts) Matrix testing con al menos 2 versiones de Python
  • (10 pts) Caching de pip implementado

Coverage (20 puntos)

  • (10 pts) Coverage report generado en CI
  • (10 pts) Coverage report publicado como artifact

Protección (10 puntos)

  • (5 pts) Pipeline falla si tests fallan (verificable con push intencional)
  • (5 pts) Badge de CI en README

Documentación (10 puntos)

  • (5 pts) pyproject.toml con configuración de pytest y coverage
  • (5 pts) README explica cómo correr tests localmente y en CI

Extra Credit (hasta +10 puntos)

  • (+5 pts) Branch protection configurado en GitHub
  • (+5 pts) Separate jobs para unit, integration, y e2e tests

Errores Comunes

Error 1: Workflow no se ejecuta

Causa: El archivo no está en .github/workflows/ exactamente, o el YAML tiene errores de indentación.

Solución: Verifica la ruta exacta y usa un validador YAML. Revisa la tab "Actions" en GitHub para ver errores.

Error 2: Tests fallan en CI pero pasan localmente

Causa: Dependencias faltantes en requirements.txt, paths hardcodeados, o variables de entorno faltantes.

Solución: Revisa los logs de CI. Asegúrate de que requirements.txt tiene TODAS las dependencias (incluyendo pytest, pytest-cov).

Error 3: Cache no funciona

Causa: El key de cache no coincide (requirements.txt cambió o no se hashea correctamente).

Solución: Verifica que hashFiles('requirements.txt') apunta al archivo correcto. Revisa los logs: "Cache hit" vs "Cache miss".

Error 4: Coverage report no se genera

Causa: pytest-cov no está en requirements.txt o el flag --cov no apunta al módulo correcto.

Solución: Agrega pytest-cov a requirements.txt y verifica que --cov=src apunta a tu código fuente.


Recursos para el Proyecto

  1. GitHub Actions Quickstart - Inicio rápido
  2. actions/setup-python - Setup Python en CI
  3. actions/cache - Caching de dependencias
  4. actions/upload-artifact - Publicar artifacts
  5. GitHub Branch Protection - Protección de branches

Conexión con Siguiente Módulo

El CI que configuraste hoy es parte del proyecto final:

  • Módulo 8 (Proyecto Integrador): La aplicación final incluye CI como parte de la entrega
  • El pipeline que construiste aquí se reutiliza directamente para el proyecto final
  • Solo necesitarás ajustar paths y dependencias para la nueva aplicación

Tienes CI profesional. Cada push, cada PR, cada merge está protegido por tu test suite. Esto es el estándar de la industria.


Módulo 7, Cápsula 06 — Testing with Claude Code Guide Tu primer CI pipeline profesional