GitLab Code Reviews with Gemini Pro 1.5
Introduction
As a solo developer working on robotics and systems software, one of the biggest gaps is the absence of peer code review. In professional engineering teams, pull request reviews catch edge cases, enforce standards, and maintain documentation.
To bridge this gap, I built an automated AI code review companion:
- GitLab Webhooks fire on Merge Request events (
open,update,merge). - Google Cloud Functions (2nd Gen) receive the webhook payload and retrieve the raw code diffs from the GitLab API.
- Vertex AI (Gemini Pro 1.5) analyzes the diffs with custom system prompts, ranking issues by severity (
minor,moderate,major,critical). - Feedback & Documentation: Gemini posts inline discussion threads directly on the merge request lines and updates the project wiki upon merge.
Architectural Workflow
[GitLab MR Created / Updated]
│
▼ (Webhook POST with secret token)
[Google Cloud Function (Python 3.11)]
│
├─► Fetch commit diffs via python-gitlab
│
├─► Call Vertex AI (Gemini Pro 1.5) with diff JSON
│
▼
[Gemini Evaluates Quality, ROS2 Idioms & Security]
│
▼
[Post Inline Discussions to GitLab MR / Update Wiki]
Cloud Infrastructure Setup
GCP Configuration
-
Enable APIs:
- Cloud Functions API
- Secret Manager API
- Vertex AI API
-
Secrets Management:
- Store
GITLAB_WEBHOOK_SECRET_IDto authenticate incoming webhooks. - Store
GITLAB_BOT_TOKENfor the bot user account withapipermissions andDeveloperrole on the repository.
- Store
-
Cloud Function Specs:
- Runtime: Python 3.11 (2nd Gen)
- Trigger: HTTP trigger
- Memory: 512 MiB
The Code: Webhook Ingestion & Diff Extraction
Using python-gitlab, we inspect the merge request diffs to extract line changes:
import os
import json
import gitlab
from google.cloud import secretmanager
import vertexai
from vertexai.generative_models import GenerativeModel
def handle_gitlab_webhook(request):
# Verify token
token = request.headers.get("X-Gitlab-Token")
if token != get_secret("GITLAB_WEBHOOK_SECRET_ID"):
return ("Unauthorized", 401)
event = request.get_json()
object_kind = event.get("object_kind")
if object_kind != "merge_request":
return ("Ignored", 200)
action = event.get("object_attributes", {}).get("action")
mr_iid = event.get("object_attributes", {}).get("iid")
project_id = event.get("project", {}).get("id")
gl = gitlab.Gitlab("https://gitlab.com", private_token=get_secret("GITLAB_BOT_TOKEN"))
project = gl.projects.get(project_id)
mr = project.mergerequests.get(mr_iid)
if action in ["open", "update"]:
review_merge_request(project, mr)
elif action == "merge":
update_wiki_documentation(project, mr)
return ("OK", 200)
Prompt Engineering for Structured Code Review
Rather than parsing individual diff lines manually in Python, we pass the raw diff array to Gemini with strict system instructions:
You are a helpful code reviewer. Your mission is to review code changes for a ROS2 package and provide feedback based on the changes.
When reviewing code, focus on:
1. Correctness: Potential logic flaws, memory leaks, unhandled exceptions.
2. ROS2 Best Practices: Node naming, parameter handling, QoS profiles, lifecycle transitions.
3. Security: Buffer overflows, bounds checking, input sanitization.
4. Maintainability: Code structure, modularity, readability.
Label all findings with severity:
- minor: Style, typos, documentation.
- moderate: Code quality, sub-optimal implementations.
- major: Logic errors, performance bottlenecks.
- critical: Security bugs, memory corruption, crashes.
Results & Lessons Learned
- Diff Context Understanding: Gemini 1.5 Pro easily understood the Git unified diff headers (
@@ -start,len +start,len @@), correctly isolating added lines (+) from deletions (-). - Context Window Size: Thanks to Gemini’s 1M+ token context window, entire multi-file merge requests could be evaluated at once, allowing the model to detect cross-file interface incompatibilities.
- Automated Wiki Sync: When an MR merged, Gemini synthesized the changes into release notes and updated the GitLab wiki automatically, keeping documentation fresh with zero human friction.