Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,6 +5,23 @@
## [Unreleased]

### Added
- **clone できなかったリポジトリを `devbase up` が知らせる**ようにしました。複数リポジトリ構成で
一部のリポジトリに権限が無い (または名前が違う) 場合、これまでは entrypoint の警告が
`docker logs` にしか出ず、`up` の画面は成功したように見えていました。コンテナ起動後に
`/work` の実体を確認し、`project.yml` に書いたのに無いリポジトリを clone URL 付きで
警告します。すべて揃っているときの出力は変わりません。clone の失敗が `up` を失敗させない
点も従来どおりです。

### Changed
- **multi-root ワークスペースに、clone できたリポジトリだけを載せる**ようにしました。これまでは
`project.yml` の内容をそのまま書き出していたため、clone に失敗したリポジトリが VS Code の
エクスプローラに「開けないフォルダ」として並んでいました。

> **Note:** ワークスペースの変更は `entrypoint.sh` の変更を含むため、反映には
> `devbase container build` (必要に応じて `--no-cache`) によるイメージの再ビルドが要ります。
> 再ビルドしていないイメージでは、これまでどおり全フォルダを載せたワークスペースが
> 書き出されます (機能が黙って失われることはありません)。

- **`plugin.yml` の `requires.devbase` をインストール時に検証**するようにしました。要件を
満たさない Plugin は `devbase plugin install` が中止します。これまでは値を読むだけで
比較しておらず、`project.yml` 形式の Plugin を 2.x へ入れられてしまい、`devbase up` の
Expand Down
64 changes: 59 additions & 5 deletions containers/base/entrypoint.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,12 @@ set -e
# lib/devbase/project/config.py の encode_repo_plan)
# DEVBASE_PRIMARY_DIR : 起動後に cd する /work 配下のディレクトリ名
# DEVBASE_WORKSPACE : 書き出す *.code-workspace の絶対パス (複数 repo 時)
# DEVBASE_WORKSPACE_B64 : その中身 (base64 JSON)
# DEVBASE_WORKSPACE_FOLDERS
# : base64 の行区切りレコード。1 行 = <dir> と folder オブジェクトの
# JSON を US (0x1f) で並べたもの。clone できた dir の行だけを
# 連結して workspace にする (PLAN37)
# DEVBASE_WORKSPACE_B64 : 完成済みの workspace (base64 JSON)。DEVBASE_WORKSPACE_FOLDERS を
# 渡さない古いホスト向けの fallback
#
# 関数定義だけを読み込みたいテストからは
# `DEVBASE_ENTRYPOINT_LIB_ONLY=1 . entrypoint.sh` で source する。
Expand DownExpand Up@@ -91,14 +96,63 @@ EOF

# 複数 repo をまとめて開くための *.code-workspace を書き出す。
#
# 中身はホスト側で組み立てて base64 で渡ってくるので、ここでは復号して置くだけ。
# JSON の組み立て (エスケープ) をシェルでやらない分、壊れにくい。
# clone できなかった repo のフォルダを載せると、VS Code のエクスプローラに開けない
# フォルダが並ぶ (PLAN37)。そこで DEVBASE_WORKSPACE_FOLDERS の各行を見て、
# <work_root>/<dir> が実在する行の JSON だけを連結する。
#
# 各 folder の JSON はホスト側が直列化済みなので、ここで組み立てるのは外枠 (
# `{"folders": [` … `]}`) とカンマだけ。dir に " や \ が入っていてもシェルで
# エスケープを考えずに済む。
devbase_write_workspace() {
local work_root="${1:-/work}"
[ -n "${DEVBASE_WORKSPACE:-}" ] || return 0
[ -n "${DEVBASE_WORKSPACE_B64:-}" ] || return 0

local dest="$DEVBASE_WORKSPACE"
mkdir -p "$(dirname "$dest")"

if [ -z "${DEVBASE_WORKSPACE_FOLDERS:-}" ]; then
# 旧ホスト (PLAN37 前) から起動された場合。完成品をそのまま置く。
devbase_write_workspace_verbatim "$dest"
return 0
fi

local records dir folder extra first=1
if ! records="$(printf '%s' "$DEVBASE_WORKSPACE_FOLDERS" | base64 -d 2>/dev/null)"; then
echo "Warning: Failed to decode DEVBASE_WORKSPACE_FOLDERS"
devbase_write_workspace_verbatim "$dest"
return 0
fi

{
printf '{\n "folders": [\n'
while IFS=$'\x1f' read -r dir folder extra; do
[ -n "$dir$folder$extra" ] || continue
if [ -z "$dir" ] || [ -z "$folder" ] || [ -n "$extra" ]; then
echo "Warning: Ignoring malformed workspace folder record" >&2
continue
fi
if [ ! -d "$work_root/$dir" ]; then
echo "Warning: Skipping workspace folder (not cloned): $dir" >&2
continue
fi
[ "$first" = "1" ] || printf ',\n'
printf ' %s' "$folder"
first=0
done <<EOF
$records
EOF
printf '\n ]\n}\n'
} > "$dest.tmp"

mv "$dest.tmp" "$dest"
echo "Workspace file written: $dest"
}

# ホストが組み立て済みの workspace (DEVBASE_WORKSPACE_B64) をそのまま書き出す。
devbase_write_workspace_verbatim() {
local dest="$1"
[ -n "${DEVBASE_WORKSPACE_B64:-}" ] || return 0

if printf '%s' "$DEVBASE_WORKSPACE_B64" | base64 -d > "$dest.tmp" 2>/dev/null; then
mv "$dest.tmp" "$dest"
echo "Workspace file written: $dest"
Expand DownExpand Up@@ -392,7 +446,7 @@ echo "AI agent settings symlinks setup completed"
# 個々の失敗はコンテナ起動を止めない (関数内で warning 扱い)。
DEVBASE_WORK_ROOT="${DEVBASE_WORK_ROOT:-/work}"
devbase_clone_repos "$DEVBASE_WORK_ROOT"
devbase_write_workspace
devbase_write_workspace "$DEVBASE_WORK_ROOT"
devbase_enter_primary_dir "$DEVBASE_WORK_ROOT"

# Signal that entrypoint setup is complete
Expand Down
2 changes: 1 addition & 1 deletion docs/developer/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -148,7 +148,7 @@ YAML の解釈をホスト側の Python に閉じ込めることで、コンテ
| モジュール | 役割 |
|-----------|------|
| `config.py` | `project.yml` の読み込み・`defaults` 継承・検証・正規化 (`ProjectConfig` / `RepoSpec`)。clone プランの符号化 (`encode_repo_plan`) |
| `runtime.py` | コンテナへ渡す環境変数の組み立て (`DEVBASE_REPOS` / `DEVBASE_PRIMARY_DIR` / `DEVBASE_WORKSPACE*`)、multi-root ワークスペース JSON の生成、`scale` の読み書き |
| `runtime.py` | コンテナへ渡す環境変数の組み立て (`DEVBASE_REPOS` / `DEVBASE_PRIMARY_DIR` / `DEVBASE_WORKSPACE*`)、multi-root ワークスペース JSON の生成 (`DEVBASE_WORKSPACE_FOLDERS` は folder ごとに直列化した形。entrypoint が clone できた repo だけを選べるようにするため)、`scale` の読み書き |
| `migrate.py` | 旧 `env` 形式 (`GIT_USER` / `GIT_REPO` 等) から `project.yml` への変換 |

```mermaid
Expand Down
20 changes: 20 additions & 0 deletions docs/user/project-yml.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,6 +97,26 @@ clone URL は `https://<host>/<owner>/<repo>.git` で組み立てられます。
- `repos[]` の `host` / `owner` / `repo` / `dir` / `branch` に空白・制御文字が混ざっている
- `dir` が `/work` 直下から外れている(`../` や入れ子のパス、`.` / `..`)

## clone できないリポジトリがあるとき

primary には権限があるがサブリポジトリには権限がない、という構成は起こりえます。この場合
**権限のあるリポジトリだけが clone され、コンテナは通常どおり起動します**。1 本 clone できない
だけで開発環境ごと止めても、他のリポジトリでの作業まで巻き添えになるためです。

| 起きること | 挙動 |
|---|---|
| clone の失敗 | 警告を出して次のリポジトリへ進む。`devbase up` は成功で終わる (終了コード 0) |
| `devbase up` の出力 | `/work` に無いリポジトリを clone URL 付きで一覧表示する。揃っていれば何も出さない |
| multi-root ワークスペース | clone できたリポジトリだけが `folders` に載る。開けないフォルダは並ばない |
| primary が clone できなかった | 警告を出し、ログイン直後のカレントは `/work` になる |

clone は**コンテナ起動のたびに試行される**ので、後から権限が付与されれば次の `devbase up` で
取り込まれます。`project.yml` を直す必要はありません。

権限が無い場合も存在しない場合も、GitHub は private リポジトリに対して同じ
`Repository not found` (404) を返します。警告からは区別できないため、リポジトリ名の
打ち間違いも同じ見え方になります。詳細は `devbase project logs <name>` で確認してください。

## `env` との使い分け

| 書く場所 | 内容 | 例 |
Expand Down
Loading
Loading