投稿

GitHub Projects v2 を gh CLI で操作する

GitHub Projects v2 を gh CLI で操作する

背景

複数リポジトリのタスクを一元管理する仕組みを構築するにあたり、GitHub Projects v2 を gh CLI で操作する方法を調査した。

Classic PAT が必要

gh project コマンドは Fine-grained PAT では動作しない。

Fine-grained PAT はユーザー所有の Projects に現在非対応(GitHub ドキュメントに明記)。

Classic PAT を発行して GH_CLASSIC_TOKEN として管理し、project 操作時のみ切り替える。

GH_TOKEN="$GH_CLASSIC_TOKEN" gh project item-list 3 --owner "@me"

必要なスコープ

スコープ 用途
repo Issue 読み書き・PR 作成・ブランチ push
project Project アイテム操作全般
read:org gh project list/item-list の GraphQL に必要
read:discussion 同上

read:orgread:discussiongh project list を実行したときのエラーで発覚した。最初に project だけ付けても動かない。

Project の作成

GH_TOKEN="$GH_CLASSIC_TOKEN" gh project create --owner "@me" --title "Symphony" --format json

デフォルトで以下のフィールドが作成される(追加フィールド不要)。

  • Status: Todo / In Progress / Done(Single Select)
  • Repository: 追加した Issue のリポジトリが自動表示
  • Linked pull requests: 関連 PR が自動リンク

Issue を Project に追加する

gh project item-add は Fine-grained PAT と Classic PAT をまたぐと動かないため、GraphQL mutation を使う。

# Step 1: Issue の Node ID を取得
ISSUE_NODE_ID=$(GH_TOKEN="$GH_CLASSIC_TOKEN" gh api graphql -f query='
  query {
    repository(owner: "OWNER", name: "REPO") {
      issue(number: 123) { id }
    }
  }
' --jq '.data.repository.issue.id')

# Step 2: Project に追加
GH_TOKEN="$GH_CLASSIC_TOKEN" gh api graphql \
  -f projectId="PROJECT_ID" \
  -f contentId="$ISSUE_NODE_ID" \
  -f query='
    mutation($projectId: ID!, $contentId: ID!) {
      addProjectV2ItemById(input: { projectId: $projectId, contentId: $contentId }) {
        item { id }
      }
    }
  '

アイテム一覧取得

GH_TOKEN="$GH_CLASSIC_TOKEN" gh project item-list 3 --owner "@me" --format json

JSON レスポンスに含まれる主要フィールド:

{
  "id": "PVTI_...",
  "status": "Todo",
  "title": "Issue タイトル",
  "content": {
    "repository": "owner/repo",
    "number": 123,
    "url": "https://github.com/owner/repo/issues/123",
    "title": "Issue タイトル",
    "body": "Issue 本文"
  },
  "linked pull requests": ["https://..."]
}

content.url をそのまま wt tree add --issue に渡せる。

ステータス更新

GH_TOKEN="$GH_CLASSIC_TOKEN" gh project item-edit \
  --id "PVTI_..." \
  --project-id "PVT_..." \
  --field-id "FIELD_ID" \
  --single-select-option-id "OPTION_ID"

--single-select-option-id に渡す値は gh project field-list --format json で事前取得しておく。

クロスリポジトリ管理の仕組み

GitHub Projects v2 はリポジトリをまたいで Issue を集約できる。複数リポジトリに存在する Issue を1つの Project に追加するだけで、ボード上で一元管理できる。

Project: Symphony
├── owner/repo-a の Issue #12
├── owner/repo-b の Issue #5
└── owner/repo-c の Issue #33

各 Issue は元のリポジトリに残ったまま、Project のステータスだけで進捗を管理する。

トレンドのタグ