caterium-app/ops/timeweb/caterium-production-sync.sh
2026-09-10 18:50:50 +03:00

111 lines
3.0 KiB
Bash

#!/bin/sh
set -eu
REPO_URL="${CATERIUM_REPO_URL:-git@github.com:pavlov346346-source/caterium-app.git}"
BRANCH="${CATERIUM_BRANCH:-production}"
STATE_DIR="${CATERIUM_STATE_DIR:-$HOME/.caterium-deploy}"
REPO_DIR="${CATERIUM_REPO_DIR:-$STATE_DIR/repo}"
BACKUP_DIR="${CATERIUM_BACKUP_DIR:-$STATE_DIR/backups}"
LOCK_DIR="$STATE_DIR/lock"
log() {
printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
fail() {
log "ERROR: $*" >&2
exit 1
}
find_web_root() {
if [ -n "${CATERIUM_WEB_ROOT:-}" ]; then
printf '%s\n' "$CATERIUM_WEB_ROOT"
return 0
fi
for candidate in \
"$HOME/caterium.ru/public_html" \
"$HOME/app.caterium.ru/public_html"
do
if [ -d "$candidate" ] && [ -f "$candidate/index.html" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
command -v git >/dev/null 2>&1 || fail "git is not available"
command -v rsync >/dev/null 2>&1 || fail "rsync is not available"
command -v tar >/dev/null 2>&1 || fail "tar is not available"
mkdir -p "$STATE_DIR" "$BACKUP_DIR"
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
if [ -f "$LOCK_DIR/pid" ]; then
old_pid=$(cat "$LOCK_DIR/pid" 2>/dev/null || true)
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
log "Another deployment is running; skip"
exit 0
fi
fi
rm -rf "$LOCK_DIR"
mkdir "$LOCK_DIR" 2>/dev/null || {
log "Could not acquire deployment lock; skip"
exit 0
}
fi
printf '%s\n' "$$" > "$LOCK_DIR/pid"
cleanup_lock() {
rm -rf "$LOCK_DIR"
}
trap cleanup_lock 0 HUP INT TERM
WEB_ROOT=$(find_web_root) || fail "web root not found; set CATERIUM_WEB_ROOT"
[ -d "$WEB_ROOT" ] || fail "web root does not exist: $WEB_ROOT"
if [ ! -d "$REPO_DIR/.git" ]; then
log "Initial clone of $BRANCH"
rm -rf "$REPO_DIR"
git clone --quiet --single-branch --branch "$BRANCH" "$REPO_URL" "$REPO_DIR" \
|| fail "initial Git clone failed; verify GitHub SSH key access"
fi
cd "$REPO_DIR"
log "Fetching $BRANCH"
git fetch --quiet origin "$BRANCH" || fail "git fetch failed"
NEW_SHA=$(git rev-parse FETCH_HEAD)
OLD_SHA=$(cat "$WEB_ROOT/.caterium-release" 2>/dev/null || true)
if [ "$NEW_SHA" = "$OLD_SHA" ]; then
log "Already current: $NEW_SHA"
exit 0
fi
git reset --quiet --hard "$NEW_SHA" || fail "could not switch deploy checkout"
[ -s "$REPO_DIR/public/index.html" ] || fail "release validation failed: public/index.html is missing or empty"
STAMP=$(date '+%Y%m%d-%H%M%S')
BACKUP_FILE="$BACKUP_DIR/${STAMP}-${OLD_SHA:-pre-marker}.tgz"
log "Backing up current site"
tar -czf "$BACKUP_FILE" -C "$WEB_ROOT" . || fail "backup failed; live files left unchanged"
log "Deploying $NEW_SHA to $WEB_ROOT"
rsync -a --delete-delay \
--exclude '.well-known/' \
--exclude '.caterium-release' \
"$REPO_DIR/public/" "$WEB_ROOT/" \
|| fail "rsync failed"
printf '%s\n' "$NEW_SHA" > "$WEB_ROOT/.caterium-release"
# Keep only the four newest rollback archives.
set +e
ls -1t "$BACKUP_DIR"/*.tgz 2>/dev/null | awk 'NR > 4' | while IFS= read -r old_backup; do
rm -f "$old_backup"
done
set -e
log "Deployment complete: $NEW_SHA"