CCAR-F · Claude Code
Claude Code in CI/CD
In a pipeline, nobody is there to answer questions. If the job runs claude "Analyze this PR" and hangs forever, it’s because Claude Code started in interactive mode and is waiting for a reply. Integrating it into CI/CD has four pieces: how it’s invoked, what it returns, what context it reads and who reviews.
How it’s invoked
The -p (or --print) flag runs Claude Code in non-interactive mode: it processes the prompt, writes the result to stdout and exits.
claude -p "Review this PR for security issues"
--batch and CLAUDE_HEADLESS don’t exist, and redirecting stdin from /dev/null is a workaround that doesn’t solve interactive mode.
What it returns
To post each finding as a comment on the exact line of the PR, a script needs structured output, not prose:
claude -p "Review the changes" \
--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 returns JSON with the result and session metadata; --json-schema makes the output conform to the schema, and it arrives in the structured_output field. If the run ends without valid output, that field is absent, so the script must check for it before using it. Asking for the format in the prompt improves the odds; the schema guarantees it.
What context it reads
Claude Code in CI reads the project CLAUDE.md just as in an interactive session. That’s where testing standards, available factories and fixtures, what makes a test valuable and review criteria go. If generated tests ignore the team’s fixtures, they most likely aren’t documented there. And if conventions work on laptops but not in CI, they live in personal ~/.claude/CLAUDE.md files, which the runner doesn’t have.
For test generation, it also helps to pass the existing test files, so it doesn’t suggest scenarios that are already covered.
Who reviews
The session that generated the code keeps its reasoning: why it chose that approach and what it ruled out. Reviewing itself, it struggles to question decisions it already justified. An independent review instance, a fresh invocation that receives only the code and the criteria, finds more. Asking the same session to “think harder” doesn’t remove that reasoning from the context.
Reviews that don’t repeat
If every push comments on the same five issues again, even the ones already fixed, pass the new run the prior findings with file, line and issue, and ask it to report only what’s new or still unaddressed. Filtering by comparing text fails, because Claude words things differently on every run.
The usual traps
- Inventing flags (
--batch,--format markdown,--strict-conventions). - JSON without a schema when the script needs fixed fields.
- Retrying until the
linefield shows up. - Moving pre-merge checks to the Message Batches API: it can take up to 24 hours and has no latency SLA; it fits nightly or weekly audits, not what blocks a merge.
- Reviewing less thoroughly so there are fewer duplicates.
In the exam
Hung job: -p. Inline comments: --output-format json with --json-schema. Conventions ignored in CI: the project CLAUDE.md. A review that can’t see its own mistakes: another instance. Repeated comments: prior findings in the context.
Quick question
A practice exam question on this domain. It counts towards your progress.
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?