Github Code Review
Ревью PR: диффы, инлайн-комментарии через gh или REST.
Метаданные навыка
| Источник | Встроенный (установлен по умолчанию) |
| Путь | skills/github/github-code-review |
| Версия | 1.1.0 |
| Автор | Hermes Agent |
| Лицензия | MIT |
| Платформы | linux, macos, windows |
| Теги | GitHub, Code-Review, Pull-Requests, Git, Quality |
| Связанные навыки | github-auth, github-pr-workflow |
Справочник: полный SKILL.md
Ниже — полное определение навыка, которое Hermes загружает при его активации. Именно этот текст агент получает как инструкции во время работы.
GitHub Code Review
Проводи ревью локальных изменений до пуша или проверяй открытые PR на GitHub. Большая часть навыка работает на чистом git — разделение на gh/curl важно только для операций уровня PR.
Требования
- Аутентификация в GitHub (см. навык
github-auth) - Работа внутри git-репозитория
Настройка (для взаимодействия с PR)
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
1. Ревью локальных изменений (до пуша)
Чистый git — работает везде, API не нужен.
Получить дифф
# Staged-изменения (то, что попадёт в коммит)
git diff --staged
# Все изменения относительно main (то, что войдёт в PR)
git diff main...HEAD
# Только имена файлов
git diff main...HEAD --name-only
# Краткая сводка (вставки/удаления по файлам)
git diff main...HEAD --stat
Стратегия ревью
- Сначала общая картина:
git diff main...HEAD --stat
git log main..HEAD --oneline
- Файл за файлом — используй
read_fileдля полного контекста и дифф для просмотра изменений:
git diff main...HEAD -- src/auth/login.py
- Проверь типичные проблемы:
# Отладочные вызовы, TODO, console.log — всё, что не должно попасть в продакшн
git diff main...HEAD | grep -n "print(\|console\.log\|TODO\|FIXME\|HACK\|XXX\|debugger"
# Случайно добавленные большие файлы
git diff main...HEAD --stat | sort -t'|' -k2 -rn | head -10
# Паттерны секретов и учётных данных
git diff main...HEAD | grep -in "password\|secret\|api_key\|token.*=\|private_key"
# Маркеры конфликтов слияния
git diff main...HEAD | grep -n "<<<<<<\|>>>>>>\|======="
- Представь структурированный отчёт пользователю.
Формат вывода ревью
При ревью локальных изменений оформляй вывод в таком виде:
## Code Review Summary
### Critical
- **src/auth.py:45** — SQL injection: user input passed directly to query.
Suggestion: Use parameterized queries.
### Warnings
- **src/models/user.py:23** — Password stored in plaintext. Use bcrypt or argon2.
- **src/api/routes.py:112** — No rate limiting on login endpoint.
### Suggestions
- **src/utils/helpers.py:8** — Duplicates logic in `src/core/utils.py:34`. Consolidate.
- **tests/test_auth.py** — Missing edge case: expired token test.
### Looks Good
- Clean separation of concerns in the middleware layer
- Good test coverage for the happy path
2. Ревью Pull Request на GitHub
Просмотр деталей PR
Через gh:
gh pr view 123
gh pr diff 123
gh pr diff 123 --name-only
Через git + curl:
PR_NUMBER=123
# Получить детали PR
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "
import sys, json
pr = json.load(sys.stdin)
print(f\"Title: {pr['title']}\")
print(f\"Author: {pr['user']['login']}\")
print(f\"Branch: {pr['head']['ref']} -> {pr['base']['ref']}\")
print(f\"State: {pr['state']}\")
print(f\"Body:\n{pr['body']}\")"
# Список изменённых файлов
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/files \
| python3 -c "
import sys, json
for f in json.load(sys.stdin):
print(f\"{f['status']:10} +{f['additions']:-4} -{f['deletions']:-4} {f['filename']}\")"
Чекаут PR локально для полного ревью
Работает на чистом git — gh не нужен:
# Забрать ветку PR и переключиться на неё
git fetch origin pull/123/head:pr-123
git checkout pr-123
# Теперь можно использовать read_file, search_files, запускать тесты и т.д.
# Посмотреть дифф относительно базовой ветки
git diff main...pr-123
Через gh (сокращённый вариант):
gh pr checkout 123
Оставить комментарий к PR
Общий комментарий — через gh:
gh pr comment 123 --body "Overall looks good, a few suggestions below."
Общий комментарий — через curl:
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/$PR_NUMBER/comments \
-d '{"body": "Overall looks good, a few suggestions below."}'
Инлайн-комментарии к ревью
Одиночный инлайн-комментарий — через gh (через API):
HEAD_SHA=$(gh pr view 123 --json headRefOid --jq '.headRefOid')
gh api repos/$OWNER/$REPO/pulls/123/comments \
--method POST \
-f body="This could be simplified with a list comprehension." \
-f path="src/auth/login.py" \
-f commit_id="$HEAD_SHA" \
-f line=45 \
-f side="RIGHT"
Одиночный инлайн-комментарий — через curl:
# Получить SHA head-коммита
HEAD_SHA=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments \
-d "{
\"body\": \"This could be simplified with a list comprehension.\",
\"path\": \"src/auth/login.py\",
\"commit_id\": \"$HEAD_SHA\",
\"line\": 45,
\"side\": \"RIGHT\"
}"
Формальное ревью (Approve / Request Changes)
Через gh:
gh pr review 123 --approve --body "LGTM!"
gh pr review 123 --request-changes --body "See inline comments."
gh pr review 123 --comment --body "Some suggestions, nothing blocking."
Через curl — атомарное ревью с несколькими инлайн-комментариями:
HEAD_SHA=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews \
-d "{
\"commit_id\": \"$HEAD_SHA\",
\"event\": \"COMMENT\",
\"body\": \"Code review from Hermes Agent\",
\"comments\": [
{\"path\": \"src/auth.py\", \"line\": 45, \"body\": \"Use parameterized queries to prevent SQL injection.\"},
{\"path\": \"src/models/user.py\", \"line\": 23, \"body\": \"Hash passwords with bcrypt before storing.\"},
{\"path\": \"tests/test_auth.py\", \"line\": 1, \"body\": \"Add test for expired token edge case.\"}
]
}"
Допустимые значения event: "APPROVE", "REQUEST_CHANGES", "COMMENT"
Поле line указывает номер строки в новой версии файла. Для удалённых строк используй "side": "LEFT".
3. Чеклист ревью
При ревью — локального или PR — проверяй по категориям:
Корректность
- Код делает то, что от него ожидается?
- Обработаны граничные случаи (пустые входные данные, null-значения, большие объёмы, параллельный доступ)?
- Ошибочные пути обрабатываются корректно?
Безопасность
- Никаких захардкоженных секретов, учётных данных, API-ключей
- Валидация пользовательского ввода
- Нет SQL-инъекций, XSS, path traversal
- Там, где нужно, есть проверки аутентификации/авторизации
Качество кода
- Понятные имена (переменных, функций, классов)
- Без лишней сложности и преждевременных абстракций
- DRY — дублирующаяся логика вынесена
- Функции сфокусированы (принцип единственной ответственности)
Тестирование
- Новые ветки кода покрыты тестами?
- Охвачены и happy path, и ошибочные случаи?
- Тесты читаемы и поддерживаемы?
Производительность
- Нет N+1 запросов и лишних циклов
- Кэширование применяется там, где оправдано
- Нет блокирующих операций в асинхронном коде
Документация
- Публичные API задокументированы
- Нетривиальная логика снабжена комментариями с объяснением «почему»
- README обновлён, если поведение изменилось
4. Рабочий процесс: ревью перед пушем
Когда пользователь просит «посмотреть код» или «проверить перед пушем»:
git diff main...HEAD --stat— оцени объём измененийgit diff main...HEAD— прочитай полный дифф- Для каждого изменённого файла при необходимости используй
read_fileдля более широкого контекста - Пройдись по чеклисту выше
- Представь результаты в структурированном формате (Critical / Warnings / Suggestions / Looks Good)
- Если найдены критические проблемы — предложи исправить их до пуша
5. Рабочий процесс: ревью PR (сквозной)
Когда пользователь просит «посмотреть PR #N», «проверить этот PR» или даёт ссылку на PR, следуй этому порядку:
Шаг 1: Настроить окружение
source "${HERMES_HOME:-$HOME/.hermes}/skills/github/github-auth/scripts/gh-env.sh"
# Или выполнить блок инициализации из начала этого навыка
Шаг 2: Собрать контекст PR
Получи метаданные, описание и список изменённых файлов — сначала разберись с масштабом, потом углубляйся в код.
Через gh:
gh pr view 123
gh pr diff 123 --name-only
gh pr checks 123
Через curl:
PR_NUMBER=123
# Детали PR (заголовок, автор, описание, ветка)
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER
# Изменённые файлы с количеством строк
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER/files
Шаг 3: Забрать PR локально
Это даёт полный доступ к read_file, search_files и возможность запускать тесты.
git fetch origin pull/$PR_NUMBER/head:pr-$PR_NUMBER
git checkout pr-$PR_NUMBER
Шаг 4: Прочитать дифф и разобраться в изменениях
# Полный дифф относительно базовой ветки
git diff main...HEAD
# Или файл за файлом для больших PR
git diff main...HEAD --name-only
# Затем для каждого файла:
git diff main...HEAD -- path/to/file.py
Для каждого изменённого файла используй read_file — дифф в одиночку может не показать проблем, которые видны только в контексте окружающего кода.
Шаг 5: Запустить автоматические проверки локально (если применимо)
# Запустить тесты, если есть тест-сьют
python -m pytest 2>&1 | tail -20
# или: npm test, cargo test, go test ./..., и т.п.
# Запустить линтер, если настроен
ruff check . 2>&1 | head -30
# или: eslint, clippy, и т.п.
Шаг 6: Применить чеклист ревью (раздел 3)
Пройдись по каждой категории: Корректность, Безопасность, Качество кода, Тестирование, Производительность, Документация.
Шаг 7: Опубликовать ревью на GitHub
Собери замечания и отправь их как формальное ревью с инлайн-комментариями.
Через gh:
# Если проблем нет — одобрить
gh pr review $PR_NUMBER --approve --body "Reviewed by Hermes Agent. Code looks clean — good test coverage, no security concerns."
# Если есть замечания — запросить изменения с инлайн-комментариями
gh pr review $PR_NUMBER --request-changes --body "Found a few issues — see inline comments."
Через curl — атомарное ревью с несколькими инлайн-комментариями:
HEAD_SHA=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
# Сформировать JSON ревью — event: APPROVE, REQUEST_CHANGES или COMMENT
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER/reviews \
-d "{
\"commit_id\": \"$HEAD_SHA\",
\"event\": \"REQUEST_CHANGES\",
\"body\": \"## Hermes Agent Review\n\nFound 2 issues, 1 suggestion. See inline comments.\",
\"comments\": [
{\"path\": \"src/auth.py\", \"line\": 45, \"body\": \"🔴 **Critical:** User input passed directly to SQL query — use parameterized queries.\"},
{\"path\": \"src/models.py\", \"line\": 23, \"body\": \"⚠️ **Warning:** Password stored without hashing.\"},
{\"path\": \"src/utils.py\", \"line\": 8, \"body\": \"💡 **Suggestion:** This duplicates logic in core/utils.py:34.\"}
]
}"
Шаг 8: Опубликовать сводный комментарий
Помимо инлайн-комментариев, оставь общий комментарий верхнего уровня — автор PR должен видеть полную картину с первого взгляда. Используй шаблон из references/review-output-template.md.
Через gh:
gh pr comment $PR_NUMBER --body "$(cat <<'EOF'
## Code Review Summary
**Verdict: Changes Requested** (2 issues, 1 suggestion)
### 🔴 Critical
- **src/auth.py:45** — SQL injection vulnerability
### ⚠️ Warnings
- **src/models.py:23** — Plaintext password storage
### 💡 Suggestions
- **src/utils.py:8** — Duplicated logic, consider consolidating
### ✅ Looks Good
- Clean API design
- Good error handling in the middleware layer
---
*Reviewed by Hermes Agent*
EOF
)"
Шаг 9: Очистка
git checkout main
git branch -D pr-$PR_NUMBER
Решение: Approve / Request Changes / Comment
- Approve — нет критических или предупреждающих замечаний, только незначительные предложения или всё чисто
- Request Changes — есть критические или предупреждающие проблемы, которые нужно исправить до слияния
- Comment — наблюдения и предложения без блокеров (используй, если не уверен или PR в статусе draft)