feat: PLAN32-migrate-cmd env から project.yml への変換コマンド - #107
Conversation
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>
0e576b4 to
38680ff
Compare
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | REQUEST_CHANGES
移行のデータ保全とプロジェクト単位の失敗隔離を修正してください。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | gemini | REQUEST_CHANGES
自動マイグレーションの堅牢性(エラーハンドリング)に 1 点懸念があります。レガシーな env ファイルから予期せぬ文字列が流れてきた場合でも、一括移行のバッチ処理全体がクラッシュしないように例外処理を調整してください。
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>
🔧 /ndf:fix サマリ (round 1)対応件数: critical=0 / major=4 / minor=0 (合計 4 件) codex 3 件・gemini 1 件すべて独自に再判定した結果、いずれも実害のある 詳細
atomic write では追加で symlink 自体を置き換えない ( 検証
|
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | codex | REQUEST_CHANGES
YAML 文字列スカラーの暗黙型変換を防ぎ、旧 env で有効なリポジトリ名を欠落なく移行してください。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | gemini | APPROVE
- 移行対象のキーを allowlist で限定し、既存の
project.ymlを保護するフェイルセーフな設計が移行スクリプトとして適切です。 os.replaceによるアトミックな書き込みや、パース失敗時に当該プロジェクトのみをfailedに倒して後続を止めないエラーハンドリングが実装されており、バッチ処理として堅牢です。envが空になった場合もファイルを残す処理(compose の制約への配慮)や、symlink 先の実体を正しく解決する仕組みがテストと共に正しく実装されていることを確認しました。
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>
🔧 /ndf:fix サマリ (round 2)対応件数: critical=0 / major=1 / minor=0 (合計 1 件) round 2 の未解決指摘は codex の 1 件のみ (gemini は APPROVE)。独自に再判定した結果、 詳細
生成物の形式は変わりません。 最小引用なので 引用化の副作用として 検証
|
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 3 | codex | APPROVE
追加の修正必須事項はありません。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 3 | gemini | APPROVE
変更内容を確認しました。スキーマの厳密な検証(型チェックや制御文字の排除)、移行ツールの安全なファイル書き換え(アトミック操作)、コンテナ側でのシェルスクリプトの堅牢なパース処理など、全体的に手堅く実装されており、テストも十分に書かれているため指摘事項はありません。
Summary
旧
env形式のプロジェクト定義をproject.ymlへ変換するコマンドdevbase project migrate-configを追加します。変換対象キー:
GIT_USER/GIT_REPO/GIT_HOST/WORK_DIR/CONTAINER_SCALE/DEVBASE_OPEN_EDITOR設計上の判断
ENABLE_SSH、AWS_CONFIG_BASE64など)はenvにそのまま残す。配布中の定義は 3 リポジトリ 136 件あり、取りこぼしを機械的に防ぐ必要があるproject.ymlは上書きしない。手で複数リポジトリ構成へ整えたものを壊さないため。envの旧キー掃除だけは行うので、何度実行しても同じ状態に収束するenvファイル自体は消さない。compose.ymlがenv_file: - envで参照しており、実在しないと compose が起動時に落ちるため。空になった場合はファイルの役割を書いた雛形を残すfailedとして報告する--projects-dir:projects/<name>は plugin リポジトリへの symlink で、実体側が書き換わる(そこが定義の正なので意図どおり)。一方 plugin リポジトリには devbase へリンクしていない projects もあるため、ディレクトリを直接指定できるようにした実データでの確認
--dry-runを実際のprojects/(42 件)に対して実行し、gitlab.com ホストのプロジェクトがhost: gitlab.comを持つこと、書き換え先が plugin リポジトリ内の実体パスになることを確認済みです。issues/PLAN32_multi-repo-project.mdの Task 4Test plan
uv run pytest tests/project/test_migrate.py— 15 件(生成内容 / 旧キー削除 / コメント削除 / 空 env の扱い / 非既定 host・work_dir /open_editor: false/ 任意キー未指定 / dry-run / 冪等性 / 既存 project.yml の保護 / 変換不能・env 欠落のスキップ / 検証失敗 / ディレクトリ走査 / symlink 解決)uv run pytest tests/commands/test_project_migrate_config.py— 7 件(全件変換 / dry-run / プロジェクト指定 / 未知プロジェクト / 変換失敗時の終了コード /--projects-dir/ 不在ディレクトリ)uv run pytest— 全 1344 件 green--dry-run