SuperAPI AI 工具集

gh-link-subissues

编程与开发

查看项目

更新于 10-16 08:52

技能介绍

用途

该技能用于在 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 过滤的步骤获取。