github-issues
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGitHub Issues Management
GitHub Issues 管理
Create, search, triage, and manage GitHub issues. Each section shows first, then the fallback.
ghcurl创建、搜索、分类和管理GitHub Issues。每个部分先展示命令,再展示备选方案。
ghcurlPrerequisites
前提条件
- Authenticated with GitHub (see skill)
github-auth - Inside a git repo with a GitHub remote, or specify the repo explicitly
- 已通过GitHub认证(参考技能)
github-auth - 处于带有GitHub远程仓库的git项目中,或明确指定仓库
Setup
设置
bash
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)bash
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. Viewing Issues
1. 查看Issues
With gh:
bash
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 42With curl:
bash
undefined使用gh:
bash
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:
bash
undefinedList open issues
List open issues
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 returns PRs in /issues too labels = ', '.join(l['name'] for l in i['labels']) print(f"#{i['number']:5} {i['state']:6} {labels:30} {i['title']}")"
-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 returns PRs in /issues too 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&per_page=20"
| python3 -c " import sys, json for i in json.load(sys.stdin): if 'pull_request' not in i: # GitHub API returns PRs in /issues too labels = ', '.join(l['name'] for l in i['labels']) print(f"#{i['number']:5} {i['state']:6} {labels:30} {i['title']}")"
-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 returns PRs in /issues too labels = ', '.join(l['name'] for l in i['labels']) print(f"#{i['number']:5} {i['state']:6} {labels:30} {i['title']}")"
Filter by label
Filter by label
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']}")"
-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?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']}")"
-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']}")"
View a specific issue
View a specific issue
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"State: {i['state']} Labels: {labels} Assignees: {assignees}") print(f"Author: {i['user']['login']} Created: {i['created_at']}") print(f"\n{i['body']}")"
-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"State: {i['state']} Labels: {labels} Assignees: {assignees}") print(f"Author: {i['user']['login']} Created: {i['created_at']}") print(f"\n{i['body']}")"
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"State: {i['state']} Labels: {labels} Assignees: {assignees}") print(f"Author: {i['user']['login']} Created: {i['created_at']}") print(f"\n{i['body']}")"
-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"State: {i['state']} Labels: {labels} Assignees: {assignees}") print(f"Author: {i['user']['login']} Created: {i['created_at']}") print(f"\n{i['body']}")"
Search issues
Search issues
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']}")"
-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']}")"
undefinedcurl -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']}")"
-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']}")"
undefined2. Creating Issues
2. 创建Issues
With gh:
bash
gh issue create \
--title "Login redirect ignores ?next= parameter" \
--body "## Description
After logging in, users always land on /dashboard.使用gh:
bash
gh issue create \
--title "Login redirect ignores ?next= parameter" \
--body "## Description
After logging in, users always land on /dashboard.Steps to Reproduce
Steps to Reproduce
- Navigate to /settings while logged out
- Get redirected to /login?next=/settings
- Log in
- Actual: redirected to /dashboard (should go to /settings)
- Navigate to /settings while logged out
- Get redirected to /login?next=/settings
- Log in
- Actual: redirected to /dashboard (should go to /settings)
Expected Behavior
Expected Behavior
Respect the ?next= query parameter."
--label "bug,backend"
--assignee "username"
--label "bug,backend"
--assignee "username"
**With curl:**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues \
-d '{
"title": "Login redirect ignores ?next= parameter",
"body": "## Description\nAfter logging in, users always land on /dashboard.\n\n## Steps to Reproduce\n1. Navigate to /settings while logged out\n2. Get redirected to /login?next=/settings\n3. Log in\n4. Actual: redirected to /dashboard\n\n## Expected Behavior\nRespect the ?next= query parameter.",
"labels": ["bug", "backend"],
"assignees": ["username"]
}'Respect the ?next= query parameter."
--label "bug,backend"
--assignee "username"
--label "bug,backend"
--assignee "username"
**使用curl:**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues \
-d '{
"title": "Login redirect ignores ?next= parameter",
"body": "## Description\nAfter logging in, users always land on /dashboard.\n\n## Steps to Reproduce\n1. Navigate to /settings while logged out\n2. Get redirected to /login?next=/settings\n3. Log in\n4. Actual: redirected to /dashboard\n\n## Expected Behavior\nRespect the ?next= query parameter.",
"labels": ["bug", "backend"],
"assignees": ["username"]
}'Bug Report Template
Bug报告模板
undefinedundefinedBug Description
Bug描述
<What's happening>
<发生了什么>
Steps to Reproduce
复现步骤
- <step>
- <step>
- <步骤>
- <步骤>
Expected Behavior
预期行为
<What should happen>
<应该发生什么>
Actual Behavior
实际行为
<What actually happens>
<实际发生了什么>
Environment
环境
- OS: <os>
- Version: <version>
undefined- 操作系统:<os>
- 版本:<version>
undefinedFeature Request Template
功能请求模板
undefinedundefinedFeature Description
功能描述
<What you want>
<你想要什么>
Motivation
动机
<Why this would be useful>
<为什么这个功能有用>
Proposed Solution
提议的解决方案
<How it could work>
<如何实现>
Alternatives Considered
考虑过的替代方案
<Other approaches>
```
<其他方法>
undefined3. Managing Issues
3. 管理Issues
Add/Remove Labels
添加/移除标签
With gh:
bash
gh issue edit 42 --add-label "priority:high,bug"
gh issue edit 42 --remove-label "needs-triage"With curl:
bash
undefined使用gh:
bash
gh issue edit 42 --add-label "priority:high,bug"
gh issue edit 42 --remove-label "needs-triage"使用curl:
bash
undefinedAdd labels
Add labels
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels
-d '{"labels": ["priority:high", "bug"]}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels
-d '{"labels": ["priority:high", "bug"]}'
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels
-d '{"labels": ["priority:high", "bug"]}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels
-d '{"labels": ["priority:high", "bug"]}'
Remove a label
Remove a label
curl -s -X DELETE
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage
curl -s -X DELETE
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage
List available labels in the repo
List available labels in the repo
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', '')}")"
-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', '')}")"
undefinedcurl -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', '')}")"
-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', '')}")"
undefinedAssignment
分配任务
With gh:
bash
gh issue edit 42 --add-assignee username
gh issue edit 42 --add-assignee @meWith curl:
bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/assignees \
-d '{"assignees": ["username"]}'使用gh:
bash
gh issue edit 42 --add-assignee username
gh issue edit 42 --add-assignee @me使用curl:
bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/assignees \
-d '{"assignees": ["username"]}'Commenting
添加评论
With gh:
bash
gh issue comment 42 --body "Investigated — root cause is in auth middleware. Working on a fix."With curl:
bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/comments \
-d '{"body": "Investigated — root cause is in auth middleware. Working on a fix."}'使用gh:
bash
gh issue comment 42 --body "Investigated — root cause is in auth middleware. Working on a fix."使用curl:
bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/comments \
-d '{"body": "Investigated — root cause is in auth middleware. Working on a fix."}'Closing and Reopening
关闭与重新打开
With gh:
bash
gh issue close 42
gh issue close 42 --reason "not planned"
gh issue reopen 42With curl:
bash
undefined使用gh:
bash
gh issue close 42
gh issue close 42 --reason "not planned"
gh issue reopen 42使用curl:
bash
undefinedClose
Close
curl -s -X PATCH
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42
-d '{"state": "closed", "state_reason": "completed"}'
-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": "closed", "state_reason": "completed"}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42
-d '{"state": "closed", "state_reason": "completed"}'
Reopen
Reopen
curl -s -X PATCH
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42
-d '{"state": "open"}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42
-d '{"state": "open"}'
undefinedcurl -s -X PATCH
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42
-d '{"state": "open"}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/issues/42
-d '{"state": "open"}'
undefinedLinking Issues to PRs
将Issues关联到PR
Issues are automatically closed when a PR merges with the right keywords in the body:
Closes #42
Fixes #42
Resolves #42To create a branch from an issue:
With gh:
bash
gh issue develop 42 --checkoutWith git (manual equivalent):
bash
git checkout main && git pull origin main
git checkout -b fix/issue-42-login-redirect当PR合并时,如果正文包含正确的关键词,Issues会自动关闭:
Closes #42
Fixes #42
Resolves #42从Issue创建分支:
使用gh:
bash
gh issue develop 42 --checkout使用git(手动等效操作):
bash
git checkout main && git pull origin main
git checkout -b fix/issue-42-login-redirect4. Issue Triage Workflow
4. Issue分类工作流
When asked to triage issues:
- List untriaged issues:
bash
undefined当需要分类Issues时:
- 列出未分类的Issues:
bash
undefinedWith gh
With gh
gh issue list --label "needs-triage" --state open
gh issue list --label "needs-triage" --state open
With curl
With 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']}")"
-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']}")"
2. **Read and categorize** each issue (view details, understand the bug/feature)
3. **Apply labels and priority** (see Managing Issues above)
4. **Assign** if the owner is clear
5. **Comment with triage notes** if neededcurl -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']}")"
-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']}")"
2. **阅读并分类**每个Issue(查看详情,理解bug/功能需求)
3. **应用标签和优先级**(参考上方的Issues管理部分)
4. **分配任务**如果负责人明确
5. **如有需要,添加分类备注评论**5. Bulk Operations
5. 批量操作
For batch operations, combine API calls with shell scripting:
With gh:
bash
undefined对于批量操作,将API调用与shell脚本结合:
使用gh:
bash
undefinedClose all issues with a specific label
Close all issues with a specific label
gh issue list --label "wontfix" --json number --jq '.[].number' |
xargs -I {} gh issue close {} --reason "not planned"
xargs -I {} gh issue close {} --reason "not planned"
**With curl:**
```bashgh issue list --label "wontfix" --json number --jq '.[].number' |
xargs -I {} gh issue close {} --reason "not planned"
xargs -I {} gh issue close {} --reason "not planned"
**使用curl:**
```bashList issue numbers with a label, then close each
List issue numbers with a label, then close each
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 "Closed #$num" done
-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 "Closed #$num" done
undefinedcurl -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 "Closed #$num" done
-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 "Closed #$num" done
undefinedQuick Reference Table
快速参考表格
| Action | gh | curl endpoint |
|---|---|---|
| List issues | | |
| View issue | | |
| Create issue | | |
| Add labels | | |
| Assign | | |
| Comment | | |
| Close | | |
| Search | | |
| 操作 | gh | curl 端点 |
|---|---|---|
| 列出Issues | | |
| 查看Issue | | |
| 创建Issue | | |
| 添加标签 | | |
| 分配任务 | | |
| 添加评论 | | |
| 关闭Issue | | |
| 搜索 | | |