107 lines
1.9 KiB
Bash
107 lines
1.9 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
INTERVAL_SECONDS="${INTERVAL_SECONDS:-30}"
|
|
ONCE="${1:-}"
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
STATE_DIR="$REPO_ROOT/.sync-state"
|
|
ERROR_FILE="$STATE_DIR/sync-error-vps.md"
|
|
|
|
ALLOWED_PATHS=(
|
|
"AGENT_BOARD.md"
|
|
"README.md"
|
|
".cursor/rules"
|
|
"handoff"
|
|
"evidence"
|
|
"rollback"
|
|
"tasks"
|
|
"sync"
|
|
".gitignore"
|
|
)
|
|
|
|
ensure_state_dir() {
|
|
mkdir -p "$STATE_DIR"
|
|
}
|
|
|
|
write_sync_error() {
|
|
ensure_state_dir
|
|
local message="$1"
|
|
local timestamp
|
|
timestamp="$(date '+%Y-%m-%d %H:%M:%S %z')"
|
|
cat > "$ERROR_FILE" <<EOF
|
|
# VPS Sync Error
|
|
|
|
- Time: $timestamp
|
|
- Repository: $REPO_ROOT
|
|
- Message: $message
|
|
|
|
Manual action required. Do not continue automatic sync until the repository is clean.
|
|
EOF
|
|
}
|
|
|
|
has_allowed_changes() {
|
|
local line path allowed
|
|
while IFS= read -r line; do
|
|
[[ -z "$line" ]] && continue
|
|
path="${line:3}"
|
|
for allowed in "${ALLOWED_PATHS[@]}"; do
|
|
if [[ "$path" == "$allowed" || "$path" == "$allowed/"* ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
done < <(git status --porcelain)
|
|
return 1
|
|
}
|
|
|
|
has_conflicts() {
|
|
[[ -n "$(git diff --name-only --diff-filter=U)" ]]
|
|
}
|
|
|
|
sync_once() {
|
|
cd "$REPO_ROOT"
|
|
ensure_state_dir
|
|
|
|
git pull --rebase --autostash
|
|
|
|
if has_conflicts; then
|
|
return 20
|
|
fi
|
|
|
|
if ! has_allowed_changes; then
|
|
return 0
|
|
fi
|
|
|
|
local path
|
|
for path in "${ALLOWED_PATHS[@]}"; do
|
|
if [[ -e "$path" ]]; then
|
|
git add -- "$path"
|
|
fi
|
|
done
|
|
|
|
if [[ -z "$(git diff --cached --name-only)" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
git commit -m "Sync agent state from VPS at $(date '+%Y-%m-%d %H:%M:%S')"
|
|
git push
|
|
}
|
|
|
|
while true; do
|
|
if sync_once; then
|
|
rm -f "$ERROR_FILE"
|
|
else
|
|
exit_code="$?"
|
|
write_sync_error "sync failed with exit code $exit_code"
|
|
echo "sync failed with exit code $exit_code" >&2
|
|
exit "$exit_code"
|
|
fi
|
|
|
|
if [[ "$ONCE" == "--once" ]]; then
|
|
break
|
|
fi
|
|
|
|
sleep "$INTERVAL_SECONDS"
|
|
done
|