diff --git a/deploy.prod.sh b/deploy.prod.sh new file mode 100755 index 0000000..d721b2d --- /dev/null +++ b/deploy.prod.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# Pure production deploy: +# - Always uses remote branch as source of truth +# - Discards local changes on server +# - Non-interactive, fail-fast + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$PROJECT_ROOT" + +BRANCH="${1:-main}" +REMOTE="${2:-origin}" + +echo "==> [prod] Project: $PROJECT_ROOT" +echo "==> [prod] Remote: $REMOTE" +echo "==> [prod] Branch: $BRANCH" + +if [[ ! -d ".git" ]]; then + echo "Error: current directory is not a git repository." + exit 1 +fi + +if ! git remote get-url "$REMOTE" >/dev/null 2>&1; then + echo "Error: git remote '$REMOTE' does not exist." + exit 1 +fi + +echo "==> [prod] Fetching latest code" +git fetch "$REMOTE" --prune + +if ! git show-ref --verify --quiet "refs/remotes/$REMOTE/$BRANCH"; then + echo "Error: remote branch '$REMOTE/$BRANCH' not found." + exit 1 +fi + +PREV_COMMIT="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)" +echo "==> [prod] Current commit: $PREV_COMMIT" + +echo "==> [prod] Force sync to $REMOTE/$BRANCH (discard local changes)" +git checkout -B "$BRANCH" "$REMOTE/$BRANCH" +git reset --hard "$REMOTE/$BRANCH" +git clean -fd + +NEW_COMMIT="$(git rev-parse --short HEAD)" +echo "==> [prod] New commit: $NEW_COMMIT" + +if [[ ! -f ".env" && -f ".env.example" ]]; then + cp ".env.example" ".env" + echo "==> [prod] Created .env from .env.example" +fi + +if docker compose version >/dev/null 2>&1; then + COMPOSE_CMD="docker compose" +elif command -v docker-compose >/dev/null 2>&1; then + COMPOSE_CMD="docker-compose" +else + COMPOSE_CMD="" +fi + +if [[ -n "$COMPOSE_CMD" ]]; then + echo "==> [prod] Restarting services with $COMPOSE_CMD" + $COMPOSE_CMD down + $COMPOSE_CMD up -d --build --remove-orphans + echo "==> [prod] Deploy success: http://localhost:18000" + exit 0 +fi + +echo "==> [prod] docker compose not found, fallback to ./start.sh" +chmod +x ./start.sh +./start.sh