用途
该技能用于在 GitHub 上把子 Issue 关联为父 Issue 的 Sub-issue,支持跨仓库(cross-repository)关联。关联完成后,会把父 Issue 与全部子 Issue 自动添加到指定的 GitHub Project,并按规则设置 Project 字段。
前提条件
- 已安装并认证 gh CLI。
- 对目标仓库具有访问权限。
配置
Project 相关配置从 ~/.claude/custom-config/create-issue-config.json 读取,与 /create-issue 技能共享,避免重复管理。配置示例:
{
"project": {
"owner": "org-or-user-name",
"number": 1
}
}
若配置文件不存在,则跳过 Project 添加,并提示用户创建配置文件。
输入
需要从用户处收集:
- 父 Issue:owner/repo#number 形式或 GitHub URL。
- 子 Issue(一个或多个):owner/repo#number 形式或 GitHub URL 列表。
使用方式(步骤)
Step 1:获取 Issue 的 Node ID
通过 GitHub GraphQL API 获取每个 Issue 的 Node ID。同一仓库的 Issue 可用别名在一次 API 调用中批量获取。
单个 Issue:
gh api graphql -f query='
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $number) { id title }
}
}' -f owner="OWNER" -f repo="REPO" -F number=NUMBER \
-q '.data.repository.issue.id'
同一仓库多个 Issue(别名批量):
gh api graphql -f query='
query {
repository(owner: "OWNER", name: "REPO") {
i1: issue(number: 10) { id title }
i2: issue(number: 20) { id title }
}
}' -q '.data.repository'
Step 2:用 addSubIssue mutation 关联
使用取得的 Node ID,把每个子 Issue 关联到父 Issue:
gh api graphql -f query='
mutation($parent: ID!, $child: ID!) {
addSubIssue(input: {issueId: $parent, subIssueId: $child}) {
issue { id title }
subIssue { id title }
}
}' -f parent="PARENT_NODE_ID" -f child="CHILD_NODE_ID"
有多个子 Issue 时,对每个子 Issue 分别执行 mutation。
Step 3:添加到 GitHub Project
从 ~/.claude/custom-config/create-issue-config.json 读取 project.owner 与 project.number,把父 Issue 和全部子 Issue 添加到 GitHub Project。
PROJECT_OWNER=$(jq -r '.project.owner' ~/.claude/custom-config/create-issue-config.json)
PROJECT_NUMBER=$(jq -r '.project.number' ~/.claude/custom-config/create-issue-config.json)
gh project item-add "$PROJECT_NUMBER" --owner "$PROJECT_OWNER" --url "ISSUE_URL"
对父 Issue 和每个子 Issue 分别执行。Issue URL 格式为 https://github.com/{owner}/{repo}/issues/{number}。
Step 4:设置 Project 字段
设置已加入 Project 的各 Issue 的 Status、Priority、Start date。
4a. 获取 Project 字段定义:
gh api graphql -f query='
{
user(login: "PROJECT_OWNER") {
projectV2(number: PROJECT_NUMBER) {
id
fields(first: 30) {
nodes {
... on ProjectV2Field {
id
name
dataType
}
... on ProjectV2SingleSelectField {
id
name
options { id name }
}
}
}
}
}
}'
需要取得的字段 ID:Status 字段 ID 及各选项(Backlog、In progress 等)ID;Priority 字段 ID 及各选项(P0、P1、P2)ID;Start date 字段 ID。
4b. 获取各 Issue 的 Project Item ID:
gh api graphql -f query='
{
repository(owner: "OWNER", name: "REPO") {
issue(number: NUMBER) {
projectItems(first: 5) {
nodes {
id
project { id }
}
}
}
}
}' -q '.data.repository.issue.projectItems.nodes[] | select(.project.id == "PROJECT_ID") | .id'
同一仓库的 Issue 可用别名批量获取。
4c. 设置字段值:
gh project item-edit --project-id "PROJECT_ID" --id "ITEM_ID" \
--field-id "STATUS_FIELD_ID" --single-select-option-id "OPTION_ID"
gh project item-edit --project-id "PROJECT_ID" --id "ITEM_ID" \
--field-id "PRIORITY_FIELD_ID" --single-select-option-id "OPTION_ID"
gh project item-edit --project-id "PROJECT_ID" --id "ITEM_ID" \
--field-id "START_DATE_FIELD_ID" --date "$(date +%Y-%m-%d)"
字段值决定规则:
- Status:默认 Backlog;用户有指示时使用其指定值。
- Priority:Issue 标题带 [P0]/[P1]/[P2] 前缀时对应设置,否则跳过。
- Start date:create-issue-config.json 中 project.start_date 为 "today" 时设为今日日期,否则跳过。
- 父 Issue 不设置 Priority(因为子 Issue 优先级可能混合)。
Step 5:确认结果
汇总报告关联与 Project 设置结果:关联成功的父 Issue 与子 Issue 标题;加入 Project 的 Issue 数量;已设置字段(Status、Priority、Start date)的明细;发生错误时报告其内容。
注意事项
- -f 用于字符串参数,-F 用于数值参数(number 为 Int! 类型,故用 -F)。
- -q 为 jq 过滤器,用于从结果中提取特定字段。
- Node ID 是以 I_kwDO 开头的全局唯一标识符。
- 已关联过时会返回错误。
- gh project item-add 是幂等的,对已加入 Project 的 Issue 也可安全执行。
- gh project item-edit 也是幂等的,对已设置相同值的字段重复设置没有问题。
- 配置文件不存在时,跳过 Project 添加与字段设置,仅执行 Sub-issue 关联。
- Project Item ID 与 Issue 的 Node ID 不同,需按 Issue → projectItems → 目标 Project 过滤的步骤获取。