#!/usr/bin/env bash set -euo pipefail # Static Site Deploy - FTP upload helper script # Usage: deploy.sh [--config path] [--dry-run] # ─── Argument Parsing ─────────────────────────────────────────────── SOURCE_DIR="" PROJECT_NAME="" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="${SCRIPT_DIR}/static-site-deploy.yml" DRY_RUN=false while [[ $# -gt 0 ]]; do case "$1" in --config) CONFIG_FILE="$2" shift 2 ;; --dry-run) DRY_RUN=true shift ;; *) if [[ -z "$SOURCE_DIR" ]]; then SOURCE_DIR="$1" elif [[ -z "$PROJECT_NAME" ]]; then PROJECT_NAME="$1" else echo "Error: unexpected argument '$1'" >&2 exit 1 fi shift ;; esac done if [[ -z "$SOURCE_DIR" || -z "$PROJECT_NAME" ]]; then echo "Usage: deploy.sh [--config path] [--dry-run]" >&2 exit 1 fi if [[ ! -d "$SOURCE_DIR" ]]; then echo "Error: source directory '$SOURCE_DIR' does not exist" >&2 exit 1 fi # Read bot_id from environment variable BOT_ID="${ASSISTANT_ID:-}" if [[ -z "$BOT_ID" ]]; then echo "Error: ASSISTANT_ID environment variable is not set" >&2 exit 1 fi # ─── Config Parsing ───────────────────────────────────────────────── if [[ ! -f "$CONFIG_FILE" ]]; then echo "Error: config file '$CONFIG_FILE' not found" >&2 exit 1 fi # Simple YAML parser (no external dependencies) parse_yaml() { local key="$1" grep "^${key}:" "$CONFIG_FILE" | sed "s/^${key}:[[:space:]]*//" | sed 's/[[:space:]]*#.*//' | sed 's/[[:space:]]*$//' | sed 's/^["'\'']\(.*\)["'\'']$/\1/' } HOST=$(parse_yaml "host") FTP_USER=$(parse_yaml "ftp_user") FTP_PASS=$(parse_yaml "ftp_pass") FTP_PORT=$(parse_yaml "ftp_port") USE_FTPS=$(parse_yaml "use_ftps") WEB_ROOT=$(parse_yaml "web_root") DOMAIN=$(parse_yaml "domain") # Defaults FTP_PORT="${FTP_PORT:-21}" USE_FTPS="${USE_FTPS:-true}" # Validate required fields for field in HOST FTP_USER FTP_PASS WEB_ROOT DOMAIN; do if [[ -z "${!field}" ]]; then echo "Error: missing required config field: $(echo "$field" | tr '[:upper:]' '[:lower:]')" >&2 exit 1 fi done REMOTE_PATH="${WEB_ROOT}/${BOT_ID}/${PROJECT_NAME}" SITE_URL="https://${DOMAIN}/${BOT_ID}/${PROJECT_NAME}/" # ─── Summary ──────────────────────────────────────────────────────── FILE_COUNT=$(find "$SOURCE_DIR" -type f | wc -l | tr -d ' ') TOTAL_SIZE=$(du -sh "$SOURCE_DIR" 2>/dev/null | cut -f1) echo "=== Static Site Deploy ===" echo "Bot ID: $BOT_ID" echo "Source: $SOURCE_DIR ($FILE_COUNT files, $TOTAL_SIZE)" echo "Project: $PROJECT_NAME" echo "Remote: ftp://${FTP_USER}@${HOST}:${FTP_PORT}${REMOTE_PATH}/" echo "URL: $SITE_URL" echo "FTPS: $USE_FTPS" echo "" if [[ "$DRY_RUN" == "true" ]]; then echo "[DRY RUN] Files that would be uploaded:" find "$SOURCE_DIR" -type f | while read -r file; do rel_path="${file#"$SOURCE_DIR"}" rel_path="${rel_path#/}" echo " $rel_path" done echo "" echo "[DRY RUN] No files were uploaded." exit 0 fi # ─── Upload ───────────────────────────────────────────────────────── echo "Uploading with curl..." curl_ssl_flag="" if [[ "$USE_FTPS" == "true" ]]; then curl_ssl_flag="--ssl-reqd" fi ftp_base="ftp://${FTP_USER}:${FTP_PASS}@${HOST}:${FTP_PORT}" # Upload files one by one uploaded=0 failed=0 find "$SOURCE_DIR" -type f | while read -r file; do rel_path="${file#"$SOURCE_DIR"}" rel_path="${rel_path#/}" remote_url="${ftp_base}${REMOTE_PATH}/${rel_path}" if curl -s -T "$file" --ftp-create-dirs $curl_ssl_flag "$remote_url"; then echo " OK: $rel_path" uploaded=$((uploaded + 1)) else echo " FAIL: $rel_path" >&2 failed=$((failed + 1)) fi done if [[ $failed -gt 0 ]]; then echo "Warning: $failed file(s) failed to upload" >&2 fi echo "" # ─── Verify ───────────────────────────────────────────────────────── echo "=== Verification ===" # FTP verification echo -n "FTP check... " ftp_list_url="ftp://${FTP_USER}:${FTP_PASS}@${HOST}:${FTP_PORT}${REMOTE_PATH}/" if curl -s --list-only "$ftp_list_url" --connect-timeout 5 >/dev/null 2>&1; then echo "OK (files present on server)" else echo "WARN (could not list remote directory)" fi # HTTP verification echo -n "HTTP check... " http_code=$(curl -sL -o /dev/null -w '%{http_code}' "$SITE_URL" --connect-timeout 10 2>/dev/null || echo "000") if [[ "$http_code" == "200" ]]; then echo "OK (HTTP $http_code)" else echo "WARN (HTTP $http_code - check Nginx config if not 200)" fi echo "" echo "=== Deploy Complete ===" echo "URL: $SITE_URL"