Cap 12: Claude Code en CI/CD

Por: Artiko
claude-certifiedci-cdautomationtestingpipelines

El flag -p (—print) para pipelines

Claude Code puede ejecutarse en modo no-interactivo con el flag -p (alias --print):

claude -p "Revisa este archivo y lista los issues de seguridad" < src/auth.ts

En este modo:

Ejemplo en GitHub Actions

- name: Code Review
  run: |
    claude -p "Revisa los cambios del PR actual. \
    Enfócate en seguridad, performance y adherencia a convenciones. \
    Lista findings por severidad." > review-output.txt

Ejemplo en GitLab CI

review:
  script:
    - claude -p "Analiza los archivos modificados en este MR" > review.txt
    - cat review.txt

Structured Output con —output-format

Para parsear la salida de Claude en pipelines, usa --output-format json:

claude -p "Lista los endpoints sin autenticación" \
  --output-format json

JSON Schema para validación

Combina con --json-schema para garantizar estructura:

claude -p "Analiza la cobertura de tests" \
  --output-format json \
  --json-schema '{
    "type": "object",
    "properties": {
      "coverage_percentage": { "type": "number" },
      "uncovered_files": {
        "type": "array",
        "items": { "type": "string" }
      },
      "recommendation": { "type": "string" }
    },
    "required": ["coverage_percentage", "uncovered_files"]
  }'

Esto produce output JSON que herramientas downstream pueden parsear directamente, sin necesidad de extraer información de texto libre.

CLAUDE.md como contexto para CI

El CLAUDE.md del proyecto es el mecanismo principal para dar contexto a Claude Code en CI/CD. Las instrucciones que Claude sigue localmente también aplican en el pipeline:

<!-- CLAUDE.md -->
## Testing Standards (CI)
- Framework: Vitest
- Coverage mínimo: 80%
- Fixtures en tests/fixtures/
- Mocks en tests/__mocks__/

## Review Criteria
- No console.log en código de producción
- Imports ordenados: built-in → external → internal
- Funciones async deben tener error handling
- No secrets hardcodeados

Cuando Claude Code ejecuta en CI con -p, lee CLAUDE.md y aplica estos criterios automáticamente.

Documentar testing standards y fixtures

El CI se beneficia especialmente de secciones explícitas sobre testing:

## Test Fixtures
- User fixtures: tests/fixtures/users.ts
- API responses: tests/fixtures/api-responses/
- Database seeds: tests/fixtures/seeds/

## Existing Test Patterns
- Unit tests: *.test.ts junto al archivo fuente
- Integration tests: tests/integration/
- E2E: tests/e2e/ con Playwright

Esto evita que Claude sugiera crear fixtures que ya existen o proponga patrones inconsistentes con los establecidos.

Session Isolation

El problema de self-review

La misma sesión de Claude Code que generó código es menos efectiva revisándolo. El modelo tiene sesgo hacia su propia generación — tiende a no encontrar issues en código que acaba de escribir.

❌ Sesión 1:
   "Genera el módulo de autenticación" → genera código
   "Ahora revisa el código que generaste" → finds superficiales

Solución: sesiones separadas

✅ Sesión 1: "Genera el módulo de autenticación" → genera código
   Sesión 2: "Revisa src/auth/ buscando vulnerabilidades" → review objetivo

En CI/CD esto es natural — el pipeline de review corre en una sesión diferente a la de generación.

Implicación para CI

Cuando configures Claude Code en CI para review de PRs, cada ejecución es una sesión fresca. Esto es una ventaja — Claude revisa sin sesgo de generación.

Evitar duplicados en reviews

Incluir prior review findings

Si ejecutas Claude Code para re-review (después de que el developer hizo correcciones), incluye los findings anteriores:

claude -p "Revisa los cambios de este PR. \
Findings previos ya atendidos (no repetir): \
- Se agregó validación de input en /api/users \
- Se removió el console.log en auth.ts \
Busca issues nuevos o que persistan."

Sin esto, Claude puede generar los mismos comments que ya fueron resueltos.

Proveer existing test files

Para evitar que Claude sugiera tests que ya existen:

claude -p "Sugiere tests faltantes para src/services/order.ts. \
Tests existentes en tests/services/order.test.ts. \
No sugieras scenarios que ya están cubiertos."

O mejor, incluye el archivo de test como contexto:

cat tests/services/order.test.ts | claude -p \
  "Dado este archivo de tests existente (stdin), \
   sugiere scenarios adicionales no cubiertos para \
   src/services/order.ts"

Patterns de CI/CD efectivos

PR Review automatizado

name: AI Code Review
on: [pull_request]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Review
        run: |
          claude -p "Revisa los archivos modificados en este PR. \
          Criterios: seguridad, performance, convenciones. \
          Output: lista de findings con severidad y archivo." \
          --output-format json > review.json

Test gap analysis

- name: Test Coverage Analysis
  run: |
    claude -p "Analiza qué funciones en src/services/ \
    no tienen tests correspondientes en tests/services/. \
    Lista archivos sin cobertura." \
    --output-format json > gaps.json

Prevenir input interactivo

Siempre usa -p en CI. Sin este flag, Claude Code esperaría input del terminal y el pipeline se colgaría indefinidamente:

# ❌ Se cuelga en CI esperando input
claude "Revisa el código"

# ✅ Modo no-interactivo, termina automáticamente
claude -p "Revisa el código"

← Cap 11: Plan Mode · Índice · Cap 13: Siguiente →