From fb1a1d2b100d549bd77a760445b7727184f473bc Mon Sep 17 00:00:00 2001 From: Kai Date: Sun, 30 Aug 2026 21:48:25 -0700 Subject: [PATCH] feat(deploy): sync a scenario's backend/ into the live workspace root deploy-scenario.sh now single-sources the application backend: it copies the git-tracked files under [scenario].backend into the workspace root (where .pi/ sits beside them), preserving modes and skipping caches/venvs. It overwrites but never prunes, and never restarts -- it prints a restart reminder when backend files change. README's Application code section updated to match. --- README.md | 11 ++++++----- scripts/deploy-scenario.sh | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 719eade..2d3cc24 100644 --- a/README.md +++ b/README.md @@ -65,11 +65,12 @@ A scenario that runs its own service keeps that service's source under units and config templates. It is the single source of truth; the live checkout at the scenario's `workspace` path is a runtime copy. -`deploy-scenario.sh` installs only `workspace/` (the `.pi` config) and renders the -launch contract; it does not touch `backend/`, build a venv or restart a service. -Rolling application code out to the live checkout and restarting the unit stays an -operator step, deliberately: restarting decides when to interrupt a live -conversation. +`deploy-scenario.sh` installs `workspace/` (the `.pi` config), vendors shared +extensions, renders the launch contract, and syncs `backend/` into the workspace +root — copying only git-tracked files (build caches and virtualenvs never leak) +and preserving file modes. It never prunes files the repo no longer tracks, never +builds a venv, and never restarts the service: it prints a reminder instead, since +restarting decides when to interrupt a live conversation. ## Start here diff --git a/scripts/deploy-scenario.sh b/scripts/deploy-scenario.sh index 99fcd17..9ffeed4 100755 --- a/scripts/deploy-scenario.sh +++ b/scripts/deploy-scenario.sh @@ -108,6 +108,44 @@ if [ "$APPLY" -eq 1 ] && [ -d "$DIR/workspace/bin" ]; then done < <(cd "$DIR/workspace" && find bin -type f -printf '%P\n' 2>/dev/null | sed 's|^|bin/|') fi +# --------------------------------------------------------------------------- +# 1c. Application backend +# +# A scenario that owns a service keeps its source under backend/ (set by +# [scenario].backend). It installs into the workspace root, where .pi/ sits +# beside it, so the repository is the single source of truth. Only git-tracked +# files are copied -- build caches and virtualenvs never leak -- and file modes +# (notably the execute bit) are preserved. This overwrites but never prunes: +# removing a file the repo no longer tracks from a live tree is too blunt to do +# unattended. Like every other step it never restarts the service; it prints a +# reminder, because restarting decides when to interrupt a live conversation. +# --------------------------------------------------------------------------- +BACKEND="$(toml_get "$PROFILE" scenario backend)" +if [ -n "$BACKEND" ]; then + case "$BACKEND" in /*) ;; *) BACKEND="$REPO_ROOT/$BACKEND" ;; esac + [ -d "$BACKEND" ] || die "profile sets [scenario].backend to '$BACKEND', which does not exist" + BACKEND_CHANGES=0 + while IFS= read -r rel; do + src="$BACKEND/$rel" + dst="$WORKSPACE/$rel" + if [ -f "$dst" ] && cmp -s "$src" "$dst"; then + continue + fi + BACKEND_CHANGES=$((BACKEND_CHANGES + 1)) + if [ -f "$dst" ]; then info " update $rel"; else info " create $rel"; fi + if [ "$APPLY" -eq 1 ]; then + install -d -m 755 "$(dirname "$dst")" + install -m "$(stat -c '%a' "$src")" "$src" "$dst" + fi + done < <(git -C "$BACKEND" ls-files) + CHANGES=$((CHANGES + BACKEND_CHANGES)) + if [ "$BACKEND_CHANGES" -gt 0 ]; then + warn "backend: $BACKEND_CHANGES file(s) changed; restart $(toml_get "$PROFILE" scenario service) to apply" + else + ok "backend already matches" + fi +fi + [ "$CHANGES" -eq 0 ] && ok "workspace already matches" # ---------------------------------------------------------------------------