Uh oh!
There was an error while loading. Please reload this page.
release: PLAN32 1 プロジェクト = 複数リポジトリ構成への変更 (v3.0.0) - #103
Merged
Conversation
issue i32 の「後方互換性配慮必要なし / 把握している plugin リポジトリを全て 新方式へ」に合わせ、旧 plan の後方互換前提を廃して project.yml を唯一の正と する設計に改めた。pilot は trygroup 2 repo と uttaro 3 repo (host 混在)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 22, 2026
* chore: PLAN32-entrypoint Draft PR 作成 * feat(entrypoint): 複数リポジトリの clone と workspace 書き出しに対応 PLAN32 Task 3。GIT_USER/GIT_REPO による単一 clone を廃し、ホストが渡す clone プラン (DEVBASE_REPOS = base64 TSV) を 1 行ずつ処理して /work 配下へ 複数リポジトリを clone する。branch 指定の checkout、init.sh の実行可否、 primary ディレクトリへの cd、複数 repo 用 workspace ファイルの書き出しを それぞれ関数に分けた。 clone / checkout / init.sh の失敗は warning に留めて次のリポジトリへ進む。 1 つ落ちただけで起動できないと、他リポジトリでの作業まで止まるため。 TSV の分解に `IFS=$'\t' read` は使っていない。タブは IFS の空白扱いで連続 する区切りが 1 つに畳まれ、branch 未指定の行で init がずれるため、パラメータ 展開で 1 フィールドずつ切り出している。 関数定義だけを source できるようにし (DEVBASE_ENTRYPOINT_LIB_ONLY)、 ローカルの bare リポジトリを clone 元にした単体テストを追加した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(entrypoint): checkout は clone 直後のみ + 失敗時は当該 repo を打ち切る - checkout 失敗時に continue し、意図しない branch で init.sh が走らないようにする - 既存 clone には checkout しない。コンテナ再起動のたびにユーザの作業ブランチから 設定 branch へ引き戻される問題を回避する - テストの PATH ハードコードをやめ、実行環境を引き継ぐ (DEVBASE_*/GIT_* のみ除去) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(entrypoint): clone プランの区切りを US (0x1f) にして空フィールドを保てるようにする タブ区切りは IFS の空白扱いで連続する区切りが 1 つに畳まれるため、branch 未指定の行で init の値がずれる。非空白の US (0x1f) にすると bash の自然な 読み方 (IFS='�' read -r ...) がそのまま正しく動くので、パラメータ展開に よる手動分解をやめて read に戻した。あわせて列数・init 値の検証を入れ、 壊れた行は警告に留めて次の行へ進む。 符号化側 (lib/devbase/project/config.py) と同じ契約に揃えている。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(PLAN32): clone プランの wire format 契約を US (0x1f) 区切りへ統一 plan と PR 本文が base64 TSV を契約としていた一方、entrypoint と符号化側 (encode_repo_plan) は US (0x1f) 区切りへ移行済みで、契約と実装が食い違っていた。 タブは IFS の空白として扱われ連続する区切りが 1 つに畳まれるため、branch 未指定 (空フィールド) の行で init の値がずれる。非空白の US なら IFS=$'\x1f' read が そのまま 4 列として読める。実装は既に正しいので、契約側 (plan) を US へ揃える。 - issues/PLAN32_multi-repo-project.md: スキーマ節の wire format を US 区切り (行区切り LF / 末尾 LF あり) の記述へ更新。代替案表にタブ区切りを不採用案として 理由付きで追加 - containers/base/entrypoint.sh: 行区切りと末尾 LF、符号化側の所在をコメントに明記 - tests/containers/test_entrypoint_repos.py: 実物の encode_repo_plan の出力を entrypoint に通す結合テストを追加 (config.py は Task 1 の別 PR なので importorskip で未導入ブランチでは skip) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: PLAN32-config-loader Draft PR 作成
* feat(project): project.yml ローダと clone プランの wire format を追加
PLAN32 Task 1。projects/<name>/project.yml を読み、defaults 継承・既定値
補完・検証を経て正規化した ProjectConfig を返すライブラリを追加した。
コンテナへは base64 TSV の clone プランとして渡す契約 (encode/decode) も
ここで確定させる。呼び出し元の差し替えは後続 PR で行うため、この PR 単体
では挙動は変わらない。
未知キー・dir 重複・primary 複数・空白混入は黙って通さずエラーにする。
project.yml が無い場合も旧 env 形式へフォールバックせず、移行コマンドを
案内するエラーにした (PLAN32 は後方互換を持たないため、移行漏れを検出
できる必要がある)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(project): YAML の型検証を厳密化し設定ファイルを UTF-8 で読む
- version: YAML の `true` が Python では `1` と等価なため bool を明示的に拒否
- defaults: `or {}` をやめ、null/未指定のみ空マッピングへ正規化
(`defaults: []` / `false` が黙って受理され型検証が素通りするのを防ぐ)
- project.yml の読み込みに encoding="utf-8" を明示し、UnicodeDecodeError は
「UTF-8 で保存してください」と案内する ConfigError に変換
- テストの write_text にも encoding="utf-8" を明示 + 上記の回帰テストを追加
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(project): version の型判定を厳密化し wire format の init 列を検証する
- version は `type(...) is int` で判定。YAML の `1.0` は float だが `1.0 == 1`
を満たすため、これまで schema version 1 として受理されていた
- decode_repo_plan で init 列が `1`/`0` 以外なら ConfigError。壊れた値や将来の
未知値を「init しない」として黙って通さない
- 非 UTF-8 (cp932) の project.yml が UTF-8 保存の案内を出すことをテストで固定
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(project): wire format の区切りを US にし末尾 LF を付けて bash 契約を固定
タブ区切りは bash の既定 IFS と同じ空白類のため、`IFS=$'\t' read -r url dir
branch init` では連続区切りが 1 つに畳まれ、branch 未指定 (空フィールド) の行で
init の値が branch にずれ込んでいた。区切りを US (\x1f) に変えると空白類ではない
ため空フィールドが保持され、bash 側の素直な読み方がそのまま正しく動く。
あわせて符号化結果に末尾 LF を付ける。`while read` は EOF 直前の改行なし行を
読み捨てるため、末尾 LF が無いと repo 1 件構成で唯一の行が丸ごと落ちていた。
契約 (区切りは \x1f / 行区切りは LF で末尾にもあり / 各フィールドは検証済みで
空白・制御文字を含まない) を docstring と PLAN32 の wire format 節に明記し、
実際の bash を `bash -c` で起動して読ませる回帰テストを追加した (Docker 不要)。
また YAML が int として読む `repo: 123` に「必須です」と出て紛らわしかったため、
未指定と型不一致でエラーメッセージを分けた。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(project): 空文字と非空白の制御文字を正しく弾き分ける
- 省略可能な branch に `branch: ""` を書くと「必須です」と返り矛盾していたため、
未指定 (None) / 型不一致 / 空文字 の 3 つをそれぞれのメッセージで書き分ける
- `isspace()` だけでは NUL・BEL・DEL やゼロ幅空白がすり抜け、encode_repo_plan の
「制御文字を一切含まない」という契約を満たせていなかったので、印字できない文字も
まとめて弾くようにした
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>* feat(up): project.yml を起動・スケール・エディタの唯一の設定源にする PLAN32 Task 2。devbase up がプロジェクトの project.yml を読み、正規化した clone プランを生成 compose の dev サービスへ環境変数として載せる。これで entrypoint が複数リポジトリを clone できる。 - lib/devbase/project/runtime.py を追加: コンテナへ渡す環境変数の組み立て (DEVBASE_REPOS / DEVBASE_PRIMARY_DIR / DEVBASE_WORKSPACE*)、workspace JSON の 生成、scale の読み書き。workspace の JSON はホスト側で組み立てて base64 で 渡すため、シェルでのエスケープが要らずテストもできる - scale の取得元と devbase scale の書き込み先を env の CONTAINER_SCALE から project.yml の scale へ移した。書き込みは行単位の置換にしてコメントと並び順を 保ち、書いた結果を読み直して壊れていれば元へ戻す - エディタは repo が 1 件なら primary のフォルダ、2 件以上なら entrypoint が 書き出した multi-root workspace を開く。自動オープンの有効判定は project.yml の open_editor > グローバル .env の DEVBASE_OPEN_EDITOR の順 - 旧 GIT_REPO / WORK_DIR / CONTAINER_SCALE を読む経路を削除した。project.yml が 無いプロジェクトは移行手順を案内するエラーで停止する (後方互換なし) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(scale): write_scale が scale 行の行内コメントを消さないようにする `^scale:.*$` の一括置換で `scale: 1 # 並列数` の行内コメントごと 消えており、「コメントを保持する」という関数の契約に反していた。 値部分と行内コメントを別々に捕まえ、値だけを差し替える。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
3 tasks
* feat(project): env から project.yml への変換コマンドを追加 PLAN32 Task 4。devbase project migrate-config で旧 env 形式 (GIT_USER / GIT_REPO / GIT_HOST / WORK_DIR / CONTAINER_SCALE / DEVBASE_OPEN_EDITOR) を project.yml へ機械的に変換する。配布中のプロジェクト 定義は 3 つの plugin リポジトリに 136 件あり、手で書き換えると取りこぼしが 混じるため。 - 変換対象キーは allowlist で限定し、それ以外 (ENABLE_SSH 等) は env に残す - 既存の project.yml は上書きしない。手で複数 repo 構成へ整えたものを壊さず、 env の旧キー掃除だけ行うので何度実行しても同じ状態に収束する - 旧キーを説明していた直前のコメント行も一緒に落とす。キーだけ消すと何を 説明しているか分からない行が残るため - 全部消えて空になった env にはファイルの役割を書いた雛形を残す (compose が env_file で参照するためファイル自体は消せない) - 生成した YAML はローダで検証してから書き出す - --dry-run で生成内容を確認でき、--projects-dir で devbase へリンクしていない plugin リポジトリ内の projects も直接変換できる Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(project): migrate-config を atomic 書き込みと失敗隔離で堅牢化 cross-review round 1 (codex / gemini) の指摘対応。 - 既存 project.yml が壊れている場合は load_project_config で検出し、env を 一切変更せず failed として返す。旧キーは唯一の復旧元であり、設定を読めない 状態で掃除すると構成が完全に失われるため - project.yml / env を同一ディレクトリの一時ファイルへ書いて os.replace する atomic write に変更。ディスクフルや中断で truncate されると「壊れた project.yml + 旧キーの無い env」から復旧できなくなる。symlink 自体を 置き換えないよう realpath 解決し、既存ファイルのパーミッションを引き継ぐ - migrate_project を薄いガードで包み、OSError / UnicodeDecodeError / yaml.YAMLError / ConfigError を failed の MigrationResult に畳む。136 件の 一括移行で 1 件の I/O・デコード失敗が全体を止めないようにする - _load_yaml は yaml.YAMLError を ConfigError にラップする。env に GIT_REPO="carmo のような閉じられていない引用符があると生成 YAML が壊れ、 その 1 件で一括移行がクラッシュしていた Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(project): migrate-config で文字列値の YAML 暗黙型変換を防ぐ GIT_REPO=123 / GIT_REPO=on のように旧 env では有効な文字列が、生成した project.yml では YAML 1.1 の暗黙タグで int / bool / date として読まれ、 ローダの「文字列で指定してください」に当たって移行が失敗していた。 host / owner / repo / work_dir は yaml.safe_dump にスカラー出力を任せ、 引用が必要な値だけを引用する。carmo-web のような通常の値は素のままなので、 既に移行済みのファイルと生成物の見た目は変わらない。 併せて、GIT_REPO="carmo のように env 側の引用符が閉じていない値は、 引用符込みのリポジトリ名として通ってしまわないよう malformed な env として failed に倒す。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 22, 2026
* docs: project.yml 方式のドキュメントを整備する PLAN32 Task 5。複数リポジトリ構成と project.yml への移行に合わせて利用者向け ドキュメントを更新した。 - docs/user/project-yml.md を新設: スキーマ、複数リポジトリの例、検証される 内容、env との使い分け、旧 env からの移行表、コンテナへの渡り方 - 環境変数ガイド / コンテナ操作ガイド / CLI リファレンス / プラグイン開発の 各所から旧キー (GIT_USER / GIT_REPO / WORK_DIR / CONTAINER_SCALE) の説明を 外し、project.yml とその参照へ置き換え - CLI リファレンスに devbase project migrate-config を追記 - アーキテクチャ解説に project/ モジュールの節を追加 - CHANGELOG に破壊的変更と再ビルドの注意を追記 過去リリース分の CHANGELOG 記述は履歴なので書き換えていない。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: レビュー指摘対応 — アンカー切れ修正と env ファイル必須の明記 - repo-backed-projects.md: 見出し変更で切れた `#スケール前提-container_scale1` 参照 2 箇所を `#スケール前提-scale-1` に修正 - quickstart.md: `env` はファイル自体が必須(中身は任意)と見出しから分かるよう変更し、 最小構成のディレクトリツリーへ `project.yml` を追加 - project-yml.md: `env` ファイルが必須である旨を同じ表現に揃える Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: DEVBASE_OPEN_EDITOR は env init の収集対象であることを明記 `devbase env init` の editor コレクター (lib/devbase/env/collectors/editor.py) が `DEVBASE_OPEN_EDITOR` を対話収集し、対話の既定は `1` (有効) である。 「収集対象外」「既定: OFF」という記述は実装と矛盾していたため、収集対象で あることと、OFF に倒れるのはキー自体が未設定のときだけである旨へ修正した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: init.sh の実行頻度と DEVBASE_WORKSPACE の有効範囲を実装に合わせる - project.yml リファレンス: `init` は clone 直後だけでなくコンテナ起動の たびに `./init.sh` を実行することを明記し、`branch` (clone 直後のみ) との タイミング差の表と冪等性の注意を追加 - 環境変数: `DEVBASE_WORKSPACE` が効くのはリポジトリ 1 件の構成だけで、 2 件以上では自動生成した workspace を直接開くため上書きできない旨を明記 - container-operations / plugin-dev quickstart の関連記述も同じ挙動へ揃える Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: 読み込み順序の表からも env の旧用途を外す env の役割を「コンテナへ渡す環境変数」と書き換えたのに、直上の表だけ 「リポジトリ名・コンテナ数等」と旧仕様のままで矛盾していた。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: work_dir の有効範囲と検証対象フィールドを正確にする - work_dir はリポジトリ 1 件のときだけ効く (2 件以上では自動生成の multi-root ワークスペースが開かれる) ことを明記 - 空白・制御文字の検証は repos[] の各項目が対象で、work_dir は前後の 空白を落とすだけなので、検証範囲を実装に合わせて限定した Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: project.yml 方式のドキュメントを整備する PLAN32 Task 5。複数リポジトリ構成と project.yml への移行に合わせて利用者向け ドキュメントを更新した。 - docs/user/project-yml.md を新設: スキーマ、複数リポジトリの例、検証される 内容、env との使い分け、旧 env からの移行表、コンテナへの渡り方 - 環境変数ガイド / コンテナ操作ガイド / CLI リファレンス / プラグイン開発の 各所から旧キー (GIT_USER / GIT_REPO / WORK_DIR / CONTAINER_SCALE) の説明を 外し、project.yml とその参照へ置き換え - CLI リファレンスに devbase project migrate-config を追記 - アーキテクチャ解説に project/ モジュールの節を追加 - CHANGELOG に破壊的変更と再ビルドの注意を追記 過去リリース分の CHANGELOG 記述は履歴なので書き換えていない。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: レビュー指摘対応 — アンカー切れ修正と env ファイル必須の明記 - repo-backed-projects.md: 見出し変更で切れた `#スケール前提-container_scale1` 参照 2 箇所を `#スケール前提-scale-1` に修正 - quickstart.md: `env` はファイル自体が必須(中身は任意)と見出しから分かるよう変更し、 最小構成のディレクトリツリーへ `project.yml` を追加 - project-yml.md: `env` ファイルが必須である旨を同じ表現に揃える Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: DEVBASE_OPEN_EDITOR は env init の収集対象であることを明記 `devbase env init` の editor コレクター (lib/devbase/env/collectors/editor.py) が `DEVBASE_OPEN_EDITOR` を対話収集し、対話の既定は `1` (有効) である。 「収集対象外」「既定: OFF」という記述は実装と矛盾していたため、収集対象で あることと、OFF に倒れるのはキー自体が未設定のときだけである旨へ修正した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: プロジェクト設定の破壊的変更に合わせて 3.0.0 へ上げる project.yml への移行はプロジェクト定義の互換性を壊すため、SemVer の major を上げる。プラグイン側は requires.devbase を ">=3.0.0" に更新して 非対応の devbase へインストールされないようにする必要がある (各 plugin リポジトリの PR で対応)。 CHANGELOG の [Unreleased] を [3.0.0] として確定し、ドキュメント中の バージョン表記も揃えた。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: 実行時版数・uv.lock・CHANGELOG 参照リンクを 3.0.0 へ同期 pyproject.toml だけを 3.0.0 にしたため、実行時の版数表示とロックファイルが 2.2.0 のまま取り残されていた。 - lib/devbase/__init__.py の __version__ を 3.0.0 へ (--version / status / export manifest の実体) - lib/devbase/cli.py, lib/devbase/commands/status.py の ImportError fallback も 同じ値へ同期 - uv.lock のローカルパッケージ版数を 3.0.0 へ (uv lock --check が通る状態に戻す) - CHANGELOG.md に [3.0.0] のリンク定義を追加し、[Unreleased] の比較開始点を v3.0.0 へ変更 - docs/user/env-export-import.md の manifest サンプルの devbase_version を 3.0.0 へ docs/user/plugin-registries.md の「devbase v2.2.0 以降」は当該仕様が導入された 版を指す履歴記述のため据え置く。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: init.sh の実行頻度と DEVBASE_WORKSPACE の有効範囲を実装に合わせる - project.yml リファレンス: `init` は clone 直後だけでなくコンテナ起動の たびに `./init.sh` を実行することを明記し、`branch` (clone 直後のみ) との タイミング差の表と冪等性の注意を追加 - 環境変数: `DEVBASE_WORKSPACE` が効くのはリポジトリ 1 件の構成だけで、 2 件以上では自動生成した workspace を直接開くため上書きできない旨を明記 - container-operations / plugin-dev quickstart の関連記述も同じ挙動へ揃える Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: 読み込み順序の表からも env の旧用途を外す env の役割を「コンテナへ渡す環境変数」と書き換えたのに、直上の表だけ 「リポジトリ名・コンテナ数等」と旧仕様のままで矛盾していた。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: plugin.yml の requires.devbase を実装どおりに文書化する CHANGELOG が 3.0.0 で requires.devbase: ">=3.0.0" への更新を求めているのに、 plugin.yml リファレンスに requires の記述が無く、プラグイン作者が何を書けばよいか たどれない状態だった (gemini round 2 の major 指摘)。 追記にあたって実装 (lib/devbase/plugin/syncer.py load_plugin_info) を確認したところ、 リファレンスとクイックスタートが載せていた plugins[] 配列 + projects[] 列挙の構造は どこからも読まれておらず、実際は plugin.yml が name / version / description / priority / requires.devbase を持つフラット形式で、プロジェクトは projects/ 配下の ディレクトリから自動検出される。旧構造のまま requires だけ足すと誤った位置を案内する ため、スキーマ記述を実装に合わせて訂正した上で追記している。 - plugin-yml-reference.md: 基本構造・フィールド一覧・使用例をフラット形式へ訂正。 requires (devbase 本体の最低バージョン。project.yml 形式は 3.0.0 以降でのみ読めるため ">=3.0.0" を指定する) と priority の詳細節を追加。プロジェクト自動検出を明記。 複数 Plugin を 1 リポジトリで配る場合は registry.yml を使う旨へ差し替え。 実在しないエラーメッセージを並べていたバリデーション表を実際の PluginError へ訂正。 - quickstart.md 1.2: plugin.yml サンプルをフラット形式 + requires.devbase へ更新。 検証: uv run pytest 1371 passed / 記載サンプルを load_plugin_info に通して requires_devbase='>=3.0.0' が取れることを確認。 * docs: plugin.yml の name/version 記述を実装の挙動へ揃える - name: 強制されない命名規則を「バリデーションルール」と書いていたため 「命名規則(推奨)」へ改め、省略時はディレクトリ名になることを追記 - version: サンプルの引用符の有無を基本構造の例と統一 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: project.yml 方式のドキュメントを整備する PLAN32 Task 5。複数リポジトリ構成と project.yml への移行に合わせて利用者向け ドキュメントを更新した。 - docs/user/project-yml.md を新設: スキーマ、複数リポジトリの例、検証される 内容、env との使い分け、旧 env からの移行表、コンテナへの渡り方 - 環境変数ガイド / コンテナ操作ガイド / CLI リファレンス / プラグイン開発の 各所から旧キー (GIT_USER / GIT_REPO / WORK_DIR / CONTAINER_SCALE) の説明を 外し、project.yml とその参照へ置き換え - CLI リファレンスに devbase project migrate-config を追記 - アーキテクチャ解説に project/ モジュールの節を追加 - CHANGELOG に破壊的変更と再ビルドの注意を追記 過去リリース分の CHANGELOG 記述は履歴なので書き換えていない。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: レビュー指摘対応 — アンカー切れ修正と env ファイル必須の明記 - repo-backed-projects.md: 見出し変更で切れた `#スケール前提-container_scale1` 参照 2 箇所を `#スケール前提-scale-1` に修正 - quickstart.md: `env` はファイル自体が必須(中身は任意)と見出しから分かるよう変更し、 最小構成のディレクトリツリーへ `project.yml` を追加 - project-yml.md: `env` ファイルが必須である旨を同じ表現に揃える Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: DEVBASE_OPEN_EDITOR は env init の収集対象であることを明記 `devbase env init` の editor コレクター (lib/devbase/env/collectors/editor.py) が `DEVBASE_OPEN_EDITOR` を対話収集し、対話の既定は `1` (有効) である。 「収集対象外」「既定: OFF」という記述は実装と矛盾していたため、収集対象で あることと、OFF に倒れるのはキー自体が未設定のときだけである旨へ修正した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: init.sh の実行頻度と DEVBASE_WORKSPACE の有効範囲を実装に合わせる - project.yml リファレンス: `init` は clone 直後だけでなくコンテナ起動の たびに `./init.sh` を実行することを明記し、`branch` (clone 直後のみ) との タイミング差の表と冪等性の注意を追加 - 環境変数: `DEVBASE_WORKSPACE` が効くのはリポジトリ 1 件の構成だけで、 2 件以上では自動生成した workspace を直接開くため上書きできない旨を明記 - container-operations / plugin-dev quickstart の関連記述も同じ挙動へ揃える Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(hooks): pre-up / deploy へ clone 先とリポジトリ URL を渡す PLAN32 で GIT_REPO / WORK_DIR が env から project.yml へ移った結果、それらを `source ./env` で読んでいたライフサイクルフックが値を取れなくなる。実際に plugin リポジトリの pre-up / deploy が壊れることを結合検証で確認した。 フックはホスト側で動くため、devbase 側から明示的に環境変数として渡す: - DEVBASE_PRIMARY_DIR: primary repo の /work 配下ディレクトリ名 - DEVBASE_PRIMARY_URL: primary repo の clone URL - DEVBASE_WORK_DIR: コンテナ内の既定の作業ディレクトリ - DEVBASE_REPO_DIRS: 全 repo のディレクトリ名 (空白区切り、宣言順) env を経由せず devbase が渡すことで、複数リポジトリ構成でもフックが clone 先を 一意に知れる。渡した値は子プロセス限定で、親の os.environ は汚さない。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: 読み込み順序の表からも env の旧用途を外す env の役割を「コンテナへ渡す環境変数」と書き換えたのに、直上の表だけ 「リポジトリ名・コンテナ数等」と旧仕様のままで矛盾していた。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: フックへ渡る環境変数を公式ガイドへ反映 pre-up / deploy へ渡す DEVBASE_PRIMARY_DIR / DEVBASE_PRIMARY_URL / DEVBASE_WORK_DIR / DEVBASE_REPO_DIRS は公開契約だが、ガイドは移行前の GIT_REPO / WORK_DIR を案内したままだった。フック作者がこの契約を使って 移行できないため、次を追記する。 - quickstart: 「フックへ渡る環境変数」表 (pre-up / deploy の別と DEVBASE_INSTANCE_INDEX が pre-up に渡らないことを含む) と、 DEVBASE_PRIMARY_URL を使う pre-up サンプル - repo-backed-projects: clone 先 / URL の受け取り方と pre-up 骨子、 関連環境変数節への追記、チェックリスト項目 - project.yml リファレンス: project.yml の各キーとの対応表 - CHANGELOG: Unreleased / Added へ本機能を記載 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: フック環境変数のテストが実行環境に影響されないようにする 親プロセスへ漏れないことを確かめるテストは、実行環境に同名の変数が居ると 偽陰性/偽陽性になる。事前に unset して初期状態を固定した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
takemi-ohama
left a comment
ContributorAuthor
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | APPROVE
修正が必要な問題は見つかりませんでした。
takemi-ohama
left a comment
ContributorAuthor
There was a problem hiding this comment.
🤖 cross-review | round 1 | gemini | APPROVE
仕様通りに project.yml への移行処理・検証・環境変数への展開が行われており、後方互換を廃したことによる設計の単純化も適切に実現されています。テストカバレッジやエラーハンドリングにも問題は見当たりません。
takemi-ohama
marked this pull request as ready for review
August 22, 2026 17:40
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
背景 / 解決したい課題
devbase はこれまで 1 プロジェクト = 1 コンテナ = 1 リポジトリを前提としていました。プロジェクトが clone するリポジトリは
projects/<name>/envのGIT_USER/GIT_REPOという単一ペアで指定するしかなく、次のことができませんでした。環境変数では配列を表現できないことがこの制約の根にあるため、プロジェクト設定を YAML (
projects/<name>/project.yml) へ移し、1 プロジェクトが複数リポジトリを持てる構成へ変更します。変更内容
プロジェクト設定
projects/<name>/project.yml(新設・設定の正)devbase upがproject.ymlを正規化した clone プランをコンテナへ渡し、entrypoint が/work配下へ全リポジトリを clone して primary へ移動します/work/<プロジェクト名>.code-workspace)で開きますscale(旧CONTAINER_SCALE)、open_editor(旧DEVBASE_OPEN_EDITOR)、work_dir(旧WORK_DIR)もproject.ymlへ集約し、envは「コンテナへ渡す環境変数」だけを持つ役割になりますpre-up/deploy)へはDEVBASE_PRIMARY_DIR/DEVBASE_PRIMARY_URL/DEVBASE_WORK_DIR/DEVBASE_REPO_DIRSを渡します。フックはホスト側で動きenvを読めないため、clone 先や URL を devbase から明示的に伝えますdevbase project migrate-configを追加しました(--dry-run付き・冪等)破壊的変更(v3.0.0)
後方互換は維持しません。
project.ymlを持たないプロジェクトはdevbase upが移行手順を案内して停止します。適用には
devbase build --no-cacheによるベースイメージの再ビルドが必要です(clone はentrypoint.shが行うため)プロジェクト定義を配布するプラグインリポジトリ側も同時に移行が必要です。
plugin.ymlのrequires.devbaseは">=3.0.0"へ更新してくださいplan:
issues/PLAN32_multi-repo-project.mdissue:
issues/i32.mdTest plan(結合観点)
一時プロジェクト(公開リポジトリのみ・稼働中の環境には影響なし)で確認済み:
/work/<dir>へ clone され、primary の dir にcdした状態になるbranch指定が clone 後のチェックアウトへ反映される/work/<プロジェクト名>.code-workspaceに生成されるpre-up/deployがDEVBASE_PRIMARY_DIR/DEVBASE_PRIMARY_URL/DEVBASE_WORK_DIR/DEVBASE_REPO_DIRSを受け取るproject.ymlの無いプロジェクトでdevbase upが終了コード 1 と移行手順の案内で停止するuv run pytest— 全 1377 件 greenマージ後に実環境で確認すること:
devbase build --no-cache後、統合したプロジェクト(uttarov2= GitLab + GitHub 混在の 3 リポジトリ /project-trygroup-prd= 2 リポジトリ)が起動するdevbase up --openで multi-root ワークスペースが開く開発用: 個別 PR 進捗 (レビュー対象外)