How to Integrate with Gerrit Code Review System: OpenCodeReview Integration Guide
OpenCodeReview provides a Python helper script that converts ocr review --format json output into Gerrit ReviewInput payloads and posts them via the REST API.
Integrating OpenCodeReview with the Gerrit code review system enables automated AI-powered code analysis results to appear directly in your Gerrit changes. The alibaba/open-code-review repository ships a complete integration in examples/gerrit_ci/post_review.py that handles authentication, payload mapping, error recovery, and retry logic.
Prerequisites for Gerrit Integration
Before running the integration, ensure you have:
- OpenCodeReview CLI (
ocr) installed and producing JSON review output - Gerrit HTTP password (not your account password) from Settings → HTTP Password
- Python 3 environment with
requestsor standard libraryurllib
The integration targets Gerrit's /a/ authenticated REST endpoints, which require preemptive Basic authentication to avoid 401 rejection cycles.
Core Architecture: Three Integration Layers
The post_review.py script operates through three coordinated layers:
1. OCR Results to Gerrit Payload Mapping
The build_review_input() function (see [post_review.py, lines 94-104](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L94-L104)) transforms OpenCodeReview JSON into Gerrit's ReviewInput schema:
# Example OCR JSON structure consumed by the mapper
{
"file_path": {
"line_number": {
"severity": "WARNING",
"message": "Potential null pointer dereference"
}
}
}
This mapping:
- Groups inline comments by file path
- Constructs a summary message with change-level statistics
- Formats the
ReviewInputdictionary withcommentsandlabelsfields
2. HTTP Transport with Authentication
The make_poster() function (see [post_review.py, lines 14-33](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L14-L33)) creates a callable that POSTs to:
POST {GERRIT_URL}/a/changes/{change}/revisions/{revision}/review
Key transport features:
- Preemptive Basic Auth: Base64-encoded credentials in the
Authorizationheader before any 401 challenge - XSSI protection handling:
strip_xssi()(see [post_review.py, lines 80-86](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L80-L86)) removes Gerrit's)]}'JSON prefix - Message truncation:
truncate_message()(see [post_review.py, lines 88-92](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L88-L92)) enforces Gerrit's 16 KB summary limit
3. CLI Orchestration and Error Recovery
The main() entry point (see [post_review.py, lines 48-70](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L48-L70)) provides:
| Error Code | Behavior |
|---|---|
| 401/403 | Exit with credential error message |
| 404 | Report change not found |
| 409 | Silent exit (change closed/abandoned) |
| 400 + inline comments | Automatic fallback to fold_comments() (see [post_review.py, lines 53-71](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L53-L71))—moves all findings to summary message |
Running the Gerrit Integration
Basic CLI Usage
# Generate OCR review output first
ocr review --format json > review.json
# Post to Gerrit
python3 examples/gerrit_ci/post_review.py \
--gerrit-url https://gerrit.mycompany.com \
--change 12345 \
--revision current \
--user gitbot \
--password $GERRIT_HTTP_PASSWORD \
--input review.json
Dry-Run Mode for Debugging
Validate your payload without posting:
python3 examples/gerrit_ci/post_review.py \
--dry-run \
--input review.json
This activates make_dry_run_poster() (see [post_review.py, lines 64-71](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L64-L71)) to print the generated ReviewInput JSON.
Environment Variable Configuration
For Gerrit-triggered CI jobs, omit flags and use standard environment variables:
export GERRIT_URL=https://gerrit.mycompany.com
export GERRIT_CHANGE_NUMBER=12345
export GERRIT_HTTP_USER=gitbot
export GERRIT_HTTP_PASSWORD=... # From Gerrit Settings → HTTP Password
python3 examples/gerrit_ci/post_review.py --input review.json
The script derives GERRIT_URL from GERRIT_CHANGE_URL if the former is unset (see [post_review.py, lines 52-58](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L52-L58)).
Retry Strategy and Reliability
The integration implements production-grade retry logic:
MAX_ATTEMPTS = 3(see [post_review.py, line 48](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L48))- Exponential backoff:
_sleep(0.5 * (2 ** attempt)) - Conditional retry: Only HTTP 5xx and connection errors trigger retry; 4xx client errors fail immediately
- Timeout propagation: Network timeouts surface immediately to prevent duplicate review posts
Summary
- Primary integration file:
examples/gerrit_ci/post_review.pyprovides complete Gerrit bridge functionality - Authentication: Requires Gerrit HTTP password with preemptive Basic Auth encoding
- Payload mapping:
build_review_input()converts OCR JSON to GerritReviewInputschema - Error resilience: Automatic comment folding on HTTP 400, change-state checking for 409
- Operational modes: Full posting, dry-run debugging, and environment-driven configuration
Frequently Asked Questions
What Gerrit credentials does the integration require?
The post_review.py script requires a Gerrit HTTP password, not your standard account password. Generate this from Gerrit Settings → HTTP Password. The script encodes these credentials in Base64 and includes them preemptively in the Authorization header, because Gerrit's /a/ authenticated endpoints may reject unauthenticated requests without a proper 401 challenge-response cycle.
How does the integration handle Gerrer's 16 KB message limit?
The truncate_message() function (see [post_review.py, lines 88-92](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L88-L92)) automatically clips summary messages exceeding 16,000 bytes. If inline comments push the total payload over limits, the fallback fold_comments() mechanism moves all findings into the summary text rather than individual line comments, ensuring the review still posts successfully.
Can I test the integration without posting to a live Gerrit server?
Yes. Use the --dry-run flag to activate make_dry_run_poster(), which prints the complete ReviewInput JSON to stdout without making any HTTP requests. This mode validates OCR output parsing, payload construction, and message truncation without side effects.
What happens if Gerrit rejects inline comments for a specific change?
When Gerrit returns HTTP 400 with inline comments, the integration automatically invokes fold_comments() (see [post_review.py, lines 53-71](https://github.com/alibaba/open-code-review/blob/main/examples/gerrit_ci/post_review.py#L53-L71)). This failure-recovery path restructures the payload: all file-line specific comments are concatenated into the summary message, and a clean ReviewInput without inline comments is retried. No manual intervention or duplicate CLI invocation is required.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →