0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Projects + gh CLI で「Epic → Story → Task」の階層管理を実現する

0
Posted at

GitHub Projects(V2)と gh CLI を組み合わせて、Issue を Epic / Story / Task の3階層で管理する方法を紹介します。
実際のプロジェクトで運用してみて分かったコツや、Sub-issues を使った親子関係の設定方法も含めてまとめました。

なぜ GitHub Projects なのか

Notion や Jira を使う選択肢もありますが、コードと課題管理が同じ場所にあるメリットは大きいです。

  • PR に Closes #12 と書くだけで Issue が自動クローズされる
  • gh CLI でターミナルから Issue 作成・編集が完結する
  • Sub-issues 機能で親子関係がネイティブに表現できる(2024年〜)
  • Iteration(スプリント)・カスタムフィールド・Insights が標準搭載

「ブラウザを開かなくても、CLI だけでプロジェクト管理が回る」のが最大の利点です。

前提:gh CLI のセットアップ

# インストール
brew install gh

# ログイン
gh auth login

# Projects 操作に必要なスコープを追加(初回のみ)
gh auth refresh -s project,read:project

1. ラベル設計 — フェーズ × 種別の2軸

Issue を分類するために、フェーズラベル種別ラベルの2軸でラベルを設計します。

フェーズラベル(いつやるか)

ラベル 意味
第1弾 🟢 緑 MVP・最初のリリース
第2弾 🔵 青 次の機能追加
第3弾 🟡 黄 自動化・効率化
第4弾 🔴 赤 将来検討

種別ラベル(何のレベルか)

ラベル 粒度
Epic 🟣 紫 フェーズのゴール
Story 🔵 青 ユーザー価値の単位
Task 🟡 黄 1〜3日で終わる作業
# ラベル作成の例
gh label create "Epic"  --color "6A0DAD" --description "フェーズのゴール単位"
gh label create "Story" --color "0075CA" --description "ユーザー価値単位"
gh label create "Task"  --color "E4E669" --description "作業単位"
gh label create "第1弾" --color "0E8A16" --description "フェーズ1"

ポイント: フェーズラベルと種別ラベルを必ず両方付けることで、「第2弾の Story 一覧」のようなフィルタリングが簡単にできます。

2. Issue の3階層 — Epic / Story / Task

各レベルの判断基準

レベル 判断基準 テンプレート
Epic 「〇〇ができる状態」と表現できる ゴール + 完了の定義
Story 「〇〇として、△△したい」と表現できる ユーザーストーリー + 受け入れ条件
Task 1人が1〜3日で完了できる 概要 + 完了条件チェックリスト

具体例:階層の分解

[Epic] Looker Studio でセグメント別集計ができる
  ├── [Story] 既存の運用を把握し、接続方式を設計する
  │     ├── [Task] データ形式(Wide/Long)を確定する
  │     └── [Task] JOIN キーを決定する
  └── [Story] セグメントデータを Looker に反映する
        ├── [Task] 同期スクリプトを実装する
        └── [Task] Looker 上で動作確認する

Issue の作成(下から順に)

重要: Task → Story → Epic の順に作成します。先に子を作っておくことで、親の本文に #番号 で参照を書けます。

Task を作成

gh issue create \
  --title "データ形式(Wide/Long)を確定する" \
  --label "第2弾" --label "Task" \
  --body "$(cat <<'EOF'
## 概要
Looker Studio のデータソースとして最適な形式を決定する。

## 完了条件
- [ ] Wide/Long の比較表を作成
- [ ] チームで合意
EOF
)"

Story を作成

gh issue create \
  --title "[Story] 既存Looker運用を把握し接続方式を設計する" \
  --label "第2弾" --label "Story" \
  --body "$(cat <<'EOF'
## ユーザーストーリー
開発者として、既存の Looker 運用を理解し、新しいデータの接続方式を設計したい。

## 受け入れ条件
- データ形式が確定している
- JOIN キーが決定している

## Tasks
- #10 データ形式(Wide/Long)を確定する
- #11 JOIN キーを決定する
EOF
)"

Epic を作成

gh issue create \
  --title "[Epic] Looker Studioでセグメント別集計ができる" \
  --label "第2弾" --label "Epic" \
  --body "$(cat <<'EOF'
## ゴール
Looker Studio 上でセグメント別の絞り込み・集計ができる状態を作る。

## 完了の定義
- Looker Studio でセグメント別フィルタが動作する
- テストデータで動作確認済み

## Stories
- 既存Looker運用を把握し接続方式を設計する
- セグメントデータを Looker に反映する
EOF
)"

3. Sub-issues で親子関係を設定する

GitHub の Sub-issues 機能を使うと、Issue 間に親子関係を持たせることができます。Project ボード上で「Sub-issues progress」として進捗バーが表示されるのが便利です。

設定には GraphQL API を使います。

# ① 親 Issue の node ID を取得
PARENT_ID=$(gh api graphql -f query='query {
  repository(owner:"YOUR_ORG", name:"YOUR_REPO") {
    issue(number:12) { id }
  }
}' --jq '.data.repository.issue.id')

# ② 子 Issue の node ID を取得
CHILD_ID=$(gh api graphql -f query='query {
  repository(owner:"YOUR_ORG", name:"YOUR_REPO") {
    issue(number:10) { id }
  }
}' --jq '.data.repository.issue.id')

# ③ 紐付け
gh api graphql -f query="mutation {
  addSubIssue(input: { issueId: \"$PARENT_ID\", subIssueId: \"$CHILD_ID\" }) {
    issue { number }
    subIssue { number }
  }
}"

ヘルパー関数を作っておくと楽

.bashrc.zshrc に以下を追加しておくと、繰り返し使えます。

# node ID 取得
get_node_id() {
  gh api graphql \
    -f query="query { repository(owner:\"YOUR_ORG\", name:\"YOUR_REPO\") { issue(number:$1) { id } } }" \
    --jq '.data.repository.issue.id'
}

# Sub-issue 紐付け
add_sub_issue() {
  gh api graphql \
    -f query="mutation { addSubIssue(input: { issueId: \"$1\", subIssueId: \"$2\" }) { issue { number } subIssue { number } } }" \
    --jq '.data.addSubIssue | "#\(.issue.number) <- #\(.subIssue.number)"'
}

# 使い方
add_sub_issue "$(get_node_id 12)" "$(get_node_id 10)"
# => #12 <- #10

4. Project ボードに追加する

Issue を作っただけでは Project ボードに表示されません。明示的に追加する必要があります。

# 1件ずつ追加
gh project item-add 29 --owner YOUR_ORG \
  --url "https://github.com/YOUR_ORG/YOUR_REPO/issues/10"

# まとめて追加(シェルのループ)
for i in 10 11 12 13 14; do
  gh project item-add 29 --owner YOUR_ORG \
    --url "https://github.com/YOUR_ORG/YOUR_REPO/issues/$i"
done

忘れがちポイント: Issue 作成後に Project への追加を忘れると、ボード上に表示されません。作成と追加はセットで行いましょう。

5. Project ボードの View を使い分ける

ラベルと種別を分けて設計したことで、View のフィルタが効果的に使えます。

View 名 フィルタ 用途
Epics label:Epic フェーズ単位のゴール一覧
Stories label:Story ユーザー価値の進捗確認
Sprint Board label:Task + Iteration で絞り込み 今スプリントの作業
Roadmap 全件、Start/End で時系列表示 全体の見通し

ロードマップビューの作成

  1. Project 画面で「+ New view」→「Roadmap」を選択
  2. Date fields に Start / End カスタムフィールドを設定
  3. Group by: Phase を選択

これで「どのフェーズが、いつからいつまでか」がガントチャート風に見えます。

6. スプリント管理(Iteration フィールド)

GitHub Projects の Iteration フィールド型を使うと、スプリント単位の管理ができます。

セットアップ

  1. Project の「+ Add field」→ Field name: Sprint、Type: Iteration
  2. Duration を設定(例: 2 weeks)
  3. 同様に Story Points(Type: Number)も作成

ストーリーポイントの可視化

  • Sum 機能: Group by Sprint にすると、各スプリントのポイント合計がヘッダーに表示される
  • Insights: 「New chart」→ Y-axis に Sum of Story Points、Group by Status で消化グラフが作れる

ポイントの基準

Story Points 目安 備考
1〜3 1日以内 小さなタスク
5 3日以内 標準的なタスク
8以上 スプリントを跨ぐ 分割を検討する

7. 開発フロー(Issue → Branch → PR → Close)

# 1. Issue に対応するブランチを作成
git checkout -b issue/10-fix-data-format

# 2. 作業してコミット
git add .
git commit -m "データ形式を Wide に確定する (#10)"

# 3. Push して PR を作成
git push -u origin issue/10-fix-data-format
gh pr create --title "データ形式を Wide に確定する" --body "Closes #10"

# 4. マージ後にクリーンアップ
git checkout main && git pull
git branch -d issue/10-fix-data-format

PR に Closes #10 と書くことで、マージ時に Issue が自動でクローズされます。

8. Milestone でリリース日を管理する

Iteration(スプリント)が「作業の区切り」なら、Milestone は「絶対的な納期」です。

# Milestone を作成
gh api repos/YOUR_ORG/YOUR_REPO/milestones \
  --method POST \
  -f title="第1弾リリース" \
  -f due_on="2026-04-01T00:00:00Z" \
  -f description="スプレッドシートでの週次提供を開始"

# Issue に Milestone を設定
gh issue edit 10 --milestone "第1弾リリース"
概念 用途
Iteration(Sprint) 作業の区切り(2週間ごと) Sprint 1, Sprint 2
Milestone リリース日・納期 第1弾リリース

この2つを組み合わせることで、「この納期までに、あと何スプリント分の作業があるか?」が見えるようになります。

よく使うコマンドまとめ

# Issue 操作
gh issue list                              # 一覧
gh issue list --label "第2弾" --label "Task" # フィルタ
gh issue view 10                           # 詳細表示
gh issue view 10 --web                     # ブラウザで開く
gh issue create --title "..." --label "..." --body "..." # 作成
gh issue edit 10 --add-label "第2弾"        # ラベル追加
gh issue edit 10 --add-assignee "@me"       # アサイン
gh issue comment 10 --body "進捗: 完了"      # コメント
gh issue close 10                          # クローズ

# Project 操作
gh project view 29 --owner YOUR_ORG --web  # ボードを開く
gh project item-add 29 --owner YOUR_ORG --url <URL> # Issue を追加

# ラベル操作
gh label list                              # 一覧
gh label create "名前" --color "FFFFFF"     # 作成

まとめ

GitHub Projects を使った階層管理のポイントは3つです。

  1. ラベル2軸(フェーズ × 種別)で、フィルタとビューを使い分ける
  2. Sub-issues で親子関係を持たせ、進捗バーで完了度を可視化する
  3. gh CLI で Issue 作成から Project 追加まで、ターミナルで完結させる

Jira ほどの複雑さは不要だけど、フラットな Issue 管理では物足りない — そんなチームにとって、GitHub Projects + Sub-issues の組み合わせはちょうどいい選択肢になるはずです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?