{/ Эта страница автоматически активируется из файлов функций SKILL.md с помощью сайта/scripts/generate-skill-docs.py. Редактируйте исходный SKILL.md, а не эту страницу. /}

Проблемы с GitHub

Создание, триаж, метки, назначение задач GitHub через gh или REST.

Метаданные навыки

Источник Встроенный (установлен по умолчанию)
Путь skills/github/github-issues
Версия 1.1.0
Автор Агент Гермес
Лицензия Массачусетский технологический институт
Платформы Linux, MacOS, Windows
Теги GitHub, Проблемы, Управление проектами, Отслеживание ошибок, Сортировка
Связанные навыки github-auth, github-pr-workflow

Справочник: полный SKILL.md:::информация

Ниже приведено полное описание навыка, который загружает Гермес при активации этого навыка. Это то, что агент видит в качестве инструкций, когда навыки активны.

Управление задачами GitHub

Создание, поиск, триаж и решение задач («issues») GitHub. В каждом разделе сначала показывается команда «gh», а затем альтернатива «curl».

Предварительные требования

Настройка

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. Просмотр задачи

С помощью gh:

gh issue list
gh issue list --state open --label "bug"
gh issue list --assignee @me
gh issue list --search "authentication error" --state all
gh issue view 42

С помощью Curl:

# Список открытых задач
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/issues?state=open&per_page=20" \
  | python3 -c "
import sys, json
for i in json.load(sys.stdin):
    if 'pull_request' not in i:  # GitHub API возвращает PR по адресу /issues
        labels = ', '.join(l['name'] for l in i['labels'])
        print(f\"#{i['number']:5}  {i['state']:6}  {labels:30}  {i['title']}\")"

# Фильтр по метке
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/issues?state=open&labels=bug&per_page=20" \
  | python3 -c "
import sys, json
for i in json.load(sys.stdin):
    if 'pull_request' not in i:
        print(f\"#{i['number']}  {i['title']}\")"

# Просмотр конкретной задачи
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42 \
  | python3 -c "
import sys, json
i = json.load(sys.stdin)
labels = ', '.join(l['name'] for l in i['labels'])
assignees = ', '.join(a['login'] for a in i['assignees'])
print(f\"#{i['number']}: {i['title']}\")
print(f\"Статус: {i['state']}  Метки: {labels}  Исполнители: {assignees}\")
print(f\"Автор: {i['user']['login']}  Создано: {i['created_at']}\")
print(f\"\n{i['body']}\")"

# Поиск задач
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/search/issues?q=authentication+error+repo:$OWNER/$REPO" \
  | python3 -c "
import sys, json
for i in json.load(sys.stdin)['items']:
    print(f\"#{i['number']}  {i['state']:6}  {i['title']}\")"

2. Создание задачи

С помощью gh:

gh issue create \
  --title "Логин перенаправляет, игнорируя параметр?next=" \
  --body "## Описание
После входа пользователи всегда попадают на /dashboard.

## Шаги для воспроизведения
1. Перейти на /settings, будучи неавторизованным
2. Произойдёт перенаправление на /login?next=/settings
3. Войти
4. Фактический результат: перенаправление на /dashboard (должно быть на /settings)

## Ожидаемое поведение
Учитывать параметр запроса?next=." \
  --label "bug,backend" \
  --assignee "username"

С помощью Curl:

curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues \
  -d '{
    "title": "Логин перенаправляет, игнорируя параметр?next=",
    "body": "## Описание\nПосле входа пользователи всегда попадают на /dashboard.\n\n## Шаги для воспроизведения\n1. Перейти на /settings, будучи неавторизованным\n2. Произойдёт перенаправление на /login?next=/settings\n3. Войти\n4. Фактический результат: перенаправление на /dashboard\n\n## Ожидаемое поведение\nУчитывать параметр запроса?next=.",
    "labels": ["bug", "backend"],
    "assignees": ["username"]
  }'

Шаблон отчёта об ошибках

## Описание ошибки
<Что происходит>

## Шаги для воспроизведения
1. <шаг>
2. <шаг>

## Ожидаемое поведение
<Что должно произойти>

## Фактическое поведение
<Что происходит на самом деле>

## Окружение
- ОС: <ос>
- Версия: <версия>

Шаблон запроса функции

## Описание функции
<Что вы хотите>

## Мотивация
<Почему это будет полезно>

## Предлагаемое решение
<Как это могло бы работать>

## Рассмотренные альтернативы
<Другие подходы>

3. Управление задачами

Добавление/Удаление меток

С помощью gh:

gh issue edit 42 --add-label "priority:high,bug"
gh issue edit 42 --remove-label "needs-triage"

С помощью Curl:

# Добавить метки
curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42/labels \
  -d '{"labels": ["priority:high", "bug"]}'

# Удалить метку
curl -s -X DELETE \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage

# Список доступных меток в репозитории
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/labels \
  | python3 -c "
import sys, json
for l in json.load(sys.stdin):
    print(f\"  {l['name']:30}  {l.get('description', '')}\")"

Назначение

С помощью gh:

gh issue edit 42 --add-assignee username
gh issue edit 42 --add-assignee @me

С помощью Curl:

curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42/assignees \
  -d '{"assignees": ["username"]}'

Комментирование

С помощью gh:

gh issue comment 42 --body "Исследовано — коренная причина в auth middleware. Работаю над исправлением."

С помощью Curl:

curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42/comments \
  -d '{"body": "Исследовано — коренная причина в auth middleware. Работаю над исправлением."}'

Закрытие и повторное открытие

С помощью gh:

gh issue close 42
gh issue close 42 --reason "not planned"
gh issue reopen 42

С помощью Curl:

# Закрыть
curl -s -X PATCH \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42 \
  -d '{"state": "closed", "state_reason": "completed"}'

# Открыть заново
curl -s -X PATCH \
  -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$OWNER/$REPO/issues/42 \
  -d '{"state": "open"}'

Привязка задач к пиару

Задачи автоматически закрываются, когда PR сливается с ключевыми словами в описании:

Closes #42
Fixes #42
Resolves #42

Чтобы создать ветку из задачи:

С помощью gh:

gh issue develop 42 --checkout

С помощью git (эквивалент вручную):

git checkout main && git pull origin main
git checkout -b fix/issue-42-login-redirect

4. Рабочий процесс триажа задач

Когда необходимо выполнить три задачи:

  1. Список неотсортированных задач:
# С помощью gh
gh issue list --label "needs-triage" --state open

# С помощью curl
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/issues?labels=needs-triage&state=open" \
  | python3 -c "
import sys, json
for i in json.load(sys.stdin):
    if 'pull_request' not in i:
        print(f\"#{i['number']}  {i['title']}\")"
  1. Прочитать и категоризировать каждую задачу (просмотреть деталь, понять ошибку/функцию)

  2. Применить метки и приоритеты (см. Управление задачами выше)

  3. Назначить исполнителя, если он очевиден

  4. При необходимости оставить комментарий с заметками триажа

5. Массовые операции

Для пакетных операций скомбинируйте API-вызовы с шелл-скриптами:

С помощью gh:

# Закрыть все задачи с определённой меткой
gh issue list --label "wontfix" --json number --jq '.[].number' | \
  xargs -I {} gh issue close {} --reason "not planned"

С помощью Curl:

# Получить номера задач с меткой, затем закрыть каждую
curl -s \
  -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/issues?labels=wontfix&state=open" \
  | python3 -c "import sys,json; [print(i['number']) for i in json.load(sys.stdin)]" \
  | while read num; do
    curl -s -X PATCH \
      -H "Authorization: token $GITHUB_TOKEN" \
      https://api.github.com/repos/$OWNER/$REPO/issues/$num \
      -d '{"state": "closed", "state_reason": "not_planned"}'
    echo "Закрыта #$num"
  done

Краткая справочная таблица

Действие хх конечная точка завитка
Список задач список проблем GET /repos/{o}/{r}/issues
Просмотр задачи gh проблема, вид N GET /repos/{o}/{r}/issues/N
Создать задачу гх проблема создать... POST /repos/{o}/{r}/issues
Добавить метки gh проблема редактирования N --add-label... POST /repos/{o}/{r}/issues/N/labels
Назначить gh, редактирование проблемы N --add-assignee... POST /repos/{o}/{r}/issues/N/assignees
Комментировать gh выдать комментарий N --body... POST /repos/{o}/{r}/issues/N/comments
Закрыть gh проблема закрыть N ИСПРАВЛЕНИЕ /repos/{o}/{r}/issues/N
Поиск gh список проблем --search "..." GET /search/issues?q=...