Przejdź do głównej zawartości

Automatyczne przeglądy kodu

Przekształć swój proces przeglądów kodu dzięki inteligentnym możliwościom analizy Claude Code. Ten przewodnik obejmuje zautomatyzowane przepływy przeglądów, niestandardowe reguły przeglądów i integrację z popularnymi platformami.

Spójność

  • Te same standardy stosowane za każdym razem
  • Brak zmęczenia recenzenta
  • Wyłapuje subtelne problemy
  • Egzekwuje konwencje zespołu

Szybkość

  • Natychmiastowa informacja zwrotna
  • Dostępność 24/7
  • Przetwarzanie równoległe
  • Brak blokowania na recenzentach

Nauka

  • Edukacyjna informacja zwrotna
  • Sugestie najlepszych praktyk
  • Wskazówki ulepszania kodu
  • Dzielenie się wiedzą zespołową
  1. Prosty przegląd pliku

    Okno terminala
    # Przejrzyj pojedynczy plik
    claude review src/components/UserAuth.js \
    --output review-comments.md
    # Przegląd z konkretnym skupieniem
    claude review src/api/endpoints.js \
    --focus "security,performance,error-handling" \
    --severity "error,warning"
  2. Przegląd oparty na diff

    Okno terminala
    # Przejrzyj zmiany między gałęziami
    claude review \
    --base main \
    --head feature/new-auth \
    --format github-pr
    # Przejrzyj zmiany staged
    git diff --staged | claude review \
    --input - \
    --context "Aplikacja React z TypeScript"
  3. Przegląd wsadowy

    Okno terminala
    # Przejrzyj wszystkie zmienione pliki
    git diff --name-only main...HEAD | \
    xargs -I {} claude review {} \
    --output reviews/{}.md
    # Połącz przeglądy
    cat reviews/*.md > combined-review.md

Niestandardowe reguły przeglądu

.claude-review.yml
version: 1
rules:
- name: security-checks
description: "Wykrywanie luk bezpieczeństwa"
patterns:
- "zakodowane hasła lub klucze API"
- "luki SQL injection"
- "wektory ataków XSS"
- "niebezpieczna deserializacja"
severity: error
- name: performance-checks
description: "Antywzorce wydajności"
patterns:
- "problemy zapytań N+1"
- "niepotrzebne re-rendery"
- "operacje blokujące w kodzie async"
- "wycieki pamięci"
severity: warning
- name: code-quality
description: "Ogólna jakość kodu"
patterns:
- "funkcje dłuższe niż 50 linii"
- "złożoność cyklomatyczna > 10"
- "zduplikowane bloki kodu"
- "brakująca obsługa błędów"
severity: info
focus_areas:
frontend:
- accessibility
- responsive design
- browser compatibility
- performance metrics
backend:
- API design
- database queries
- error handling
- logging practices
security:
- authentication
- authorization
- data validation
- encryption
ignore_patterns:
- "**/*.test.js"
- "**/node_modules/**"
- "**/*.generated.ts"
.github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
automated-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Claude Code
run: |
npm install -g @anthropic-ai/claude-code
claude --version
- name: Load Review Configuration
run: |
if [ -f .claude-review.yml ]; then
export CLAUDE_REVIEW_CONFIG=.claude-review.yml
fi
- name: Analyze Changed Files
id: analyze
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# Pobierz zmienione pliki
CHANGED_FILES=$(git diff --name-only \
origin/${{ github.base_ref }}...${{ github.sha }} \
-- '*.js' '*.ts' '*.jsx' '*.tsx' '*.py' '*.go')
# Utwórz przegląd dla każdego pliku
echo "## Wyniki przeglądu Claude Code" > review.md
echo "" >> review.md
for file in $CHANGED_FILES; do
if [ -f "$file" ]; then
echo "### $file" >> review.md
claude review "$file" \
--base origin/${{ github.base_ref }} \
--config $CLAUDE_REVIEW_CONFIG \
--format markdown >> review.md
echo "" >> review.md
fi
done
# Wygeneruj podsumowanie
claude "Podsumuj te odkrycia przeglądu i uporządkuj problemy według priorytetu" \
--input review.md \
--output summary.md
- name: Post Review Comments
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review.md', 'utf8');
const summary = fs.readFileSync('summary.md', 'utf8');
// Utwórz przegląd
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
await github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
body: summary,
event: 'COMMENT',
comments: parseReviewComments(review)
});
function parseReviewComments(review) {
// Parsuj review.md i utwórz komentarze inline
// Implementacja zależy od formatu przeglądu
return [];
}
- name: Update PR Status
run: |
# Sprawdź problemy blokujące
if grep -q "severity: error" review.md; then
echo "::error::Znaleziono krytyczne problemy w przeglądzie kodu"
exit 1
fi

Integracja GitLab CI

.gitlab-ci.yml
stages:
- review
claude-code-review:
stage: review
image: node:18
only:
- merge_requests
before_script:
- npm install -g @anthropic-ai/claude-code-cli
- export ANTHROPIC_API_KEY=$CLAUDE_API_KEY
script:
# Pobierz zmiany MR
- |
git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
CHANGED_FILES=$(git diff --name-only origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD)
# Uruchom przeglądy
- |
echo "## Przegląd Claude Code" > review.md
for file in $CHANGED_FILES; do
if [[ -f "$file" ]]; then
echo "### $file" >> review.md
claude review "$file" \
--context "GitLab MR: $CI_MERGE_REQUEST_TITLE" \
--format markdown >> review.md || true
fi
done
# Opublikuj przegląd jako komentarz MR
- |
REVIEW_CONTENT=$(cat review.md | jq -Rs .)
curl --request POST \
--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
--header "Content-Type: application/json" \
--data "{\"body\": $REVIEW_CONTENT}" \
"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"
artifacts:
reports:
codequality: claude-review-report.json
paths:
- review.md
  1. Przeglądy świadome architektury

    Okno terminala
    # Zbuduj kontekst architektury
    claude analyze --architecture src/ \
    --output architecture.json
    # Użyj architektury w przeglądach
    claude review src/services/NewService.js \
    --context-file architecture.json \
    --check "spójność z istniejącymi wzorcami"
  2. Kontekst historyczny

    Okno terminala
    # Dołącz historię commitów
    git log --oneline -n 20 --pretty=format:"%h %s" > recent-commits.txt
    claude review src/api/auth.js \
    --context-file recent-commits.txt \
    --check "zgodność z ostatnimi zmianami"
  3. Linie bazowe wydajności

    Okno terminala
    # Dołącz dane wydajności
    npm run benchmark > performance-baseline.txt
    claude review src/components/DataGrid.jsx \
    --context-file performance-baseline.txt \
    --focus "wpływ na wydajność"

Progresywne przeglądy

progressive_review.py
import subprocess
import json
class ProgressiveReviewer:
def __init__(self):
self.severity_levels = ['error', 'warning', 'info', 'style']
def review_file(self, file_path):
"""Progresywnie przeglądaj plik ze wzrastającą dokładnością"""
issues = []
for level in self.severity_levels:
# Uruchom przegląd na aktualnym poziomie
result = subprocess.run([
'claude', 'review', file_path,
'--severity', level,
'--format', 'json'
], capture_output=True, text=True)
level_issues = json.loads(result.stdout)
# Zatrzymaj jeśli znaleziono krytyczne problemy
if level == 'error' and level_issues:
issues.extend(level_issues)
break
issues.extend(level_issues)
return self.prioritize_issues(issues)
def prioritize_issues(self, issues):
"""Sortuj i deduplikuj problemy"""
# Usuń duplikaty
unique_issues = []
seen = set()
for issue in issues:
key = (issue['file'], issue['line'], issue['message'])
if key not in seen:
seen.add(key)
unique_issues.append(issue)
# Sortuj według ważności i numeru linii
return sorted(unique_issues,
key=lambda x: (x['severity'], x['line']))

Reguły specyficzne dla zespołu

team-review-config.js
const teamRules = {
frontend: {
focus: ['accessibility', 'performance', 'responsive'],
ignore: ['*.generated.ts', '*.d.ts'],
customChecks: [
'Zależności React hooks',
'Właściwe error boundaries',
'Stany ładowania',
'Tagi meta SEO'
]
},
backend: {
focus: ['security', 'scalability', 'error-handling'],
ignore: ['*/migrations/*', '*/seeds/*'],
customChecks: [
'Zapobieganie SQL injection',
'Rate limiting',
'Właściwe logowanie',
'Obsługa transakcji'
]
},
mobile: {
focus: ['performance', 'offline-support', 'battery'],
ignore: ['*.android.js', '*.ios.js'],
customChecks: [
'Wycieki pamięci',
'Optymalizacja sieci',
'Kod specyficzny dla platformy',
'Wpływ na rozmiar aplikacji'
]
}
};
function getTeamRules(filePath) {
// Określ zespół na podstawie ścieżki pliku
if (filePath.includes('/frontend/')) return teamRules.frontend;
if (filePath.includes('/backend/')) return teamRules.backend;
if (filePath.includes('/mobile/')) return teamRules.mobile;
return teamRules.frontend; // domyślny
}
  1. Utwórz zbieranie metryk

    review_metrics.py
    import json
    from datetime import datetime
    from collections import defaultdict
    class ReviewMetrics:
    def __init__(self):
    self.metrics = defaultdict(lambda: {
    'total_issues': 0,
    'issues_by_severity': defaultdict(int),
    'issues_by_category': defaultdict(int),
    'false_positives': 0,
    'review_time': 0,
    'files_reviewed': 0
    })
    def record_review(self, file_path, review_result, review_time):
    """Zapisz metryki z przeglądu"""
    team = self.get_team(file_path)
    metrics = self.metrics[team]
    metrics['files_reviewed'] += 1
    metrics['review_time'] += review_time
    for issue in review_result.get('issues', []):
    metrics['total_issues'] += 1
    metrics['issues_by_severity'][issue['severity']] += 1
    metrics['issues_by_category'][issue['category']] += 1
    def generate_report(self):
    """Wygeneruj raport metryk"""
    report = {
    'generated_at': datetime.now().isoformat(),
    'summary': {
    'total_files': sum(m['files_reviewed'] for m in self.metrics.values()),
    'total_issues': sum(m['total_issues'] for m in self.metrics.values()),
    'avg_review_time': self.calculate_avg_time(),
    'most_common_issues': self.get_top_issues()
    },
    'by_team': dict(self.metrics)
    }
    return report
    def calculate_avg_time(self):
    total_time = sum(m['review_time'] for m in self.metrics.values())
    total_files = sum(m['files_reviewed'] for m in self.metrics.values())
    return total_time / total_files if total_files > 0 else 0
  2. Wizualizuj metryki

    review-dashboard.js
    import Chart from 'chart.js/auto';
    async function createReviewDashboard() {
    const metrics = await fetch('/api/review-metrics').then(r => r.json());
    // Wykres problemów według ważności
    new Chart(document.getElementById('severity-chart'), {
    type: 'doughnut',
    data: {
    labels: ['Błąd', 'Ostrzeżenie', 'Info', 'Styl'],
    datasets: [{
    data: [
    metrics.summary.issues_by_severity.error,
    metrics.summary.issues_by_severity.warning,
    metrics.summary.issues_by_severity.info,
    metrics.summary.issues_by_severity.style
    ],
    backgroundColor: ['#dc3545', '#ffc107', '#17a2b8', '#6c757d']
    }]
    }
    });
    // Trendy w czasie
    new Chart(document.getElementById('trends-chart'), {
    type: 'line',
    data: {
    labels: metrics.daily_stats.map(d => d.date),
    datasets: [{
    label: 'Znalezione problemy',
    data: metrics.daily_stats.map(d => d.issues),
    borderColor: '#dc3545'
    }, {
    label: 'Przejrzane pliki',
    data: metrics.daily_stats.map(d => d.files),
    borderColor: '#28a745'
    }]
    }
    });
    }

Architektura pluginów

claude_review_plugin.py
from abc import ABC, abstractmethod
import subprocess
class ReviewPlugin(ABC):
"""Klasa bazowa dla niestandardowych pluginów przeglądów"""
@abstractmethod
def name(self):
"""Nazwa pluginu"""
pass
@abstractmethod
def check(self, file_path, content):
"""Wykonaj niestandardowe sprawdzenie"""
pass
def run_claude_check(self, prompt, context):
"""Helper do uruchamiania sprawdzenia Claude Code"""
result = subprocess.run([
'claude', prompt,
'--context', context,
'--format', 'json'
], capture_output=True, text=True)
return json.loads(result.stdout)
class SecurityPlugin(ReviewPlugin):
def name(self):
return "security-scanner"
def check(self, file_path, content):
# Niestandardowe sprawdzenia bezpieczeństwa
issues = []
# Sprawdź zakodowane sekrety
secret_patterns = [
r'api[_-]?key\s*=\s*["\'][\w\-]+["\']',
r'password\s*=\s*["\'][^"\']+["\']',
r'token\s*=\s*["\'][\w\-]+["\']'
]
for pattern in secret_patterns:
if re.search(pattern, content, re.IGNORECASE):
issues.append({
'severity': 'error',
'message': 'Wykryto potencjalny zakodowany sekret',
'pattern': pattern
})
# Użyj Claude do zaawansowanych sprawdzeń
claude_result = self.run_claude_check(
"Sprawdź luki bezpieczeństwa jak SQL injection, XSS, itd.",
content
)
issues.extend(claude_result.get('issues', []))
return issues
class PerformancePlugin(ReviewPlugin):
def name(self):
return "performance-analyzer"
def check(self, file_path, content):
# Sprawdzenia specyficzne dla wydajności
return self.run_claude_check(
"Przeanalizuj problemy wydajności: zapytania N+1, niepotrzebne rendery, wycieki pamięci",
content
)
# Menedżer pluginów
class PluginManager:
def __init__(self):
self.plugins = []
def register(self, plugin):
self.plugins.append(plugin)
def run_all(self, file_path, content):
all_issues = []
for plugin in self.plugins:
try:
issues = plugin.check(file_path, content)
for issue in issues:
issue['plugin'] = plugin.name()
all_issues.extend(issues)
except Exception as e:
print(f"Plugin {plugin.name()} nie powiódł się: {e}")
return all_issues
.git/hooks/pre-commit
#!/bin/bash
echo "Uruchamianie przeglądu Claude Code..."
# Pobierz pliki staged
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
# Przejrzyj każdy plik
ISSUES_FOUND=false
for file in $STAGED_FILES; do
if [[ $file =~ \.(js|ts|py|go)$ ]]; then
echo "Przeglądanie $file..."
# Uruchom przegląd
REVIEW=$(claude review "$file" \
--severity "error,warning" \
--format json)
# Sprawdź problemy
if echo "$REVIEW" | jq -e '.issues | length > 0' > /dev/null; then
ISSUES_FOUND=true
echo "$REVIEW" | jq -r '.issues[] | "[\(.severity)] \(.file):\(.line) - \(.message)"'
fi
fi
done
if $ISSUES_FOUND; then
echo ""
echo "Znaleziono problemy! Proszę naprawić przed commitem."
echo "Aby ominąć, użyj: git commit --no-verify"
exit 1
fi
echo "Przegląd przeszedł!"

Ulepsz swoją automatyzację przeglądów:

Pamiętaj: Automatyczne przeglądy powinny wzmacniać, nie zastępować ludzkich przeglądów kodu. Używaj Claude Code do wyłapywania częstych problemów i egzekwowania standardów, pozwalając ludzkim recenzentom skupić się na architekturze, logice biznesowej i złożonych decyzjach.