diff --git a/deploy.sh b/deploy.sh index d0b95a1..6a4d2e9 100755 --- a/deploy.sh +++ b/deploy.sh @@ -42,7 +42,26 @@ fi # ─── ۱. کدِ تازه ──────────────────────────────────────────────────────────── if [ "${SKIP_PULL:-0}" != "1" ]; then step "گرفتنِ کدِ تازه" + # امضای خودِ این فایل قبل از pull. توضیحش پایین‌تر. + SELF_BEFORE="$(cksum "$0" 2>/dev/null || true)" git pull --ff-only || fail "git pull نشد. اگر تغییرِ محلی دارید اول تعیین تکلیفش کنید." + + # اگر همین اسکریپت در pull عوض شد، نسخه‌ی تازه از اول اجرا می‌شود. + # + # چرا لازم است: bash اسکریپت را یک‌جا نمی‌خواند، حین اجرا از روی دیسک ادامه + # می‌دهد. پس وقتی pull همین فایل را زیر پای خودش عوض می‌کند، ادامه‌ی اجرا + # مخلوطی از نسخه‌ی قدیم و جدید می‌شود. یک بار همین اتفاق افتاد: نسخه‌ی قدیمی + # که هنوز در حال اجرا بود سرویسِ تیمِ دیگری را ری‌استارت کرد، در حالی که + # نسخه‌ی اصلاح‌شده همان لحظه روی دیسک نشسته بود. + # + # DEPLOY_REEXEC جلوی حلقه‌ی بی‌پایان را می‌گیرد: نسخه‌ی تازه دیگر خودش را + # صدا نمی‌زند چون بعد از pullِ دوم دیگر چیزی عوض نمی‌شود. + if [ "${DEPLOY_REEXEC:-0}" != "1" ] \ + && [ -n "$SELF_BEFORE" ] \ + && [ "$SELF_BEFORE" != "$(cksum "$0" 2>/dev/null || true)" ]; then + printf ' این اسکریپت خودش به‌روز شد؛ نسخه‌ی تازه از اول اجرا می‌شود.\n' + DEPLOY_REEXEC=1 SKIP_PULL=1 exec "$0" "$@" + fi else step "گرفتنِ کد رد شد (SKIP_PULL=1)" fi @@ -175,7 +194,12 @@ if [ -n "$SERVICE" ]; then BEFORE="$(systemctl show "$SERVICE" -p ActiveEnterTimestamp --value 2>/dev/null || true)" if sudo systemctl restart "$SERVICE"; then AFTER="$(systemctl show "$SERVICE" -p ActiveEnterTimestamp --value 2>/dev/null || true)" - if [ -n "$BEFORE" ] && [ "$BEFORE" = "$AFTER" ]; then + if [ -z "$BEFORE" ] || [ -z "$AFTER" ]; then + # نتوانستیم ثابت کنیم ری‌استارت شده. «نمی‌دانم» را موفقیت حساب نمی‌کنیم — + # همین اشتباه بود که دو روز پنهان ماند. + warn "زمانِ بالا آمدنِ $SERVICE خوانده نشد، پس ری‌استارت تأیید نشد. + خودتان بررسی کنید: systemctl status $SERVICE" + elif [ "$BEFORE" = "$AFTER" ]; then warn "دستورِ ری‌استارت خطا نداد ولی سرویس بالا نیامد (هنوز از $BEFORE در حال اجراست). یعنی کدِ جدید بار نشده. لاگ: sudo journalctl -u $SERVICE -n 50 --no-pager" else