AWS Builder Center

AI-DLC Workflow V2のマルチリポジトリ運用: 兄弟配置と自動検出で複数リポジトリを扱う

バックエンドとフロントエンドでリポジトリが別々、そんなサービスをAI-DLCでどう回せばいいのか気になりませんか。この記事では、AI-DLC Workflow V2(以降V2)でコードが複数リポジトリに分かれている構成をどう扱うかを、兄弟配置と自動検出から `repos.json`、`aidlc-workspace-sync`、トラブルシュートまで見ていきましょう。シリーズ第27回。

Series: AI-DLC Workflow V2の解説 (31 articles)

  1. …
  2. 27
    AI-DLC Workflow V2のマルチリポジトリ運用: 兄弟配置と自動検出で複数リポジトリを扱う This article
AWS Japan, Developer Specialist SA

1. はじめに

この記事はV2解説シリーズの第27回です。
ワークスペースの構造そのものは、シリーズ第17回「SpaceとIntent」で扱いました。そこでは、1つのワークスペースの中で作業(Intent)とチームの世界(Space)をどう整理するかを見ています。本記事は、その先の実践に踏み込みます。1つのIntentが複数のコードリポジトリにまたがる、いわゆるマルチリポジトリ構成の運用です。
今回のゴールは、コードが複数リポジトリに分かれている状況でV2をどう活用するかを理解することです。この記事を読み終えると、リポジトリの配置と自動検出の仕組み、repos.json による宣言、aidlc-workspace-sync によるセットの再現、そして設計思想「Disk wins at runtime」までを扱えるようになります。
なお、Intent は1つの作業(ライフサイクルの1回の実行)を指す用語です。仕組みを詳しく知りたい場合は第17回「SpaceとIntent」を参照してください。

2. 前提: リポジトリが分かれているとはどういうことか

では、この記事が扱う前提を整理していきましょう。
コードの置き方には、大きく分けて2つの形があります。1つは単一リポジトリで、1つのリポジトリの中にサービスのコードをまとめる形です。この中には、複数のパッケージやサービスを1つのリポジトリに同居させるモノレポも含まれます。もう1つはマルチリポジトリで、サービスを構成するコードが複数のリポジトリに分かれている形です。
本記事は、後者の「コードが既に複数リポジトリに分かれている」前提に集中します。モノレポとマルチリポジトリのどちらを選ぶべきかという分割の是非には立ち入りません。ここで扱うのは、既に分かれている構成をV2でどう回すか、という運用の話だけです。
言い換えれば、この記事の設定は複数リポジトリに分かれている場合のものです。単一リポジトリで作業している場合は、V2は追加の設定なしで動くため、以降の内容は必要になったときに読み返せば十分です。

3. 兄弟配置と自動検出

では、リポジトリの配置と自動検出の仕組みを見ていきましょう。
V2では、コードリポジトリをワークスペースルート直下の兄弟として配置します。つまり、aidlc/ ワークスペースと同じ階層に、各コードリポジトリが直下の子ディレクトリとして並びます。それぞれのリポジトリは自分自身の .git を持ちます。コードリポジトリがどれか1つの中に入れ子になっているのではなく、横に並ぶ形です。
例として、バックエンドの checkout-api とフロントエンドの checkout-web という2つのリポジトリを持つ構成を挙げます。
1
2
3
4
my-project/
├── aidlc/ # ワークスペース
├── checkout-api/ # バックエンド(自分の .git を持つ)
└── checkout-web/ # フロントエンド(自分の .git を持つ)
この配置になっていると、V2はIntentの生成時に各兄弟リポジトリを自動検出します。検出の対象は、ワークスペースルートの直下の子で、かつ自分の .git を持つディレクトリです。検出したリポジトリのセットは、そのIntentの intents.json の行に記録されます。ここで特別なコマンドを打つ必要はありません。Intentを作成すると、そのとき実在する兄弟リポジトリが記録される、という流れです。
リポジトリを1つも記録しないIntentは、通常の単一リポジトリのケースになります。

4. repos.json: リポジトリセットの宣言

続いて、リポジトリセットを宣言する repos.json を見ていきましょう。
repos.json は、ワークスペースルートに置く任意のマニフェストです。役割は、期待されるリポジトリのセットを記録しておき、新規チェックアウトで同じセットを再現できるようにすることです。自動検出は兄弟リポジトリがすでにクローンされていることを前提とするため、共有ワークスペースを新しくチェックアウトした直後には、どのリポジトリをどこにクローンすべきかがわかりません。repos.json は、その期待セットを書き留めておくためのものです。
先ほどの checkout-api / checkout-web の構成なら、次のように書けます。
1
2
3
4
5
6
7
{
"org": "your-github-org",
"repos": [
{ "name": "checkout-api", "branch": "main" },
{ "name": "checkout-web" }
]
}
各フィールドの意味は次のとおりです。
  • org は既定のクローン元ホストを供給します。url を持たないエントリは git@github.com:<org>/<name>.git からクローンされます。
  • url をエントリに設定すると、org から導かれる既定のクローン元を上書きします。
  • branch は新規クローンのチェックアウト先を選びます。すでにディスク上にあるリポジトリに対しては助言的な期待値として扱われ、省略するとそのリポジトリ自身の既定ブランチが使われます。
  • name はリポジトリ名で、安全な単一パスセグメントである必要があります。これはランタイムの「直下の子」を探す検出モデルに合わせるためです。

5. aidlc-workspace-sync: セットの再現

では、宣言したセットを再現する aidlc-workspace-sync を見ていきましょう。
aidlc-workspace-sync は直接のツール呼び出しであり、/aidlc コマンドではありません。ワークスペースルートの repos.json を読み、マルチリポジトリのワークスペースをそのマニフェストに合わせて整えます。
1
aidlc system workspace-sync [--force]
このツールの主な動作は次のとおりです。
  • repos.json に宣言されていてディスク上に無いリポジトリをクローンします。新規クローンでは、宣言された branch がチェックアウトされます。すでにディスク上にあるリポジトリは、再クローンもブランチ切り替えもされません(不一致は助言にとどまります)。
  • ワークスペースの .gitignore のマネージドブロックを、リポジトリごとに /{name}/ の1行になるよう書き換えます。
  • ルートと各子リポジトリを列挙した aidlc.code-workspace(VSCodeのマルチルートワークスペースファイル)を書き出します。
これにより、新規チェックアウトのチームメイトは、1つのコマンドで同じリポジトリのセットを再現できます。どのリポジトリをどこに置くかを個別に共有しなくても、repos.json があれば手順が1つに収まります。
終了コードは次のように使い分けられます。0 は完全に同期済み、1 はブロックまたはエラー(実体は変更されません)、2 は同期は済んだが助言的な警告が残っている場合(例として、既存チェックアウトのブランチ不一致)です。

6. Disk wins at runtime: マニフェストは第二の真実ではない

ここで、V2のマルチリポジトリ運用を支える設計思想を整理しましょう。キーワードは「Disk wins at runtime」です。
最小限、次の2点を押さえておくと混乱しません。
1つ目は、ランタイムでは自動検出、つまり Disk wins at runtime(ディスク上の実在リポジトリが優先される)である、という点です。Intentの生成は、そのとき実際に存在する兄弟リポジトリを自動検出します。したがって、リポジトリは repos.json に宣言されているかどうかにかかわらず、クローンされた時点でそのIntentのセットに加わって動作します。逆に、宣言されていてもクローンされていないリポジトリは、単にセットに含まれません。
2つ目は、マニフェストは第二の真実のソースではない、という点です。repos.json が駆動するのは、aidlc-workspace-sync ツールと、--doctor の助言的な乖離チェックだけです。ランタイムの動作を決めるのはあくまでディスク上の実在リポジトリであって、マニフェストの記述ではありません。
つまり、repos.json は再現のための便利な記録であって、ランタイムの権威ではない、という位置づけです。

7. Construction でのマルチリポ動作

続いて、Construction フェーズでのマルチリポジトリ動作を見ていきましょう。ここでは詳細な手順ではなく、押さえておきたい要点に絞ります。
まず、Intentが作成された時点で、そのIntentが触れるリポジトリのセットが記録されます。そのうえで、Construction では各git操作が特定のリポジトリにアンカリングされます。アンカリングには --repo <name> が使われ、これはIntentが2つ以上のリポジトリにまたがる場合にのみ必要になります。単一リポジトリのIntentでは、git操作はワークスペース側でそのまま実行されるため、--repo の指定は不要です。
また、Reverse Engineering(既存コードの読み取り)やパイプラインチェーンは、リポジトリごとに走ります。複数リポジトリにまたがるIntentでは、それぞれのリポジトリが個別に扱われる、と捉えておけば十分です。

8. ベストプラクティス

では、これまでの内容を運用の指針としてまとめていきましょう。次の4点を軸にします。
1つ目は、マニフェストは任意であり「Disk wins at runtime」だと理解することです。自動検出とマニフェストの役割を混同しないでください。ランタイムで動作を決めるのは実在するリポジトリであり、repos.json はその再現を助ける記録です。
2つ目は、新規チェックアウトのチームメイトが aidlc-workspace-sync の1コマンドで同じリポジトリセットを再現できる、という利点を活かすことです。セットアップ手順を口伝で共有する代わりに、この1コマンドに集約できます。
3つ目は、repos.json をコミットして共有することです。宣言を第二の真実にするのではなく、再現と --doctor の駆動に使う、という使い方に留めます。
4つ目は、リポジトリ名を安全な単一パスセグメントにすることです。あわせて、branch と url の使い分けを押さえておきます。branch は新規クローンのチェックアウト先を選び、ディスク上のリポジトリへは助言的な期待値として働きます。url はエントリごとに、org から導かれる既定のクローン元を上書きします。

9. トラブルシュート

続いて、つまずきやすいところと対処を見ていきましょう。
repos.json が存在する場合、--doctor は宣言セットとディスクに関する助言的な行を報告します。1つは、宣言したリポジトリセットとディスク上の実在リポジトリが乖離しているときの行です。もう1つは、.gitignore のマネージドブロックが宣言セットに対して古く(stale に)なっているときの行です。いずれも助言的で、--doctor の終了コードを変えることはありません。乖離に気づいた ら、そのまま放置するのではなく、意図した状態かどうかを確認する手がかりとして使います。
.gitignore のマネージドブロックが古くなっている場合の対処は、aidlc-workspace-sync を再実行することです。再実行すると、マネージドブロックがリポジトリごとの /{name}/ の行に書き直され、aidlc.code-workspace も生成・更新されます。
オーファンチェックアウト、つまり repos.json に無いのにディスク上に存在するリポジトリは、sync の実行をブロックします。これがアクティブな兄弟セットから取り除かれるのは、--force を渡し、かつローカル固有の状態が無いことをツールが証明できた場合に限られます。証明にはローカルの状態確認に加えて実在リモートへの問い合わせが含まれ、いずれかに不確かさがあれば手動レビューのためにブロックします。取り除かれたチェックアウトの複製は、無視される .aidlc-workspace-sync-recovery-* ディレクトリに保持されるため、後から中身を確認できます。不要になったら手動で削除します。

10. まとめ

この記事では、V2でコードが複数リポジトリに分かれている構成をどう回すかを見てきました。
  • 兄弟配置と自動検出 — コードリポジトリをワークスペースルート直下の兄弟として置くと、V2はIntent生成時に各兄弟を自動検出し、そのセットを intents.json に記録する
  • repos.json — ワークスペースルートに置く任意のマニフェストで、org / repos(name / branch / url)で期待セットを宣言し、新規チェックアウトでの再現に使う
  • aidlc-workspace-sync — 不足リポジトリのクローン、.gitignore マネージドブロックの書き換え、aidlc.code-workspace の生成を1コマンドで行い、同じセットを再現する
  • Disk wins at runtime — ランタイムの権威はディスク上の実在リポジトリであり、マニフェストは sync と --doctor の乖離チェックを駆動する記録にすぎない
  • Construction — Intentが触れるリポジトリセットが記録され、各git操作は --repo <name> でリポジトリにアンカリングされる
  • トラブルシュート — --doctor の助言的な乖離行、.gitignore stale の対処(sync 再実行)、オーファンチェックアウトの --force 扱い
コードが複数リポジトリに分かれている構成でも、兄弟として並べておけばV2はそのまま自動検出で回ります。チームで再現性を持たせたくなったら、repos.json をコミットして共有し、aidlc-workspace-sync で揃える、という流れを試してみましょう。

Series: AI-DLC Workflow V2の解説 (31 articles)

  1. …
  2. 27
    AI-DLC Workflow V2のマルチリポジトリ運用: 兄弟配置と自動検出で複数リポジトリを扱う This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article