コンテンツにスキップ

GitHub リポジトリからプロジェクトを作成する

エージェントを GitHub リポジトリに向けるだけで、動くボードが返ってきます。すべてのイシューがストーリーになり、その履歴が示すとおりの状態に置かれ、チェックリスト・ラベル・マイルストーンも一緒に引き継がれます。そのあと同じエージェントがストーリーを取り上げ、自分のものにし、ステートマシンを進め、自分が開いたプルリクエストをリンクします。

このページはそのループを端から端まで扱います。作成のステップには二つの経路があります。GitHub-to-EAT(East Agile のオープンソース・インポーター)は 1 コマンドで済ませます(手順 3)。インポート API は同じ処理を呼び出しごとに行い(手順 4 と 5)、ジョブハンドルが欲しいエージェントはこちらを駆動します。それ以降はすべて API 上で動きます。残りをエージェントが無人で進められることこそが要点だからです。

これは別物の「AI インポート」ではありません。 作成のステップは、プロジェクト設定 → インポート / エクスポート から手動で実行できるのと同じ GitHub インポーターであり、操作手順 → 他のトラッカーからのインポート で説明されています。エージェントはあなたと同じエンドポイントを呼びます。このページが加えるのはその周辺のすべてです。誰が鍵を持つのか、書き込む前にインポートをどう確認するのか、そしてボードができたあとエージェントがそれをどう扱うのか。

Import / Export タブの GitHub ソース:オーナーとリポジトリを入力し、トークンは空欄、プルリクエストとマイルストーンにチェック

  • プロジェクト — と、それを作成するためのセッションまたは ea_user_… キー。
  • エージェントキー — そのプロジェクトにスコープされた ea_agent_… キー。必要なロールは、ループのどこまでをエージェントに任せるかで決まります。手順 2 を参照してください。API ガイド → 2 種類のキー も参照。
  • GitHub のパーソナルアクセストークン — リポジトリのイシューへの読み取り権限つき。すべてのインポートは認証されます。取得が GitHub の GraphQL API 上で行われ、GraphQL はトークンを持たないリクエストを拒否するからです。省略できるのは Tracker があなたの代わりに取得する場合だけです。つまりパブリックリポジトリで、共有フォールバックトークンを持つデプロイ上(ホスト版の eastagiletracker.com は持っています。セルフホストの導入は運用者が GITHUB_IMPORT_PAT を設定するまで持ちません)であり、かつ GitHub-to-EAT の --engine direct ではないときに限ります。トークンとレート制限を参照してください。
  • Node.js 22+ — 手順 3 の GitHub-to-EAT 経路のみで必要です。API 経路に必要なのは curl だけです。

エージェントキーより先にプロジェクトが存在していなければならず、しかも人が作成する必要があります。エージェントキーは発行時に 1 つのプロジェクトに束縛され、プロジェクトをブートストラップできません。UI で作るか、自分の ea_user_… キーで作ります。

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: $TRACKER_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "hello-world", "iteration_length_weeks": 1}'

レスポンスには、以下のすべての呼び出しが必要とする project_id が入っています。

2. エージェントキーを発行する

Section titled “2. エージェントキーを発行する”

プロジェクトオーナーは プロジェクト設定 → エージェント でエージェントキーを作成します。選んだロールが、このページのどこまでをエージェントが単独でできるかを決めます。妥当な答えは二つあります。

  • owner — 1 本のキーでインポートを含むループ全体を回せます。インポートはプロジェクトの形を丸ごと書き換えるため、オーナー専用です。owner ロールのエージェントを発行するには、あなた自身がプロジェクトオーナーである必要があります。エージェントのロールが作成者のロールを超えることは決してありません。
  • member — 最小権限。エージェントはストーリーを取得し、動かし、コメントし、プルリクエストをリンクできますが、インポートはできません。インポートは自分のキーで自分で実行し(手順 5)、そのあとボードをエージェントに引き渡します。

いずれにせよ既定値のままにしないでください。新しいエージェントキーは指定がなければ viewer であり、viewer はボードを読めてもストーリーを取得・移動できません。それはこのループの大部分にあたります。

エージェントキーがここで重要なのは、アクセス権を超えた理由があります。エージェントキーは 1 つのプロジェクト内の名前を持つ参加者 として振る舞うため、作成したストーリー、行った状態変更、書いたコメントのすべてが履歴上そのエージェントに帰属します。あなた自身の作業と混ざらず、区別できます。

Terminal window
export TRACKER_TOKEN="ea_agent_xxxxx"

何よりも先にエージェントに /meta を読ませてください。

Terminal window
curl https://eastagiletracker.com/api/v1/meta \
-H "X-TrackerToken: $TRACKER_TOKEN"

これでエージェントが本来なら推測するしかない二つの問いに答えが出ます。キーがどのプロジェクトに束縛されているか(auth.project_id)と、ストーリー種別ごとにどの状態遷移が正当か(transitions)です。feature は unstarted → started → finished → delivered → accepted を通り、chore は unstarted → started → accepted だけです。マップを読むほうがハードコードより優れています。

GitHub-to-EAT は East Agile 自身のオープンソース・インポーターです。MIT ライセンスのコマンドラインツールで、作成のステップ全体 — 下の手順 4 と 5 — を 1 コマンドで行います。端末の前に人がいるときはこちらを使ってください。エージェントが無人で駆動し、ポーリングするジョブハンドルが欲しいときは、その下の API を使ってください。

Node.js 22+ が必要で、それ自身のランタイム依存はありません。まだ npm に公開されていないため、リポジトリからインストールします。

Terminal window
git clone git@github.com:EastAgile/GitHub-to-EAT.git
cd GitHub-to-EAT
npm install --global .

次に、手順 2 で発行したキーと手順 1 で作ったプロジェクトを指定します。

Terminal window
export EAT_AGENT_KEY="ea_agent_xxxxx"
github-to-eat --project $PROJECT_ID --repo octocat/hello-world

まずマッピングの凡例 — 選択した各種別がどう着地するか — を表示し、何かを書き込む前に確認を求めます。端末の外、パイプの中、CI やエージェントの中では、そのプロンプトを表示する場所がありません。したがって書き込みを伴う実行は --yes を渡す必要があります。渡さなければツールはあなたの答えを推測せず、2 で終了して何も書き込みません。再実行は安全です。すでにインポート済みのものはスキップされ、重複しません。

フラグ何をするか
--dry-runプリフライトのあと、実行するはずの計画 — 何件のストーリーをインポートし、既存として何件をスキップするか — を表示し、何も書き込みません。--yes は不要です。
--includeインポートする種別をカンマ区切りで指定します: issues,prs,milestones,releases,deps。既定は issues で、どの選択にもこれを含める必要があります。手順 6 の表と同じオプトインです。
--tokenあなたの GitHub パーソナルアクセストークン(環境変数や .envGITHUB_TOKEN も有効)。そのリポジトリに対して repo、または細粒度の Issues: Read が必要です。プライベート リポジトリ、共有フォールバックトークンのないサーバー、そして --engine direct では 常に 必須です。ホスト型サービスの既定エンジンで省略すると Tracker が自身の共有予算を消費します — トークンとレート制限を参照してください。
--engine既定の server/import/json を 1 回呼び、取得・マッピング・書き込みを Tracker に任せます。direct は同じパイプラインをあなたのマシンで実行し、代わりに公開 API 経由で書き込みます。つまり GitHub を自分で読むため常にトークンが必要で、無ければ 2 で終了します。
--states, --milestones, --story-type, --no-comments, --no-tasks1 回の実行だけマッピングを絞り込む、あるいは上書きします。何も永続化されません。いずれも --engine direct を含意します。

EAT_API_BASEEAT_APP_BASE を設定すると、セルフホストまたはローカルの Tracker に向けられます。どちらも既定ではホスト型サービスを指します。README には全フラグのリファレンス、終了コード、トラブルシューティングがあります。

以下はすべて、同じインポートを呼び出しごとに駆動したものです。エージェントが実行するときに欲しいのはこちらです。

インポートは オーナー専用 です。owner ロールのエージェントキーを使うか、エージェントを member のままにしたなら自分のキーを使ってください。何かを書き込ませる前に、まず dry_run で実行します。

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/import/json \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"owner": "octocat",
"repo": "hello-world",
"include_pull_requests": true,
"include_milestones": true,
"dry_run": true
}'

ドライランは GitHub から取得し、解決し、重複排除まで本番とまったく同じに行い、同じ件数 — importedskippederrorsunmatched — を報告してから、トランザクション全体をロールバックします。何も永続化されず、インポート完了イベントも監査ログに届きません。マイルストーンを含めるつもりだったこと、あるいはリポジトリが思ったより大きいことに、まだ何のコストもかからないうちに気づける、いちばん安上がりな方法です。

/import/json への呼び出しは、ドライランも含めてすべて非同期です。エンドポイントは結果ではなくジョブハンドルとともに 202 を返し、件数はジョブをポーリングしたとき(ステップ 5)にジョブ上に届きます。ドライランのジョブも本番と同じく done に到達します。違いは、何も書き込まれていないことだけです。

dry_run を外して再送します。先ほどと同様に、エンドポイントはジョブハンドルとともに 202 を返します。

{ "import_id": "…", "status": "pending" }

終端状態に達するまでジョブをポーリングします。

Terminal window
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/imports/$IMPORT_ID \
-H "X-TrackerToken: $TRACKER_TOKEN"

ステータスは pending → fetching → writing → done | failed と進みます。終端は最後の二つだけです。done は結果件数を、failed はエラーメッセージと分岐可能な安定した機械コードを持ちます。取得がページングしている間、progress_currentprogress_total が何ページ目かを示します。人が見ているなら表示する価値があります。

トークン。 "token": "github_pat_…" を渡します。省略するとサーバーが共有のプラットフォームトークンで代替します。これはパブリックリポジトリ専用で、そのデプロイ上のすべての呼び出し元にわたって消費されます — トークンとレート制限がその代償を説明します。どのトークンが使われても、それはアップストリームの GitHub 呼び出しを駆動するだけです。ログにも監査ログにも残らず、保存もされず、レスポンスやエラーでエコーバックされることもありません。

再実行は安全です。 すでにインポート済みの行はソース id で照合されてスキップされ、重複しません。2 回目のインポートは、1 回目以降に現れた分でボードを補充します。

イシューは既定でインポートされます。それ以外はすべてオプトインで、種別ごとに 1 フラグです。

GitHub 側変換先フラグ
イシューストーリー。オープン → Backlog の unstarted。クローズ → accepted。ただし GitHub が not_planned または duplicate としてクローズされたと示す場合は rejected(ストーリーには対応するラベルが付きます)。既定
イシュー本文のチェックリストタスク- [ ] / - [x] の各行が本文の順にタスク 1 件となり、[x] は完了状態で届きます。チェックリストは説明文にも残ります。既定
ラベルラベル。そのまま引き継がれます。既定
プルリクエストpull-request ラベルの付いた ストーリー。オープン → started、マージ済み → accepted、マージせずクローズ → rejectedinclude_pull_requests
マイルストーンマイルストーン名を冠した エピック。タイトルで重複排除されるため、同じマイルストーンを共有する 2 件のイシューは 1 つのエピックに入ります。フラグがオフなら、代わりに milestone:<タイトル> ラベルとして付いてきます。include_milestones
リリースリリースストーリー。公開済み → accepted、下書き → unstartedinclude_releases
イシューの依存関係ストーリー上の ブロッカー。イシューのみで、プルリクエストは対象外です。include_dependencies

ストーリー種別はイシューが明示しないときに推論されます。 bugfixdefect を含むラベル — あるいは fixbug で始まるタイトル — はバグに、choremaintenancedevopsinfra は chore に、それ以外は feature になります。インポート前に知っておく価値があります。East Agile Tracker では feature だけがポイントを持ち、feature だけがベロシティに反映されるからです。イントロダクション → ストーリーを参照してください。

サンプルリポジトリをインポートした直後のプロジェクトボード:Issue はラベル付きのストーリーに、マイルストーンはエピックに、GitHub の人はオーナーになる

7. エージェントがストーリーを進める

Section titled “7. エージェントがストーリーを進める”

ボードには履歴があり、エージェントには鍵があります。ここから先のループは 4 回の呼び出しです。

ストーリーを見つける、または書く。 取り上げるものをボードから絞り込みます。

Terminal window
curl "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories?state=unstarted" \
-H "X-TrackerToken: $TRACKER_TOKEN"

import_source=github はインポートが持ち込んだものに絞ります。リポジトリが記録していなかった作業をエージェントが見つけたなら、代わりにストーリーを作成します — API ガイド → ストーリーの作成を参照してください。

自分のものにする。 エージェントは空のボディを POST して自分をオーナーに追加します。

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/owners \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

空のボディは 呼び出し元 を意味するので、エージェントは自分の id を知る必要がありません。ボードはエージェントをオーナーとして表示し、見ている人はそれで作業が取られたと分かります。

着手する。

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/transitions \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to": "started"}'

そのあとエージェントは実際の作業に向かいます。リポジトリを読み、コードを書き、プルリクエストを開きます。その部分はここではなく、あなたのコーディングツールの中で起こります。

プルリクエストを添付する。

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/links \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/octocat/hello-world/pull/42"}'

GitHub のプルリクエスト URL はそれと認識されます。指定する必要はありません。ストーリーとそれを閉じるコードは、双方向にワンクリックの距離になります。

完了させる。 finished に遷移させ、そこで止めます。feature にはまだ deliveredaccepted が控えており、それがレビューのゲートです。作業が正しいかどうかは、エージェント以外の誰かが判断します。chore にはそのゲートがなく、started → accepted が残りの道のすべてです。

インポートしたクローズ済み Issue。CODE セクションに修正したプルリクエストへのリンクがあり、隣に GitHub のコメントがある

すべてのインポートは認証されます。イシュー・コメント・プルリクエストの取得は GitHub の GraphQL API 上で行われ、GraphQL はトークンを持たないリクエストを拒否します。パブリックリポジトリであろうとプライベートであろうと、匿名の階層は存在しません。問題は GitHub にトークンが 渡るかどうか ではなく、誰の トークンかだけです。

インポート呼び出しで token を渡すか、GitHub-to-EAT に --token を渡します。リポジトリのイシューに読み取り権限を持つ細粒度のパーソナルアクセストークンで十分です。それはアップストリームの GitHub 呼び出しを駆動するだけです。ログにも監査ログにも残らず、保存もされず、レスポンスやエラーでエコーバックされることもありません。

デモを超える用途なら自分のトークンを持ち込んでください。誰も触らない予算を使うことになり、他人のインポートを理由にプリフライトで拒否されることもなくなります。

--engine direct には選択の余地がありません。このエンジンは Tracker を介さずあなたのマシンから GitHub を読むため、サーバーのトークンは手が届きません。トークンなしの実行は、取得も書き込みもする前に使用法エラーとともに 2 で終了します。環境や .envGITHUB_TOKEN--token と同じく有効です。

トークンを強いるのはイシューの走査であって、エンジン全体ではありません。direct はイシュー、コメント、プルリクエストを GraphQL で読みます。GraphQL に匿名モードはありません。REST に触れるのはリリース一覧と無料の /rate_limit 照会だけです。このツールには、パブリックリポジトリのインポートを毎時 60 の枠内で走らせていた古い匿名 REST 取得器がまだ同梱されていますが、CLI のどの経路からも到達できなくなっており、削除が予定されています。したがって direct では --token を必須と考えてください。

token を送らなければ、サーバーは運用者が設定したプラットフォームトークン(GITHUB_IMPORT_PAT)で代替します。これには 3 つの制約が伴います。

  • これは任意の設定です。 ホスト版の eastagiletracker.com は 1 つを用意しているため、トークンなしのパブリックリポジトリのインポートはそこで動きます。セルフホストの導入 — ダウンロードしたバイナリ — は運用者が環境に GITHUB_IMPORT_PAT を設定するまで持たず、それまではトークンなしのインポートをすべて 400 import_github_no_token で拒否します。
  • パブリックリポジトリしか読めません。 ホスト型サービスはこれをパブリックリポジトリに対する読み取り専用として発行するため、プライベートリポジトリには常にあなた自身のトークンが必要です。
  • デプロイ上のすべての呼び出し元が 1 つの予算を共有します。 トークンなしのインポートを実行する前に、サーバーは共有トークンに残った GraphQL ポイントを読み、500 を下回っていれば 400 import_github_shared_quota_low で拒否します。インポートの途中で予算が尽きた場合は import_github_rate_limited_platform でジョブが失敗します。どちらのメッセージも同じ対処を示します。自分のトークンを渡してください。

GitHub は 2 つの API を別々に計測しており、未認証時の上限は 2 桁低くなります。

GitHub API用途トークンありトークンなし
GraphQLイシュー、コメント、プルリクエスト、サブイシュー、依存関係1 時間あたり 5,000 ポイント。クエリが返すノード数で採点されます拒否 — GraphQL に未認証の階層はありません
RESTリリース(include_releases)と /rate_limit のプリフライト1 時間あたり 5,000 リクエスト1 時間あたり 60 リクエスト。IP アドレスごとに数えられ、その背後にいる全員と共有されます

インポートがこの 1 時間 60 回の階層に落ちることはありません。送るトークンがなければ、匿名で再試行されるのではなく、事前に拒否されるからです。この数字が効いてくるのはインポートの 周辺 で何をするかです。GitHub を直接読むスクリプトや、他のクライアントと同じネットワークにあるシェルは、60 リクエストを数秒で使い切ります。

残り予算はいつでも読めます。GET /rate_limit は両方の制限から除外されているので、確認にコストはかかりません。

Terminal window
curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limit

GraphQL ポイントはリクエスト数ではありません。GitHub はクエリが返すノードで採点するため、コメントとアサイニーを伴う 100 件のイシュー 1 ページ分でも多くのポイントを消費し、大きなリポジトリは REST 時代の数字が示すよりはるかに少ない呼び出し回数で 1 時間分の予算を使い切ります。--dry-run(手順 3)と dry_run(手順 4)は本番の取得と同じポイントを消費します — だからこそその件数は信頼できます — 大きなインポートをプリフライトするときは 2 回分を見込んでください。

  • API ガイド — 検索文法、イベントストリーム、一括遷移、冪等な書き込み、その他のサーフェス。
  • 操作手順 — UI から見た同じ操作と、他の 10 個のインポーター。
  • イントロダクション — ステートマシンと 4 つのストーリー種別がこの形をしている理由。
  • GitHub-to-EAT — インポーター自身のリポジトリ。すべてのフラグ、両方のエンジン、そして貢献の方法。