claudio.cool
CCAR-FLecciones

CCAR-F · Claude Code

Claude Code en CI/CD

⏱ 3 min de lecturaBorrador

En un pipeline no hay nadie para contestar preguntas. Si el job corre claude "Analizá este PR" y se cuelga para siempre, es porque Claude Code arrancó en modo interactivo y está esperando una respuesta. Integrarlo en CI/CD tiene cuatro piezas: cómo se invoca, qué devuelve, qué contexto lee y quién revisa.

Cómo se invoca

El flag -p (o --print) corre Claude Code en modo no interactivo (non-interactive mode): procesa el prompt, escribe el resultado en stdout y termina.

claude -p "Revisá este PR buscando problemas de seguridad"

--batch y CLAUDE_HEADLESS no existen, y redirigir stdin desde /dev/null es un parche que no resuelve el modo interactivo.

Qué devuelve

Para publicar cada hallazgo como comentario en la línea exacta del PR, un script necesita salida estructurada (structured output), no prosa:

claude -p "Revisá los cambios" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"findings":{"type":"array","items":{"type":"object","properties":{"file":{"type":"string"},"line":{"type":"integer"},"severity":{"type":"string"},"message":{"type":"string"}},"required":["file","line","severity","message"]}}},"required":["findings"]}'

--output-format json devuelve JSON con el resultado y metadatos de la sesión; --json-schema obliga a que la salida cumpla el esquema, y llega en el campo structured_output. Si la corrida termina sin una salida válida, ese campo no viene, así que el script tiene que verificarlo antes de usarlo. Pedir el formato en el prompt mejora la probabilidad; el esquema lo garantiza.

Qué contexto lee

Claude Code en CI lee el CLAUDE.md del proyecto igual que en una sesión interactiva. Ahí van los estándares de testing, las factories y fixtures disponibles, qué hace valioso a un test y los criterios de revisión. Si los tests generados ignoran las fixtures del equipo, lo más probable es que no estén documentadas ahí. Y si las convenciones andan en las laptops pero no en CI, están en los ~/.claude/CLAUDE.md personales, que el runner no tiene.

Para la generación de tests, además, conviene pasar los archivos de test existentes, así no sugiere escenarios que ya están cubiertos.

Quién revisa

La sesión que generó el código conserva su razonamiento: por qué eligió ese enfoque y qué descartó. Al revisarse a sí misma le cuesta cuestionar decisiones que ya justificó. Una instancia de revisión independiente (independent review instance), una invocación nueva que recibe solo el código y los criterios, encuentra más. Pedirle a la misma sesión que “piense más” no saca ese razonamiento del contexto.

Revisiones que no se repiten

Si cada push vuelve a comentar los mismos cinco problemas, incluso los ya arreglados, pasale a la nueva corrida los hallazgos anteriores (prior findings) con archivo, línea y problema, y pedile que informe solo lo nuevo o lo que sigue sin resolver. Filtrar comparando texto falla, porque Claude redacta distinto en cada corrida.

Las trampas típicas

  • Inventar flags (--batch, --format markdown, --strict-conventions).
  • JSON sin esquema cuando el script necesita campos fijos.
  • Reintentar hasta que aparezca el campo line.
  • Pasar los chequeos pre-merge a la Message Batches API: puede tardar hasta 24 horas y no tiene SLA de latencia; sirve para auditorías nocturnas o semanales, no para lo que bloquea un merge.
  • Revisar con menos detalle para que haya menos duplicados.

En el examen

Job colgado: -p. Comentarios en línea: --output-format json con --json-schema. Convenciones ignoradas en CI: el CLAUDE.md del proyecto. Revisión que no ve sus propios errores: otra instancia. Comentarios repetidos: hallazgos anteriores en el contexto.

Pregunta rápida

Una pregunta del simulacro sobre este dominio. Cuenta para tu progreso.

A government contractor's repository has two rule files under .claude/rules/: security.md, with no paths frontmatter, which describes how secrets, input validation and logging of personal data must be handled; and api.md, with paths ["src/api/**/*"], which describes route and response conventions.

A developer starts a new session and asks Claude Code to add a field to src/api/user.ts. He has not run any command beforehand, and he has not edited any other file in the session.

The project also has a root CLAUDE.md with build commands, and a skill for generating release notes that nobody has invoked today.

Which of the two rule files are loaded?

Practicá este dominio en el simulacro →