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:org と read:discussion は gh 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 jsonJSON レスポンスに含まれる主要フィールド:
{
"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 のステータスだけで進捗を管理する。