Ahmed Codes

Automating Code Reviews with AI and Distributed Systems

By Ahmed Sulaimon2025-10-03

I built the Auto PR Review Assistant to automate the first-pass review of GitHub pull requests. The project grew from a single-process prototype into a multi-tenant microservice stack with deployment, packaging, and production-hardening workstreams. Below I describe the core problem I hit, the design I implemented, operational choices, and what I learned.


Summary


The problem I started with

At first I used global Redis keys:

That worked locally but failed as the app gained multiple installations:

  1. Cross-tenant data leakage — jobs and histories from different GitHub App installations mixed together, exposing other users’ reviews.
  2. Operational scale & hygiene — a single global list made pruning, debugging, and per-tenant policies hard.

Also, hosting a continuously running worker on free managed platforms proved unreliable: instances would spin down when idle and new jobs would sit unprocessed.


My solution: namespaced Redis + microservices

The fix was straightforward: namespace Redis keys by GitHub App installation_id.

Key patterns

Request flow

  1. GitHub → FastAPI webhook listener (validates signature).
  2. Listener extracts installation.id and LPUSHes a job into pr-review-queue:<installation_id>.
  3. Review worker BRPOP(s) the installation-specific queue, fetches PR metadata/diffs, calls the LLM, posts comments, and appends history to pr-review-history:<installation_id>.

Benefits


Hosting & the worker keep-alive pattern

To run a worker on free tiers (that don’t offer persistent background workers) I used a pragmatic approach:

This is a cost-conscious trade-off -- it works well enough for demos and low usage, but for production I recommend a host that supports long-running workers or a paid worker plan.


GitHub App auth: JWTs and installation tokens

GitHub App auth required care:

Add logging and retries around token creation and API calls -- that made the workflow much more robust.


LLM integration: prompting and parsing

AI is the interesting part, but it’s also noisy. My approach:

This makes downstream processing predictable and reduces failure modes from unexpected model output.


CLI & packaging

The CLI offers these commands:

I store API_URL and installation_id in ~/.pr-review/config.json for a frictionless UX. The CLI is packaged and the release workflow uses GitHub Actions + OIDC to publish to PyPI securely (no long-lived PyPI tokens in the repo).


Testing, CI/CD & observability


Small but important engineering bits


What I’d improve next


Closing thoughts

Small design choices can have big outcomes. Namespacing Redis keys by installation_id fixed security and scaling issues early. Operational realities (free-host spin-down) forced pragmatic trade-offs -- the wake endpoint is one such pattern that kept things usable at low cost. Finally, integrating APIs and LLMs taught me the value of strict output contracts, defensive parsing, and strong observability.


Installation

If you want to try the GitHub App, install it here:
https://github.com/apps/auto-pr-review-assistant/installations/new

CLI tool Installation and usage Guide: https://github.com/Ahmedsulaimon/Auto-PR-Review-Assistant/blob/main/cli/README.md