diff --git a/.env.production b/.env.production index 232afe0..1be7b6a 100644 --- a/.env.production +++ b/.env.production @@ -5,4 +5,4 @@ # ۲) بدونِ build: روی سرور، در dist/config.js مقدارِ apiBaseUrl را بنویسید. # آن فایل در زمانِ اجرا خوانده می‌شود و بر این مقدار مقدم است. # اگر nginxِ دامنه‌ی فرانت /api را به بک‌اند پراکسی کند، مقدارِ /api کافی است. -VITE_API_BASE_URL=https://api.math.tadrisino2.ir/api +VITE_API_BASE_URL=https://mathapi.tadrisino2.ir/api diff --git a/.gitignore b/.gitignore index 805d9ee..1906164 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ dist .env .env.local .env.*.local +dist.next +dist.prev +.deploy-backups diff --git a/README.md b/README.md index 2d890b1..74ac4f4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ npm run dev # http://localhost:5173 بدونِ بک‌اندِ محلی، یک فایلِ `.env.development.local` بسازید: ```bash -VITE_DEV_PROXY_TARGET=https://api.math.tadrisino2.ir +VITE_DEV_PROXY_TARGET=https://mathapi.tadrisino2.ir ``` ⚠️ آن‌وقت هر کاری در اپ بکنید روی دیتابیسِ واقعی نوشته می‌شود. @@ -47,11 +47,16 @@ VITE_DEV_PROXY_TARGET=https://api.math.tadrisino2.ir ## دیپلوی +روی سرور (`~/mathapp_frontend_new`، که nginxِ `math.tadrisino2.ir` از `dist/`ش سرو می‌کند): + ```bash -npm ci && npm run build +./deploy.sh # fetch، npm ci، type-check، build در dist.next و جابه‌جاییِ بی‌وقفه ``` -محتوای `dist/` را سرو کنید. اپ مسیرِ جدا (route) ندارد و همه‌چیز از `/` بار می‌شود؛ +buildِ قبلی در `dist.prev` می‌ماند (برگشت: `rm -rf dist && mv dist.prev dist`)، و +`dist/config.js`ِ ویرایش‌شده روی سرور به buildِ تازه منتقل می‌شود. + +جای دیگر: `npm ci && npm run build` و سرو کردنِ `dist/`. اپ مسیرِ جدا (route) ندارد و همه‌چیز از `/` بار می‌شود؛ فقط `index.html` و `config.js` نباید طولانی کش شوند (باقیِ فایل‌ها نامِ hashدار دارند). درگاهِ پرداخت کاربر را به `/?orderId=…&status=…` برمی‌گرداند و لینکِ دعوت `/?ref=CODE` است؛ هر دو را خودِ اپ می‌خواند. diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..5b29959 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# انتشارِ فرانت روی سرور: گرفتنِ کدِ تازه، build، و جابه‌جاییِ بی‌وقفه‌ی dist. +# +# ./deploy.sh # شاخه‌ی main +# ./deploy.sh +# +# build در dist.next ساخته می‌شود و فقط اگر کامل موفق شد جای dist را می‌گیرد؛ +# پس سایت حتی چند ثانیه هم بی‌فایل نمی‌ماند. buildِ قبلی در dist.prev می‌ماند: +# برگشت: rm -rf dist && mv dist.prev dist +# +# dist/config.js (آدرسِ API در زمانِ اجرا) اگر روی سرور دستی ویرایش شده باشد، +# به buildِ تازه منتقل می‌شود تا با هر انتشار از دست نرود. +set -euo pipefail +cd "$(dirname "$0")" + +BRANCH="${1:-main}" +step() { printf '\n\033[0;32m▸ %s\033[0m\n' "$1"; } +fail() { printf '\033[0;31m✖ %s\033[0m\n' "$1" >&2; exit 1; } + +step "گرفتنِ کدِ تازه ($BRANCH)" +git fetch origin "$BRANCH" || fail "به gitea وصل نشد." +if [ -n "$(git status --porcelain --untracked-files=no)" ]; then + mkdir -p .deploy-backups + PATCH=".deploy-backups/local-changes-$(date +%Y%m%d-%H%M%S).patch" + git diff > "$PATCH" + printf ' تغییرِ دستی روی سرور بود؛ در %s ذخیره شد.\n' "$PATCH" +fi +git reset --hard "origin/$BRANCH" +git log --oneline -1 + +step "نصبِ وابستگی‌ها" +npm ci --no-audit --no-fund + +step "type-check و build" +rm -rf dist.next +npx tsc --noEmit || fail "type-check شکست خورد؛ سایت دست نخورد." +npx vite build --outDir dist.next --emptyOutDir || fail "build شکست خورد؛ سایت دست نخورد." + +if [ -f dist/config.js ] && ! cmp -s dist/config.js public/config.js; then + cp dist/config.js dist.next/config.js + printf ' config.jsِ ویرایش‌شده‌ی سرور نگه داشته شد.\n' +fi + +step "جابه‌جایی" +rm -rf dist.prev +[ -d dist ] && mv dist dist.prev +mv dist.next dist +API="$(grep -o 'https\?://[a-zA-Z0-9.-]*/api' dist/assets/*.js | head -1 | cut -d: -f2-)" +printf ' منتشر شد. آدرسِ API در build: %s\n' "${API:-(هم‌دامنه /api یا config.js)}" +printf ' کشِ آروان را برای index.html و config.js پاک کنید اگر تغییری دیده نشد.\n'