A complete AI-powered pull request review system with automated security scanning, code analysis, and intelligent feedback generation.
- Prerequisites
- Architecture Overview
- Installation Steps
- Configuration
- Deployment
- Verification
- GitHub Webhook Setup
- Troubleshooting
You need a running Kubernetes cluster. We recommend k0s for simplicity.
Follow the official k0s installation guide: π k0s Installation Documentation
Quick install on Ubuntu/Debian:
curl -sSLf https://get.k0s.sh | sudo sh
sudo k0s install controller --single
sudo k0s start
sudo k0s statusConfigure kubectl:
# Get kubeconfig
sudo k0s kubeconfig admin > ~/.kube/config
# Verify cluster
kubectl get nodes
kubectl get pods -AYou'll need API keys for:
- OpenAI - For PR-Agent (GPT-4)
- Anthropic - For Summarizer (Claude)
- GitHub - Personal Access Token with repo permissions
- Semgrep - App Token from semgrep.com (optional but recommended)
Ensure all images are built and pushed to your registry (e.g., ghcr.io):
ghcr.io/YOUR_USERNAME/orchestrator:VERSIONghcr.io/YOUR_USERNAME/pr-agent:VERSIONghcr.io/YOUR_USERNAME/summarizer-agent:VERSIONghcr.io/YOUR_USERNAME/github-mcp-server:VERSIONghcr.io/YOUR_USERNAME/semgrep-service:VERSION
Services:
- Orchestrator - Main coordinator, receives GitHub webhooks
- PR-Agent - Generates PR descriptions and reviews (GPT-4)
- Semgrep Service - Security scanning and vulnerability detection
- Summarizer Agent - Synthesizes all feedback (Claude)
- GitHub MCP Server - Posts comments back to GitHub
kubectl apply -f ns.ymlVerify:
kubectl get namespace agensys-demo-1Create a file keys_tokens.txt with your API keys:
cat > keys_tokens.txt << 'EOF'
OPENAI_API_KEY=sk-proj-your-openai-key-here
ANTHROPIC_API_KEY=sk-ant-api03-your-anthropic-key-here
GITHUB_TOKEN=ghp_your-github-token-here
SEMGREP_APP_TOKEN=your-semgrep-token-here
EOFCreate the secret:
kubectl create secret generic api-secrets \
--from-env-file=keys_tokens.txt \
-n agensys-demo-1
# Verify
kubectl get secret api-secrets -n agensys-demo-1keys_tokens.txt after creating the secret:
rm keys_tokens.txtIf using a private registry (e.g., GitHub Container Registry):
kubectl create secret docker-registry ghcr-secret \
--docker-server=ghcr.io \
--docker-username=YOUR_GITHUB_USERNAME \
--docker-password=YOUR_GITHUB_PAT \
--docker-email=YOUR_EMAIL \
--namespace=agensys-demo-1
# Verify
kubectl get secret ghcr-secret -n agensys-demo-1Deploy in the following order:
# Deploy
kubectl apply -f semgrep/deploy.yml
kubectl apply -f semgrep/svc.yml
# Wait for ready
kubectl wait --for=condition=available --timeout=60s \
deployment/semgrep-service -n agensys-demo-1
# Verify
kubectl get pods -n agensys-demo-1 -l app=semgrep-service
kubectl logs -l app=semgrep-service -n agensys-demo-1 --tail=20# Deploy
kubectl apply -f pr-agent/cm.yml
kubectl apply -f pr-agent/deploy.yml
kubectl apply -f pr-agent/svc.yml
# Wait for ready
kubectl wait --for=condition=available --timeout=60s \
deployment/pr-agent -n agensys-demo-1
# Verify
kubectl get pods -n agensys-demo-1 -l app=pr-agent
kubectl logs -l app=pr-agent -n agensys-demo-1 --tail=20# Deploy
kubectl apply -f summarizer-agent/cm.yml
kubectl apply -f summarizer-agent/deploy.yml
kubectl apply -f summarizer-agent/svc.yml
# Wait for ready
kubectl wait --for=condition=available --timeout=60s \
deployment/summarizer-agent -n agensys-demo-1
# Verify
kubectl get pods -n agensys-demo-1 -l app=summarizer-agent
kubectl logs -l app=summarizer-agent -n agensys-demo-1 --tail=20# Deploy
kubectl apply -f github-mcp/cm.yml
kubectl apply -f github-mcp/deploy.yml
kubectl apply -f github-mcp/svc.yml
# Wait for ready
kubectl wait --for=condition=available --timeout=60s \
deployment/github-mcp-server -n agensys-demo-1
# Verify
kubectl get pods -n agensys-demo-1 -l app=github-mcp-server
kubectl logs -l app=github-mcp-server -n agensys-demo-1 --tail=20# Deploy
kubectl apply -f orchestrator/cm.yml
kubectl apply -f orchestrator/deploy.yml
kubectl apply -f orchestrator/svc.yml
# Wait for ready
kubectl wait --for=condition=available --timeout=60s \
deployment/orchestrator -n agensys-demo-1
# Verify
kubectl get pods -n agensys-demo-1 -l app=orchestrator
kubectl logs -l app=orchestrator -n agensys-demo-1 --tail=20Alternatively, use the provided script:
# Make executable
chmod +x s.sh
# Deploy all
./s.sh
# Check status
kubectl get pods -n agensys-demo-1# Check all pods are running
kubectl get pods -n agensys-demo-1
# Expected output:
# NAME READY STATUS RESTARTS AGE
# orchestrator-xxx-xxx 1/1 Running 0 2m
# pr-agent-xxx-xxx 1/1 Running 0 3m
# semgrep-service-xxx-xxx 1/1 Running 0 5m
# summarizer-agent-xxx-xxx 1/1 Running 0 3m
# github-mcp-server-xxx-xxx 1/1 Running 0 3mkubectl get svc -n agensys-demo-1
# Expected output:
# NAME TYPE CLUSTER-IP PORT(S)
# orchestrator ClusterIP 10.x.x.x 8085/TCP
# pr-agent ClusterIP 10.x.x.x 80/TCP
# semgrep-service ClusterIP 10.x.x.x 80/TCP
# summarizer-agent ClusterIP 10.x.x.x 80/TCP
# github-mcp-server ClusterIP 10.x.x.x 80/TCP# Get a shell in orchestrator
kubectl exec -it deployment/orchestrator -n agensys-demo-1 -- sh
# Inside the pod, test connectivity
wget -O- http://pr-agent/health 2>/dev/null || echo "Check logs"
wget -O- http://semgrep-service/health 2>/dev/null || echo "Check logs"
wget -O- http://summarizer-agent/health 2>/dev/null || echo "Check logs"
wget -O- http://github-mcp-server/health 2>/dev/null || echo "Check logs"
exitChoose one option:
kubectl patch svc orchestrator -n agensys-demo-1 \
-p '{"spec":{"type":"NodePort"}}'
# Get the node port
kubectl get svc orchestrator -n agensys-demo-1
# Your webhook URL: http://NODE_IP:NODE_PORT/webhookkubectl patch svc orchestrator -n agensys-demo-1 \
-p '{"spec":{"type":"LoadBalancer"}}'
# Wait for external IP
kubectl get svc orchestrator -n agensys-demo-1 -w
# Your webhook URL: http://EXTERNAL_IP:8085/webhookapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orchestrator-ingress
namespace: agensys-demo-1
spec:
rules:
- host: ai-pr-review.yourdomain.com
http:
paths:
- path: /webhook
pathType: Prefix
backend:
service:
name: orchestrator
port:
number: 8085-
Go to your GitHub repository
-
Click Settings β Webhooks β Add webhook
-
Configure:
- Payload URL:
http://YOUR_IP:PORT/webhook - Content type:
application/json - Events: Select "Pull requests"
- Active: β Checked
- Payload URL:
-
Click Add webhook
- Create a new PR in your repository
- Check orchestrator logs:
kubectl logs -f deployment/orchestrator -n agensys-demo-1You should see:
{"level":"info","message":"received GitHub PR webhook"}
{"level":"info","message":"starting PR processing pipeline"}# All orchestrator logs
kubectl logs -f deployment/orchestrator -n agensys-demo-1
# Specific service
kubectl logs -f deployment/pr-agent -n agensys-demo-1
kubectl logs -f deployment/semgrep-service -n agensys-demo-1
kubectl logs -f deployment/summarizer-agent -n agensys-demo-1
kubectl logs -f deployment/github-mcp-server -n agensys-demo-1
# All pods with label
kubectl logs -f -l app=orchestrator -n agensys-demo-1kubectl top pods -n agensys-demo-1# Follow orchestrator logs and trigger a PR
kubectl logs -f deployment/orchestrator -n agensys-demo-1 | grep "pr_number"# Check pod status
kubectl get pods -n agensys-demo-1
# Describe pod to see events
kubectl describe pod POD_NAME -n agensys-demo-1
# Check logs
kubectl logs POD_NAME -n agensys-demo-1Common causes:
- Image pull errors β Check
ghcr-secret - Missing secrets β Verify
api-secretsexists - Resource constraints β Check
kubectl describe node
# Check image pull secret
kubectl get secret ghcr-secret -n agensys-demo-1
# Verify image exists
docker pull ghcr.io/YOUR_USERNAME/IMAGE:TAG
# Recreate secret if needed
kubectl delete secret ghcr-secret -n agensys-demo-1
# Then create again (Step 3)# Check if pod is ready
kubectl get pods -n agensys-demo-1
# Check service endpoints
kubectl get endpoints SERVICE_NAME -n agensys-demo-1
# Test from orchestrator pod
kubectl exec -it deployment/orchestrator -n agensys-demo-1 -- \
wget -O- http://SERVICE_NAME/health# Check orchestrator logs
kubectl logs -f deployment/orchestrator -n agensys-demo-1
# Check if webhook is configured correctly
# Verify GitHub webhook deliveries in repo settings
# Test manually
curl -X POST http://ORCHESTRATOR_URL/webhook \
-H "Content-Type: application/json" \
-d '{"action":"opened","number":1,"pull_request":{...}}'# Check if secret exists
kubectl get secret api-secrets -n agensys-demo-1
# View secret keys (not values)
kubectl describe secret api-secrets -n agensys-demo-1
# Recreate if needed
kubectl delete secret api-secrets -n agensys-demo-1
# Then create again (Step 2)# Build and push new image
docker build -t ghcr.io/YOUR_USERNAME/SERVICE:NEW_TAG .
docker push ghcr.io/YOUR_USERNAME/SERVICE:NEW_TAG
# Update deployment
kubectl set image deployment/SERVICE_NAME \
CONTAINER_NAME=ghcr.io/YOUR_USERNAME/SERVICE:NEW_TAG \
-n agensys-demo-1
# Watch rollout
kubectl rollout status deployment/SERVICE_NAME -n agensys-demo-1# View history
kubectl rollout history deployment/SERVICE_NAME -n agensys-demo-1
# Rollback to previous
kubectl rollout undo deployment/SERVICE_NAME -n agensys-demo-1# Scale up
kubectl scale deployment/SERVICE_NAME --replicas=3 -n agensys-demo-1
# Scale down
kubectl scale deployment/SERVICE_NAME --replicas=1 -n agensys-demo-1# Delete all deployments
kubectl delete -f orchestrator/
kubectl delete -f pr-agent/
kubectl delete -f semgrep/
kubectl delete -f summarizer-agent/
kubectl delete -f github-mcp/
# Delete secrets
kubectl delete secret api-secrets -n agensys-demo-1
kubectl delete secret ghcr-secret -n agensys-demo-1
# Delete namespace (removes everything)
kubectl delete namespace agensys-demo-1- k0s Documentation: https://docs.k0sproject.io/
- Kubernetes Documentation: https://kubernetes.io/docs/
- GitHub Webhooks: https://docs.github.com/en/webhooks
- Semgrep: https://semgrep.dev/
- OpenAI API: https://platform.openai.com/docs/
- Anthropic API: https://docs.anthropic.com/
Your deployment is successful when:
- β All 5 pods are Running
- β All services have endpoints
- β Orchestrator logs show "starting orchestrator"
- β GitHub webhook deliveries show success (200)
- β PR comments appear automatically on new PRs
Test with a real PR:
- Create a PR with some code
- Check orchestrator logs:
kubectl logs -f deployment/orchestrator -n agensys-demo-1 - Wait 30-60 seconds
- See automated review comment on GitHub PR! π
Need help? Check the logs first, then review the troubleshooting section above.
