Cap 12: Claude Code en CI/CD
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:
- No espera input del usuario (esencial para CI/CD)
- Lee el prompt, ejecuta, y retorna el resultado
- Termina automáticamente al completar
- Compatible con pipes y redirección
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"