github-sync について
github-syncは、BMADの計画ファイルとGitHub Projects v2を双方向に同期するスキルです。フィールドごとのデータ所有元を守り、変更前にレポートの提示と承認を求めます。
主な機能
- 01BMADとGitHub Projectsの双方向同期
- 02プロジェクトの初期設定と構成
- 03ストーリーをGitHub Issueに登録
- 04ステータス、担当者、タスク完了状況の取得
- 05承認制の変更と冪等な同期
活用シーン
- 01BMAD成果物向けGitHub Projectの設定
- 02計画ストーリーからGitHub Issueを作成
- 03GitHubの進捗をローカルストーリーに反映
- 04同期前に変更内容を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bmad-labs/ skills --skill github-syncインストール後、Claude Code で/github-syncを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/evals.jsonreferences/config-schema.mdcontent-mapping.mdgh-commands.mdscripts/parse-artifacts.py詳細
GitHub Sync — BMAD から GitHub Projects v2 への同期
Markdown ファイルに保存されている BMAD の計画成果物(エピック、ストーリー、スプリント計画)と、視覚的なプロジェクト追跡に使用する GitHub Projects v2 の双方向同期です。
クイックナビゲーション
ghCLI コマンド、GraphQL クエリ →references/gh-commands.md- Issue 本文テンプレート、フィールドマッピング、ラベル、マイルストーン →
references/content-mapping.md- 設定ファイルの形式 →
references/config-schema.md- 成果物パーサースクリプト →
scripts/parse-artifacts.py
4 つのルール(決して破らないこと)
-
自動で同期しないでください。 すべての変更操作(Issue の作成、フィールドの更新、ファイルの変更)では、まず同期レポートを生成してユーザーに提示し、明示的な承認を待ってから実行する必要があります。ユーザーには、何が変更されるかを正確に示す必要があります。
-
フィールド単位で正とする情報源を定めます。 各フィールドの所有者は、BMAD ファイルまたは GitHub のどちらか一方です。同期時には、常に所有者側の値が優先されます。所有者のデータを上書きしないでください。
- BMAD が所有するフィールド: ストーリー本文、受け入れ条件、タスク、スプリントの割り当て、エピックのグループ化、依存関係
- GitHub が所有するフィールド: ステータス、開発担当者の割り当て、タスクのチェックボックスの完了状態、ストーリーポイント、優先度
-
冪等な操作にします。 同じ同期を 2 回実行しても、結果は同じになります。ストーリーファイル内の H1 タイトルリンクと、計画ファイルのフロントマターにある
gh_item_urlのリンクバック識別子によって、重複作成を防ぎます。作成前に、既存の同期状態を必ず確認してください。 -
スクリプトで 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 を読んでください — 以下の各操作で使う正確なコマンドが必要です。
承認された場合は、次の順序で実行します。
- GitHub Project を作成または接続する(セクション 2)— 既存のものを使用する場合は、そのノード ID を取得するだけです
- カスタムフィールドを作成する(セクション 3)— Story ID、Epic、Sprint、Dev、Sprint Start、Sprint End、Story Points
- すべてのフィールド ID を照会する(セクション 4)— 既存の Start date、Target date、Status フィールドも含みます
- 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)— 合計 17 個のラベル
- フェーズベースのマイルストーンを作成する(セクション 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 ツールで読み込んでください。本文は手動で作成します。スクリプトは使用しません。
各ストーリーについて:
- Read ツールを使用してファイルを読み込む
references/content-mapping.mdを読む — 正確な形式についてセクション 1~4 と 9 を参照します- テンプレートに従ってイシューの本文を作成する:
- ユーザーストーリーの引用ブロック
- AC は Then 節の要約を 1 行ずつ記載(チェックボックス)
- タスクリスト全体(Task 2 以降のみ — エージェント専用のタスクは、位置ではなく内容を読んで除外します)
#N形式の GitHub イシュー番号を使った依存関係- 折りたたみ可能な開発メモ:表、設定スニペット、アーキテクチャパターン — コードのスケルトン、ASCII ツリー、「What NOT to Do」リスト、参考資料は含めません
- 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 ごとに次の手順を実行します。
- 課題の本文を一時ファイルに書き込みます(
/tmp/issue-{story_id}.md) gh issue create --title "..." --body-file /tmp/... --label "epic:X-name" --label "phase:poc" --milestone "{PoC|Production Hardening}"- 出力から課題の URL を抽出します
gh project item-add {project_number} --owner {owner} --url {issue_url} --format json- JSON 出力からアイテム ID を抽出します
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 と同じ日付 — 既存のフィールド)
- ローカルファイルにリンクを記録します。H1 を
# [Story X.X: Title](issue_url)に置き換えます。
UPDATE ごとに次の手順を実行します。
- 更新した本文を一時ファイルに書き込みます
gh issue edit {number} --body-file /tmp/... --milestone "{phase_milestone}"- スプリントまたはエピックが変更された場合は、プロジェクトフィールドを更新します
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 アイテムごとに、次の手順を実行します。
- 一致するローカルストーリーファイルを見つけます(ストーリー ID → ファイル名のパターン)
- GitHub の状態とローカルファイルの状態を比較します。
- ステータス:GitHub のステータスとローカルの
Status:行 - 担当者:GitHub の担当者とローカルの開発者マッピング
- タスクのチェックボックス: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 を実行する
承認された場合、ファイルの更新ごとに次の手順を実行します。
- ストーリーファイルを読み取ります
- マッピングされた BMAD ステータスで
Status:行を更新します - ファイルを書き戻します
- 設定の
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 3 | Epic 3 のすべてのストーリー |
| スプリント別 | push sprint 2 | Sprint 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 の作成または読み取りが必要なとき |