nomadweb/scripts/deploy_dating_fix.py
eric e23cf9a03c Close Explore/Grow loops: visa wizard, jobs, lessons, gigs notify, map.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 09:26:56 -05:00

137 lines
4.3 KiB
Python

"""Upload dating hotfix deps and rebuild web."""
from __future__ import annotations
import sys
from pathlib import Path
import paramiko
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
HOST = "107.173.30.245"
USER = "root"
PASS = "Xiao4669805"
REMOTE = "/opt/nomadweb"
ROOT = Path(__file__).resolve().parents[1]
FILES = [
"frontend/src/lib/communityDraft.ts",
"frontend/src/lib/meetupLinks.ts",
"frontend/src/lib/localDraft.ts",
"frontend/src/lib/savedGigs.ts",
"frontend/src/lib/savedJobs.ts",
"frontend/src/lib/meetupIcs.ts",
"frontend/src/lib/aiHistory.ts",
"frontend/src/lib/compareHistory.ts",
"frontend/src/lib/nextStopPrefs.ts",
"frontend/src/lib/recentDestinations.ts",
"frontend/src/lib/watchLater.ts",
"frontend/src/lib/toolCopy.ts",
"frontend/src/lib/coworking.ts",
"frontend/src/lib/authNext.ts",
"frontend/src/lib/rings.ts",
"frontend/src/lib/toast.tsx",
"frontend/src/lib/api.ts",
"frontend/src/lib/types.ts",
"frontend/src/lib/i18n/dictionaries.ts",
"frontend/src/components/ToolCityExits.tsx",
"frontend/src/components/RecentlyViewed.tsx",
"frontend/src/components/NomadDigest.tsx",
"frontend/src/components/DatingClient.tsx",
"frontend/src/components/DatingLikesClient.tsx",
"frontend/src/components/ChatClient.tsx",
"frontend/src/components/CommunityNewClient.tsx",
"frontend/src/components/DiscussionDetailClient.tsx",
"frontend/src/components/GigsClient.tsx",
"frontend/src/components/MeetupsClient.tsx",
"frontend/src/components/MeetupsHostClient.tsx",
"frontend/src/components/CommunityHubClient.tsx",
"frontend/src/components/MemberProfileClient.tsx",
"frontend/src/components/NotificationsClient.tsx",
"frontend/src/components/PricingClient.tsx",
"frontend/src/components/GlobalSearch.tsx",
"frontend/src/components/SiteShell.tsx",
"frontend/src/components/Navbar.tsx",
"frontend/src/components/Footer.tsx",
"frontend/src/app/globals.css",
"frontend/src/app/changelog/page.tsx",
]
REBUILD = r"""
set -euo pipefail
exec 9>/var/lock/nomadro-deploy.lock
if ! flock -n 9; then echo LOCK_BUSY; exit 75; fi
export NEXT_TELEMETRY_DISABLED=1
export NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1
export NEXT_PUBLIC_SITE_URL=https://nomadweb.nomadro.com
export NODE_ENV=production
cd /opt/nomadweb/frontend
echo BUILD_START
npm run build
mkdir -p .next/standalone/.next
rm -rf .next/standalone/public .next/standalone/.next/static
cp -a public .next/standalone/public
cp -a .next/static .next/standalone/.next/static
rm -rf .next/standalone/content
mkdir -p .next/standalone/content
cp -a content .next/standalone/content
systemctl restart nomadro-web
for i in $(seq 1 30); do
web=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3055/ || true)
echo "try=$i web=$web"
[ "$web" = "200" ] && exit 0
sleep 1
done
exit 1
"""
def ensure_dir(sftp: paramiko.SFTPClient, path: str) -> None:
parts = path.strip("/").split("/")
cur = ""
for p in parts:
cur += "/" + p
try:
sftp.stat(cur)
except FileNotFoundError:
try:
sftp.mkdir(cur)
except OSError:
pass
def main() -> int:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, username=USER, password=PASS, timeout=30)
sftp = client.open_sftp()
for i, rel in enumerate(FILES, 1):
local = ROOT / rel
if not local.exists():
print(f"[{i}/{len(FILES)}] SKIP {rel}", flush=True)
continue
remote = f"{REMOTE}/{rel}"
print(f"[{i}/{len(FILES)}] UPLOAD {rel}", flush=True)
ensure_dir(sftp, str(Path(remote).parent).replace("\\", "/"))
sftp.put(str(local), remote)
sftp.close()
print("BUILD...", flush=True)
_, stdout, stderr = client.exec_command(REBUILD, timeout=900)
while True:
line = stdout.readline()
if not line:
break
print(line.rstrip(), flush=True)
err = stderr.read().decode("utf-8", errors="replace")
if err.strip():
print("LOG:", err[-4000:], flush=True)
code = stdout.channel.recv_exit_status()
client.close()
print("exit", code, flush=True)
return code
if __name__ == "__main__":
raise SystemExit(main())