Skip to content

Commit ceea9de

Browse files
tridgeclaude
andcommitted
scripts/update_server.sh: deploy via git-tracked staging tree
The previous rsync swept the whole working tree, relying on an allow-list of excludes to keep secrets out. Codex review flagged it: generic scratch (pass.dat, x.dat, way.txt), local-only scripts, *.orig from a recent merge etc. weren't covered, so a fresh untracked file in the local cwd would silently ship. Switch to deny-by-default. Build a temporary staging tree from 'git ls-files --recurse-submodules' (so modules/mavlink/* lands along with the top-level files), filter out paths that resolve to a directory (uninitialised nested submodules — cp without -r would otherwise fail), then rsync that staging tree to the remote. Local dry-run confirms pass.dat / x.dat / way.txt / .webadmin_secret / fullchain.pem / keys.tdb / AGENTS.md / *.orig / *.rej / etc. all stay behind, while the 477 tracked files (including the mavlink submodule and .git/) ship correctly. Uncommitted edits to TRACKED files still go through; only NEW files now have to be git add'd before they're deployable, which is reasonable hygiene. RSYNC_EXCLUDES is unchanged — the staging side is already clean, so the excludes' job is now just protecting server-side state (keys.tdb, *.pem, logs/, .webadmin_secret) from --delete. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f8a49b8 commit ceea9de

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

scripts/update_server.sh

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,46 @@ RSYNC_EXCLUDES=(
6060
--exclude='.webadmin_secret'
6161
)
6262

63+
if ! command -v git >/dev/null 2>&1; then
64+
echo "git not found — needed to enumerate the deploy file list" >&2
65+
exit 1
66+
fi
67+
68+
# Build a clean staging tree of *only* git-tracked files (deny-by-
69+
# default). Anything in the local working tree that isn't tracked —
70+
# pass.dat, x.dat, *.orig from a recent merge, .webadmin_secret,
71+
# fullchain.pem, scratch notes, an unrelated test/ dir — physically
72+
# can't reach the deploy. Uncommitted edits to TRACKED files do go
73+
# through (cp from the working tree), so the existing
74+
# "edit-then-deploy" workflow keeps working; new files have to be
75+
# git add'd before they ship. The .git directory is also copied so
76+
# the deployed build's `git rev-parse --short HEAD` succeeds.
77+
STAGE="$(mktemp -d)"
78+
trap 'rm -rf "$STAGE"' EXIT
79+
80+
(
81+
cd "$REPO_ROOT"
82+
# --recurse-submodules so modules/mavlink/* ends up in the list
83+
# rather than just the submodule pointer. Filter out any path
84+
# that resolves to a directory — those are uninitialised nested
85+
# submodules (e.g. modules/mavlink/.../node_modules/...) that we
86+
# don't have content for locally and the build doesn't need.
87+
git ls-files -z --recurse-submodules | \
88+
while IFS= read -r -d '' f; do
89+
[ -f "$f" ] && printf '%s\0' "$f"
90+
done | \
91+
xargs -0 cp --parents -t "$STAGE"
92+
cp -a .git "$STAGE/.git"
93+
)
94+
6395
for host in "$@"; do
6496
echo
6597
echo "=== $host: syncing source ==="
98+
# RSYNC_EXCLUDES still applies — the staging tree itself is
99+
# already clean, but the excludes are what stops --delete from
100+
# clobbering the server's own state (keys.tdb, *.pem, logs/, ...).
66101
rsync -az --delete "${RSYNC_EXCLUDES[@]}" \
67-
"$REPO_ROOT/" "$host:SupportProxy/"
102+
"$STAGE/" "$host:SupportProxy/"
68103

69104
echo "=== $host: rebuild + restart ==="
70105
ssh "$host" bash -se <<'SSH_EOF'

0 commit comments

Comments
 (0)