178 lines
5.1 KiB
Bash
Executable File
178 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Static Site Deploy - FTP upload helper script
|
|
# Usage: deploy.sh <source-dir> <project-name> [--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 <source-dir> <project-name> [--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"
|