An AI-powered code review system using DeepSeek LLM with Temporal workflow orchestration, GitLab integration, and agentic capabilities.
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β GitLab/CLI ββββββΆβ Temporal ββββββΆβ Worker β
β (Trigger) β β Server β β (Activities) β
βββββββββββββββββββ βββββββββββββββββββ ββββββββββ¬βββββββββ
β
βββββββββββββββββββ β
β Knowledge Store ββββββββββββββββ€
β (Framework RAG) β β
βββββββββββββββββββ β
βΌ
βββββββββββββββββββ
β DeepSeek LLM β
β (via Ollama) β
βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β GitLab β
β (Post Reviews) β
βββββββββββββββββββ
- AI-Powered Reviews: Uses DeepSeek LLM for intelligent code analysis
- GitLab Integration: Automatically post reviews to merge requests
- Framework-Aware: Index your codebase for context-aware reviews
- Agentic Mode: Multi-step reasoning with specialized tools
- Configurable Logging: Multiple log levels, formats, and outputs
- Graceful Shutdown: Clean shutdown handling for all services
| Component | Description |
|---|---|
cmd/reviewer |
CLI for direct code review without Temporal |
cmd/worker |
Temporal worker that processes review workflows |
cmd/trigger |
CLI to start Temporal workflows |
cmd/indexer |
Index GitHub repositories for framework-aware reviews |
cmd/server |
HTTP server for GitLab webhook integration |
- Go 1.21+
- Ollama with DeepSeek model installed
- Temporal (optional, for workflow orchestration)
- GitLab (optional, for MR integration)
# Install Ollama (https://ollama.ai)
curl -fsSL https://ollama.ai/install.sh | sh
# Pull DeepSeek model
ollama pull deepseek-coder:1.3b
# or larger model
ollama pull deepseek-coder:6.7b# Using Docker
docker run -d --name temporal \
-p 7233:7233 \
temporalio/auto-setup:latest# Clone the repository
git clone <repository-url>
cd code-reviewer
# Build all binaries
go build -o bin/ ./cmd/...
# Run tests
go test ./...The fastest way to run the entire stack locally:
# Start all services (Temporal, Ollama, ChromaDB, Server, Worker)
docker-compose up -d
# Pull the DeepSeek model (first time only)
docker-compose exec ollama ollama pull deepseek-coder:6.7b
# Check service health
curl http://localhost:8080/health
# View Temporal UI
open http://localhost:8088
# View logs
docker-compose logs -f server worker
# Stop all services
docker-compose down| Service | Port | Description |
|---|---|---|
server |
8080 | HTTP API and GitLab webhook server |
worker |
- | Temporal worker for processing reviews |
temporal |
7233 | Temporal workflow engine |
temporal-ui |
8088 | Temporal web dashboard |
ollama |
11434 | Local LLM server |
chromadb |
8000 | Vector database for RAG |
postgres |
5432 | Database for Temporal |
Create a .env file for GitLab integration:
# .env
GITLAB_URL=https://gitlab.yourcompany.com
GITLAB_TOKEN=your-gitlab-tokenUse the Makefile for common operations:
# Build server and worker binaries (with version info)
make build
# Run all tests
make test
# Run tests with coverage report
make test-coverage
# Run server locally
make run-server
# Run worker locally
make run-worker
# Format code
make fmt
# Run linter (requires golangci-lint)
make lint
# Check for vulnerabilities (requires govulncheck)
make vuln
# Build Docker image
make docker
# Clean build artifacts
make clean
# Show all available commands
make helpThe Makefile automatically injects version information:
make build
./bin/server &
curl http://localhost:8080/health | jq
# {
# "status": "ok",
# "version": "v1.0.0",
# "build_time": "2024-01-15_10:30:45",
# "git_commit": "abc123",
# "uptime": "5s",
# "go_version": "go1.21.0",
# "services": {"llm": "healthy", "gitlab": "configured"}
# }The simplest way to review code:
# Review a single file
./bin/reviewer -file path/to/code.go
# Specify model
./bin/reviewer -file code.go -model deepseek-coder:6.7b
# With framework context (after indexing)
./bin/reviewer -file code.go -framework gin
# With debug logging
./bin/reviewer -file code.go -log-level debugIndex a GitHub repository to provide framework-aware reviews:
# Index the Gin framework
./bin/indexer index -name gin -repo gin-gonic/gin
# Index your internal framework
./bin/indexer index -name myframework -repo yourorg/framework
# List indexed frameworks
./bin/indexer list
# Search indexed code
./bin/indexer search -name gin -query "middleware"For production use with workflow orchestration:
# Terminal 1: Start the worker with GitLab integration
./bin/worker \
-llm-url http://localhost:11434 \
-model deepseek-coder:1.3b \
-gitlab-url https://gitlab.yourcompany.com \
-gitlab-token YOUR_TOKEN \
-log-level info \
-log-format json
# Terminal 2: Trigger a review
./bin/trigger -file path/to/code.go
# With agentic multi-step reasoning
./bin/trigger -file code.go -agent
# With framework context
./bin/trigger -file code.go -framework gin -agent# Start the webhook server
./bin/server \
-addr :8080 \
-gitlab-url https://gitlab.yourcompany.com \
-gitlab-token YOUR_TOKEN \
-log-level info
# Configure GitLab webhook:
# 1. Go to Project > Settings > Webhooks
# 2. URL: http://your-server:8080/webhook
# 3. Trigger: Merge request events# Review and post to GitLab MR
curl -X POST http://localhost:8080/api/review \
-H "Content-Type: application/json" \
-d '{
"file_path": "main.go",
"diff": "+func insecure() { exec.Command(userInput) }",
"project_id": 123,
"merge_request_id": 42,
"post_to_mr": true
}'
# Batch review multiple files
curl -X POST http://localhost:8080/api/review/batch \
-H "Content-Type: application/json" \
-d '{
"files": [
{"file_path": "a.go", "diff": "+code"},
{"file_path": "b.go", "diff": "+more code"}
],
"project_id": 123,
"merge_request_id": 42,
"post_to_mr": true
}'| Variable | Description | Default |
|---|---|---|
LLM_URL |
Ollama API endpoint | http://localhost:11434 |
LLM_MODEL |
Model to use | deepseek-coder:1.3b |
TEMPORAL_HOST |
Temporal server address | localhost:7233 |
GITLAB_URL |
GitLab instance URL | - |
GITLAB_TOKEN |
GitLab API token | - |
LOG_LEVEL |
Log level (debug, info, warn, error) | info |
LOG_FORMAT |
Log format (text, json) | text |
LOG_OUTPUT |
Log output (stdout, stderr, file path) | stdout |
KNOWLEDGE_DIR |
Directory for framework data | ~/.code-reviewer/knowledge |
reviewer:
-file string Path to file to review
-model string LLM model name (default "deepseek-coder:1.3b")
-ollama string Ollama URL (default "http://localhost:11434")
-framework string Framework name for context-aware review
-log-level string Log level: debug, info, warn, error (default "info")
worker:
-llm-url string LLM URL (default "http://localhost:11434")
-model string LLM model (default "deepseek-coder:6.7b")
-temporal string Temporal host (default "localhost:7233")
-gitlab-url string GitLab server URL
-gitlab-token string GitLab access token
-knowledge-dir string Knowledge store directory
-log-level string Log level (default "info")
-log-format string Log format: text, json (default "text")
-log-output string Log output: stdout, stderr, or file path
server:
-addr string Server address (default ":8080")
-llm-url string LLM URL (default "http://localhost:11434")
-model string LLM model (default "deepseek-coder:1.3b")
-gitlab-url string GitLab server URL
-gitlab-token string GitLab access token
-log-level string Log level (default "info")
-log-format string Log format: text, json (default "text")
-log-output string Log output: stdout, stderr, or file path
trigger:
-file string Path to file to review
-framework string Framework for context
-agent Enable agentic multi-step review
-temporal string Temporal host (default "localhost:7233")
indexer:
index -name string -repo string Index a GitHub repository
list List indexed frameworks
search -name string -query string Search indexed code
The system supports configurable logging with multiple levels and output formats.
| Level | Description |
|---|---|
debug |
Verbose debugging information |
info |
Normal operational messages |
warn |
Warning messages |
error |
Error messages |
Text format (default):
2024-01-15 10:30:45 [INFO] Starting Code Review Worker...
2024-01-15 10:30:45 [INFO] LLM: http://localhost:11434 (model: deepseek-coder:1.3b)
JSON format:
{"time":"2024-01-15T10:30:45Z","level":"INFO","msg":"Starting Code Review Worker..."}
{"time":"2024-01-15T10:30:45Z","level":"INFO","msg":"LLM: http://localhost:11434 (model: deepseek-coder:1.3b)"}./bin/worker -log-output /var/log/code-reviewer/worker.logAll services support graceful shutdown:
- Worker: Completes in-progress tasks before stopping (30s timeout)
- Server: Finishes active HTTP requests before stopping (30s timeout)
Send SIGINT (Ctrl+C) or SIGTERM to trigger graceful shutdown.
When using -agent mode, the system uses a multi-step reasoning approach with these tools:
| Tool | Description |
|---|---|
search_framework |
Search indexed framework code for patterns and best practices |
analyze_security |
Deep security vulnerability analysis |
analyze_performance |
Performance issue detection |
suggest_fix |
Generate code fixes for identified issues |
final_review |
Compile findings into final review result |
The agent performs up to 5 reasoning steps, selecting appropriate tools based on the code being reviewed.
When posting reviews to GitLab, the system creates:
- Summary Comment: Overview with issue counts by severity
- Inline Comments: Comments on specific lines (when possible)
Example summary posted to MR:
## π€ Automated Code Review
**Files Reviewed:** 3 / 3
**Issues Found:** 5
### Issues by Severity
| Severity | Count |
|----------|-------|
| π΄ Critical | 1 |
| π High | 2 |
| π‘ Medium | 1 |
| π’ Low | 1 |
### Detailed Findings
#### π `db/query.go`
- π΄ **[SECURITY]** SQL Injection (line 42)
- User input directly concatenated into SQL query
- π‘ Use parameterized queries insteadReviews are returned as JSON:
{
"issues": [
{
"type": "security",
"severity": "high",
"line": 42,
"title": "SQL Injection",
"description": "User input directly concatenated into SQL query",
"suggestion": "Use parameterized queries instead"
}
],
"summary": "Found 1 critical security issue",
"risk_score": 8,
"recommendation": "Fix security issues before merging"
}.
βββ cmd/
β βββ reviewer/ # Direct review CLI
β βββ worker/ # Temporal worker
β βββ trigger/ # Workflow trigger CLI
β βββ indexer/ # Framework indexer CLI
β βββ server/ # GitLab webhook server
βββ internal/
β βββ llm/ # LLM client (Ollama/OpenAI)
β βββ reviewer/ # Core review logic
β βββ agent/ # Agentic reasoning with tools
β βββ workflow/ # Temporal workflows & activities
β βββ knowledge/ # Framework knowledge store
β βββ indexer/ # Go AST parser for indexing
β βββ github/ # GitHub repo cloning
β βββ gitlab/ # GitLab API client & review poster
β βββ logger/ # Configurable logging
βββ samples/ # Sample vulnerable code for testing
βββ frameworks/ # Indexed framework data (generated)
Test the system with provided samples:
./bin/reviewer -file samples/sql_injection.go
./bin/reviewer -file samples/command_injection.go
./bin/reviewer -file samples/hardcoded_secrets.go
./bin/reviewer -file samples/xss_vulnerability.go
./bin/reviewer -file samples/concurrency_issues.goThe system handles common LLM quirks:
- JSON with
//comments (stripped automatically) - Numbers as strings (
"10"vs10) - Extra text around JSON (extracted automatically)
Ensure Ollama is running:
ollama serve
# or check if already running
curl http://localhost:11434/api/tagsEnsure Temporal is running:
docker ps | grep temporal
# or start it
docker run -d -p 7233:7233 temporalio/auto-setup:latestVerify your token has the required permissions:
apiscope for full API access- Or at minimum:
read_api,read_repository,write_repository
Check:
- GitLab URL and token are configured
- Token has permission to comment on the project
- Project ID and MR IID are correct
- Check logs for specific errors (
-log-level debug)
Deploy to Kubernetes using the included Helm chart:
# Add Temporal Helm repo (dependency)
helm repo add temporal https://charts.temporal.io
helm repo update
# Install with default values
helm install code-reviewer ./helm/code-reviewer
# Install with custom values
helm install code-reviewer ./helm/code-reviewer \
--set gitlab.url=https://gitlab.yourcompany.com \
--set gitlab.token=your-token \
--set ollama.model=deepseek-coder:6.7b
# Install with values file
helm install code-reviewer ./helm/code-reviewer -f my-values.yaml
# Upgrade existing installation
helm upgrade code-reviewer ./helm/code-reviewer
# Uninstall
helm uninstall code-reviewerKey configuration options:
# values.yaml
replicaCount:
server: 2
worker: 3
image:
repository: code-reviewer
tag: latest
pullPolicy: IfNotPresent
ollama:
enabled: true
model: deepseek-coder:6.7b
externalUrl: "" # Use if Ollama is external
gitlab:
url: ""
token: ""
existingSecret: "" # Use existing secret for token
temporal:
enabled: true
externalHost: "" # Use if Temporal is external
resources:
server:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
worker:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
ingress:
enabled: true
className: nginx
hosts:
- host: code-reviewer.example.com
paths:
- path: /
pathType: Prefix
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80If you have existing Temporal or Ollama instances:
helm install code-reviewer ./helm/code-reviewer \
--set temporal.enabled=false \
--set temporal.externalHost=temporal.default.svc:7233 \
--set ollama.enabled=false \
--set ollama.externalUrl=http://ollama.default.svc:11434For production, use a Kubernetes secret:
# Create secret
kubectl create secret generic gitlab-credentials \
--from-literal=token=your-gitlab-token
# Reference in Helm
helm install code-reviewer ./helm/code-reviewer \
--set gitlab.url=https://gitlab.yourcompany.com \
--set gitlab.existingSecret=gitlab-credentialsMIT