mcpField
G
github-sync

github-sync

github.com/bmad-labs開発1989 回インストール6 日前に更新
リポジトリ

github-sync について

github-syncは、BMADの計画ファイルとGitHub Projects v2を双方向に同期するスキルです。フィールドごとのデータ所有元を守り、変更前にレポートの提示と承認を求めます。

主な機能

  1. 01BMADとGitHub Projectsの双方向同期
  2. 02プロジェクトの初期設定と構成
  3. 03ストーリーをGitHub Issueに登録
  4. 04ステータス、担当者、タスク完了状況の取得
  5. 05承認制の変更と冪等な同期

活用シーン

  1. 01BMAD成果物向けGitHub Projectの設定
  2. 02計画ストーリーからGitHub Issueを作成
  3. 03GitHubの進捗をローカルストーリーに反映
  4. 04同期前に変更内容を確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bmad-labs/skills --skill github-sync

インストール後、Claude Code で/github-syncを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
evals.json
references/
config-schema.md
content-mapping.md
gh-commands.md
scripts/
parse-artifacts.py

詳細

GitHub Sync — BMAD から GitHub Projects v2 への同期

Markdown ファイルに保存されている BMAD の計画成果物(エピック、ストーリー、スプリント計画)と、視覚的なプロジェクト追跡に使用する GitHub Projects v2 の双方向同期です。

クイックナビゲーション

  • gh CLI コマンド、GraphQL クエリ → references/gh-commands.md
  • Issue 本文テンプレート、フィールドマッピング、ラベル、マイルストーン → references/content-mapping.md
  • 設定ファイルの形式 → references/config-schema.md
  • 成果物パーサースクリプト → scripts/parse-artifacts.py

4 つのルール(決して破らないこと)

  1. 自動で同期しないでください。 すべての変更操作(Issue の作成、フィールドの更新、ファイルの変更)では、まず同期レポートを生成してユーザーに提示し、明示的な承認を待ってから実行する必要があります。ユーザーには、何が変更されるかを正確に示す必要があります。

  2. フィールド単位で正とする情報源を定めます。 各フィールドの所有者は、BMAD ファイルまたは GitHub のどちらか一方です。同期時には、常に所有者側の値が優先されます。所有者のデータを上書きしないでください。

    • BMAD が所有するフィールド: ストーリー本文、受け入れ条件、タスク、スプリントの割り当て、エピックのグループ化、依存関係
    • GitHub が所有するフィールド: ステータス、開発担当者の割り当て、タスクのチェックボックスの完了状態、ストーリーポイント、優先度
  3. 冪等な操作にします。 同じ同期を 2 回実行しても、結果は同じになります。ストーリーファイル内の H1 タイトルリンクと、計画ファイルのフロントマターにある gh_item_url のリンクバック識別子によって、重複作成を防ぎます。作成前に、既存の同期状態を必ず確認してください。

  4. スクリプトで Issue 本文を自動解析しないでください。 Issue 本文を生成するには、Read ツールで各ストーリーファイルを直接読み取り、references/content-mapping.md のテンプレートに従って本文を手作業で作成する必要があります。自動解析スクリプトは、微妙な問題を気づかれないまま引き起こします。書式に関する前提が誤っているとタスクリストが削除され、コードブロックが取り除かれて開発メモが損なわれ、空のセクション見出しが生成されます。1 回の不適切なプッシュで、27 件すべての Issue が一度に汚染されるおそれがあります。ファイルを読み、本文を書く。近道はしないでください。


フローの判定

ユーザーの発言ワークフロー設定が必要か?
"set up github project", "onboard", "initialize github"オンボーディングいいえ(設定を作成)
"push to github", "sync push", "create issues"プッシュはい
"pull from github", "sync pull", "update from github"プルはい
"sync status", "what's out of sync"同期状態の確認はい

プロジェクトのルートに .github-sync.yaml が存在しない場合は、必ず最初にオンボーディングへ進んでください。


事前確認(各ワークフローの前に実行)

いずれかのワークフローを開始する前に、以下を順番に確認してください。最初に失敗した時点で停止します。

Step 1: gh --version
        → If missing: "Install GitHub CLI: https://cli.github.com/"

Step 2: gh auth status
        → If not authenticated: "Run: gh auth login"

Step 3: gh auth status (check for "project" in scopes)
        → If missing: "Run: gh auth refresh -s project"

Step 4: (For push/pull/status only) Check .github-sync.yaml exists
        → If missing: "Run onboarding first: say 'set up github project'"

オンボーディングワークフロー

これは初回セットアップです。GitHub Project を新規作成または接続し、カスタムフィールド、ラベル、フェーズベースのマイルストーンを作成します。

ステップ 1:BMAD 成果物を検出する

パーサーを実行して、存在するものを特定します。

python3 .agents/skills/github-sync/scripts/parse-artifacts.py --mode scan \
  --stories-dir .artifacts/implementation-artifacts

さらに、以下のファイルが存在することを確認します。

  • .artifacts/planning-artifacts/epics.md
  • .artifacts/planning-artifacts/sprint-plan.md

注: 成果物のパス .artifacts/ はプロジェクトによって異なる場合があります。実際のディレクトリ構造を確認してください。一部のプロジェクトでは _bmad-output/ が使用されています。ユーザーに正しいパスを確認し、全体を通じてそのパスを使用してください。設定の paths.* も適宜更新してください。

件数を報告します。「ストーリーファイル N 件、エピック M 件、スプリント K 件が見つかりました。」

ステップ 2:GitHub の詳細を確認する

現在のリポジトリを自動検出します。

gh repo view --json owner,name --jq '.owner.login + "/" + .name'

既存のプロジェクトを一覧表示し、既存のものを使用するか、新規作成するかをユーザーに尋ねます。

gh project list --owner {owner} --format json

検出した owner/repo と既存のプロジェクトを提示します。続行する前に確認を求めてください。

ステップ 3:エピックとスプリントのデータを解析する

ここで references/content-mapping.md を読みます — セクション 7(ラベル体系)、8(マイルストーン体系)、12(エピックの導出)。正確なオンボーディングレポートを作成するには、これらの情報が必要です。

次に、実際の成果物を解析します。

python3 .agents/skills/github-sync/scripts/parse-artifacts.py --mode epics \
  --file .artifacts/planning-artifacts/epics.md

python3 .agents/skills/github-sync/scripts/parse-artifacts.py --mode sprints \
  --file .artifacts/planning-artifacts/sprint-plan.md
ステップ 4:オンボーディングレポートを生成する

作成される内容をすべて示すレポートを提示します。

=== GITHUB SYNC — ONBOARDING REPORT ===

Repository: {owner}/{repo}
Project: #{N} "{title}" (existing) OR new project "{title}"

Will create/verify:
  Custom fields (7):
    - Story ID      (TEXT)
    - Epic          (SINGLE_SELECT: 12 options, rainbow colors)
    - Sprint        (SINGLE_SELECT: Sprint 01–12, rainbow colors + sprint goal descriptions)
    - Dev           (SINGLE_SELECT: All, Dev 1, Dev 2, Dev 3, Dev 1+2)
    - Sprint Start  (DATE)
    - Sprint End    (DATE)
    - Story Points  (NUMBER)
  Built-in fields to set:
    - Start date    (DATE, pre-existing)   ← same dates as Sprint Start
    - Target date   (DATE, pre-existing)   ← same dates as Sprint End
    - Status        (single-select, pre-existing)
  {N} labels:
    - Epic labels (one per epic, e.g., epic:1-foundation ... epic:12-testing)
    - Phase labels (e.g., phase:poc, phase:hardening)
    - Layer labels (optional, project-specific architecture layers)
  {K} milestones (phase-based, NOT per-sprint):
    - PoC              (due: {sprint_6_end})    Sprints 1–6
    - Production Hardening (due: {sprint_12_end}) Sprints 7–12

Note: No "Phase" custom field — the milestone covers phase membership.

Proceed with onboarding? [Y/N]

ここで必ず停止してください。ユーザーの承認を待ちます。

Step 5: セットアップを実行する

今すぐ references/gh-commands.md を読んでください — 以下の各操作で使う正確なコマンドが必要です。

承認された場合は、次の順序で実行します。

  1. GitHub Project を作成または接続する(セクション 2)— 既存のものを使用する場合は、そのノード ID を取得するだけです
  2. カスタムフィールドを作成する(セクション 3)— Story ID、Epic、Sprint、Dev、Sprint Start、Sprint End、Story Points
  3. すべてのフィールド ID を照会する(セクション 4)— 既存の Start date、Target date、Status フィールドも含みます
  4. Sprint フィールドと Epic フィールドにレインボーカラーとスプリント目標の説明を適用する(セクション 13)
    • Sprint のオプション:RED→ORANGE→YELLOW→GREEN→BLUE→PURPLE→PINK の順で繰り返します
    • Sprint の説明 = sprint-plan.md のスプリント目標
    • Epic のオプション:RED→ORANGE→YELLOW→GREEN→BLUE→PURPLE→PINK→RED→ORANGE→YELLOW→GREEN→BLUE
  5. ラベルを作成する(セクション 5)— 合計 17 個のラベル
  6. フェーズベースのマイルストーンを作成する(セクション 6)— PoC と Production Hardening

重要: updateProjectV2Field を呼び出して色や説明を設定すると、単一選択オプション ID が変更されます(ミューテーションによってオプションリストが置き換えられます)。このミューテーションを呼び出した後は、必ずオプション ID を再照会し、新しい ID を設定に使用してください。

Step 6: 設定ファイルを作成する

今すぐ references/config-schema.md を読んでください — 正確な YAML 形式が必要です。

スキーマに従って、すべての ID を入力した .github-sync.yaml をプロジェクトのルートに作成します。 注:field_ids または option_ids に phase フィールドはありません — Phase はマイルストーンに置き換えられています。

Step 7: 完了を報告する
Onboarding complete!
  Project: https://github.com/orgs/{owner}/projects/{number}
  Config: .github-sync.yaml

Next: Run "push stories to github" to create issues.

Push ワークフロー(ファイル → GitHub)

BMAD ストーリーファイルを GitHub のイシューとしてプッシュし、プロジェクトに追加して、すべてのフィールドを設定し、日付フィールドを設定して、関連付けを確立します。

Step 1: 設定を読み込む

.github-sync.yaml を読み込みます。すべてのフィールド ID が入力済みであることを確認します。空のフィールドがある場合は、GitHub からフィールド ID を再照会します(ID が失われている可能性があります)。

Step 2: ストーリーをスキャンする
python3 .agents/skills/github-sync/scripts/parse-artifacts.py --mode scan \
  --stories-dir .artifacts/implementation-artifacts

各ストーリーについて、作成モードと編集モードのどちらかを判定します。

  • H1 がプレーンな # Story X.X: Title(リンクなし)→ 作成
  • H1 に # [Story X.X: Title](url) が含まれる → 更新(同期済み)
Step 3: 一部のストーリーのみ同期する(任意)

ユーザーがフィルターを指定した場合(例:「push stories 1.1 1.2」「push epic 1」「push sprint 2」)、続行する前にストーリーリストをフィルタリングします。フィルターが指定されていない場合は、すべてのストーリーをプッシュします。

Step 4: ストーリーファイルを読み込み、イシューの内容を作成する

⚠️ ルール 4 が適用されます:各ファイルは Read ツールで読み込んでください。本文は手動で作成します。スクリプトは使用しません。

各ストーリーについて:

  1. Read ツールを使用してファイルを読み込む
  2. references/content-mapping.md を読む — 正確な形式についてセクション 1~4 と 9 を参照します
  3. テンプレートに従ってイシューの本文を作成する:
    • ユーザーストーリーの引用ブロック
    • AC は Then 節の要約を 1 行ずつ記載(チェックボックス)
    • タスクリスト全体(Task 2 以降のみ — エージェント専用のタスクは、位置ではなく内容を読んで除外します)
    • #N 形式の GitHub イシュー番号を使った依存関係
    • 折りたたみ可能な開発メモ:表、設定スニペット、アーキテクチャパターン — コードのスケルトン、ASCII ツリー、「What NOT to Do」リスト、参考資料は含めません
  4. sprint-plan.md からスプリント/開発者/エピックを確認する(ストーリーファイルの本文からは確認しません)
Step 5: 同期レポートを作成する
=== GITHUB SYNC — PUSH REPORT ===
Generated: {timestamp}

--- CREATES ({count} new issues) ---

  [CREATE] {story_id} {short_title}
           File: {story_file_path}
           Epic: {epic_label} | Sprint: {sprint} | Dev: {dev} | Phase: {phase}
           Labels: epic:{N}-{name}, phase:{phase}
           Milestone: {PoC | Production Hardening}

--- UPDATES ({count} existing issues) ---

  [UPDATE] {story_id} {short_title} (#{issue_number})
           Changes: body updated

--- SKIPPED ({count} items) ---

  [SKIP] {story_id} {short_title} — already synced, no local changes

--- SUMMARY ---
Creates: {N} | Updates: {N} | Skips: {N}

Proceed? [Y/N]

ここで停止してください。ユーザーの承認を待ちます。

Step 6: Push を実行する

承認された場合、CREATE ごとに次の手順を実行します。

  1. 課題の本文を一時ファイルに書き込みます(/tmp/issue-{story_id}.md)
  2. gh issue create --title "..." --body-file /tmp/... --label "epic:X-name" --label "phase:poc" --milestone "{PoC|Production Hardening}"
  3. 出力から課題の URL を抽出します
  4. gh project item-add {project_number} --owner {owner} --url {issue_url} --format json
  5. JSON 出力からアイテム ID を抽出します
  6. gh project item-edit を使って、すべてのプロジェクトフィールドを設定します。
    • Story ID(テキスト)
    • Epic(単一選択オプション)
    • Sprint(単一選択オプション、例:「Sprint 01」)
    • Dev(単一選択オプション)
    • Sprint Start(sprint-plan.md の日付)
    • Sprint End(sprint-plan.md の日付)
    • Status(Backlog)
    • Start date(Sprint Start と同じ日付 — 既存のフィールド)
    • Target date(Sprint End と同じ日付 — 既存のフィールド)
  7. ローカルファイルにリンクを記録します。H1 を # [Story X.X: Title](issue_url) に置き換えます。

UPDATE ごとに次の手順を実行します。

  1. 更新した本文を一時ファイルに書き込みます
  2. gh issue edit {number} --body-file /tmp/... --milestone "{phase_milestone}"
  3. スプリントまたはエピックが変更された場合は、プロジェクトフィールドを更新します
Step 7: 関連付けを設定する

すべての課題を作成した後、GitHub ネイティブの関連付けを設定します。

正確な GraphQL ミューテーションについては、references/gh-commands.md のセクション 12 を読みます。

7a. 親としてのエピック追跡課題

エピックごとにエピック追跡課題を 1 件作成します(まだ作成されていない場合)。本文のテンプレートについては、 references/content-mapping.md のセクション 10 を参照してください。その後、各ストーリーについて、 エピック追跡課題を親として設定します。

mutation {
  addSubIssue(input: {
    issueId: "{epic_tracking_issue_node_id}"
    subIssueId: "{story_issue_node_id}"
    replaceParent: true
  }) {
    issue { number }
    subIssue { number }
  }
}
7b. ブロックされる依存関係

sprint-plan.md の依存関係テーブル(各スプリントのストーリーテーブルにある Dependencies 列)を読み取ります。依存関係 A → B(ストーリー A がストーリー B に依存)ごとに、次を実行します。

mutation {
  addBlockedBy(input: {
    issueId: "{story_A_node_id}"
    blockingIssueId: "{story_B_node_id}"
  }) {
    issue { number }
    blockingIssue { number }
  }
}

依存関係は必ずストーリーファイルの本文ではなく、sprint-plan.md から取得してください。 スプリント計画が、依存関係の正規の記録です。

次のコマンドで課題のノード ID を取得します。

gh api graphql -f query='
  query {
    repository(owner:"{owner}", name:"{repo}") {
      issues(first:50, orderBy:{field:CREATED_AT, direction:ASC}) {
        nodes { number id title }
      }
    }
  }
'
Step 8: 完了を報告する
Push complete!
  Created: {N} issues
  Updated: {N} issues
  Skipped: {N} items
  Relationships set: {N} parent, {M} blocked-by

Config updated: last_synced = {timestamp}

Pull ワークフロー(GitHub → ファイル)

GitHub からステータス、担当者、タスクの完了状況をローカルの BMAD ファイルに取り込みます。

Step 1: 設定を読み込み、GitHub に問い合わせる

.github-sync.yaml を読み取ります。次に、プロジェクトアイテムの完全な GraphQL クエリを取得するため、references/gh-commands.md のセクション 9 を読みます。クエリを実行して、すべてのプロジェクトアイテムを取得します。

Step 2: アイテムをローカルファイルと照合する

「Story ID」フィールドに値がある GitHub アイテムごとに、次の手順を実行します。

  1. 一致するローカルストーリーファイルを見つけます(ストーリー ID → ファイル名のパターン)
  2. GitHub の状態とローカルファイルの状態を比較します。
    • ステータス:GitHub のステータスとローカルの Status: 行
    • 担当者:GitHub の担当者とローカルの開発者マッピング
    • タスクのチェックボックス:GitHub の課題本文のチェックボックスとローカルファイルのチェックボックス
Step 3: 同期レポートを生成する
=== GITHUB SYNC — PULL REPORT ===
Generated: {timestamp}

--- FILE UPDATES ({count} items) ---

  [UPDATE] {story_filename}.md
           Status: ready-for-dev → done (from GitHub #{issue_number})
           Assignee: (none) → @{username}

--- NO CHANGES ({count} items) ---

  [OK] {story_filename}.md — in sync

--- GITHUB-ONLY ({count} items) ---

  [WARN] GitHub #{N} "{title}" — no matching local file

--- SUMMARY ---
File updates: {N} | No changes: {N} | Warnings: {N}

Proceed? [Y/N]

ここで停止してください。ユーザーの承認を待ちます。

Step 4: Pull を実行する

承認された場合、ファイルの更新ごとに次の手順を実行します。

  1. ストーリーファイルを読み取ります
  2. マッピングされた BMAD ステータスで Status: 行を更新します
  3. ファイルを書き戻します
  4. 設定の last_synced を更新します

ステータス確認(読み取り専用)

変更を加えずに、ローカルファイルと GitHub の状態を比較します。承認は不要です。

# Scan local files
python3 .agents/skills/github-sync/scripts/parse-artifacts.py --mode scan \
  --stories-dir .artifacts/implementation-artifacts

# Query GitHub items (full field values)
# Use GraphQL query from references/gh-commands.md section 9

比較テーブルを出力します。

=== GITHUB SYNC — STATUS ===

| Story | Local Status  | GitHub Status | Sprint | Synced? | Issue |
|-------|--------------|---------------|--------|---------|-------|
| 1.1   | ready-for-dev | Done          | 01     | NO      | #1    |
| 1.2   | ready-for-dev | Ready         | 01     | YES     | #2    |
| 2.1   | backlog       | (not synced)  | 02     | NO      | —     |

Summary: {N} in sync, {M} out of sync, {K} not yet pushed

部分同期フィルター

フィルター例効果
ストーリー ID 別push stories 1.1 1.2 1.3これらのストーリーのみ
エピック別push epic 3Epic 3 のすべてのストーリー
スプリント別push sprint 2Sprint 2 に割り当てられたすべてのストーリー
ステータス別push unsyncedまだプッシュされていないストーリーのみ
すべてpush または push allすべてのストーリー(デフォルト)

エラー処理

エラー対応
gh コマンドがゼロ以外の終了コードを返すエラー出力を表示し、修正方法を提案して停止します
設定にフィールド ID がないgh-commands.md のセクション 4 を使ってフィールド ID を再取得します
レート制限に達した(HTTP 429)警告を表示し、60 秒待つよう提案して停止します
ストーリーファイルの形式が想定外警告を同期レポートに記載してスキップします
マイルストーンがすでに存在する作成をスキップします(冪等)
ラベルがすでに存在する作成をスキップします(冪等)
ストーリーのイシューがすでに存在する更新モードに切り替えます
単一選択オプションの ID が古いupdateProjectV2Field の呼び出し後に再取得します。このミューテーションはすべてのオプションを置き換え、新しい ID を発行します
addBlockedBy のペイロードフィールドエラー戻り値のフィールドは blockingIssue です(blockedByIssue ではありません)
updateProjectV2Field が projectId を拒否するこのミューテーションが受け取るのは fieldId のみで、projectId は受け取りません
updateProjectV2Field がオプションの id を拒否するオプションで使用するのは name/color/description のみです。id フィールドはありません

参照ファイル一覧

ファイル読むタイミング
references/gh-commands.md正確な gh CLI コマンドや GraphQL クエリが必要なとき
references/content-mapping.mdイシュー本文の作成、フィールドのマッピング、ラベル/マイルストーンの方式の確認が必要なとき
references/config-schema.md.github-sync.yaml の作成または読み取りが必要なとき

コメント