finalizing source rebuild process, docs in progress

This commit is contained in:
Deckard
2025-10-19 01:14:54 -04:00
parent 859a214e12
commit 3426acae6d
12 changed files with 816 additions and 162 deletions

220
deploy.sh Executable file
View File

@@ -0,0 +1,220 @@
#!/bin/bash
#
# High-level orchestrator for module-aware deployments.
# 1. Ensures AzerothCore source repo is present
# 2. Runs ac-modules to sync/clean module checkout and configs
# 3. Rebuilds source images when C++ modules demand it
# 4. Stages target compose profile and optionally tails worldserver logs
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="$ROOT_DIR/compose.yml"
ENV_PATH="$ROOT_DIR/.env"
TARGET_PROFILE=""
WATCH_LOGS=1
KEEP_RUNNING=0
SKIP_REBUILD=0
BLUE='\033[0;34m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info(){ echo -e "${BLUE} $*${NC}"; }
ok(){ echo -e "${GREEN}$*${NC}"; }
warn(){ echo -e "${YELLOW}⚠️ $*${NC}"; }
err(){ echo -e "${RED}$*${NC}"; }
usage(){
cat <<EOF
Usage: $(basename "$0") [options]
Options:
--profile {standard|playerbots|modules} Force target profile (default: auto-detect)
--no-watch Do not tail worldserver logs after staging
--keep-running Do not pre-stop runtime stack before rebuild
--skip-rebuild Skip source rebuild even if modules require it
-h, --help Show this help
This command automates the module workflow (sync modules, rebuild source if needed,
stage the correct compose profile, and optionally watch worldserver logs).
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--profile) TARGET_PROFILE="$2"; shift 2;;
--no-watch) WATCH_LOGS=0; shift;;
--keep-running) KEEP_RUNNING=1; shift;;
--skip-rebuild) SKIP_REBUILD=1; shift;;
-h|--help) usage; exit 0;;
*) err "Unknown option: $1"; usage; exit 1;;
esac
done
require_cmd(){
command -v "$1" >/dev/null 2>&1 || { err "Missing required command: $1"; exit 1; }
}
require_cmd docker
read_env(){
local key="$1" default="${2:-}"
local value=""
if [ -f "$ENV_PATH" ]; then
value="$(grep -E "^${key}=" "$ENV_PATH" | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
fi
if [ -z "$value" ]; then
value="$default"
fi
echo "$value"
}
resolve_project_name(){
local raw_name="$(read_env COMPOSE_PROJECT_NAME "acore-compose")"
local sanitized
sanitized="$(echo "$raw_name" | tr '[:upper:]' '[:lower:]')"
sanitized="${sanitized// /-}"
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
if [[ -z "$sanitized" ]]; then
sanitized="acore-compose"
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
sanitized="ac${sanitized}"
fi
echo "$sanitized"
}
compose(){
local project_name
project_name="$(resolve_project_name)"
docker compose --project-name "$project_name" -f "$COMPOSE_FILE" "$@"
}
ensure_source_repo(){
local src_path
src_path="$(read_env MODULES_REBUILD_SOURCE_PATH "./source/azerothcore")"
if [[ "$src_path" != /* ]]; then
src_path="$ROOT_DIR/$src_path"
fi
if [ -d "$src_path/.git" ]; then
echo "$src_path"
return
fi
warn "AzerothCore source not found at $src_path; running setup-source.sh"
(cd "$ROOT_DIR" && ./scripts/setup-source.sh)
echo "$src_path"
}
stop_runtime_stack(){
info "Stopping runtime stack to avoid container name conflicts"
compose \
--profile services-standard \
--profile services-playerbots \
--profile services-modules \
--profile db \
--profile client-data \
--profile client-data-bots \
--profile modules \
down 2>/dev/null || true
}
sync_modules(){
info "Synchronising modules (ac-modules)"
compose --profile db --profile modules up ac-modules
compose --profile db --profile modules down >/dev/null 2>&1 || true
}
modules_need_rebuild(){
local storage_path
storage_path="$(read_env STORAGE_PATH "./storage")"
if [[ "$storage_path" != /* ]]; then
storage_path="$ROOT_DIR/$storage_path"
fi
local sentinel="$storage_path/modules/.requires_rebuild"
[[ -f "$sentinel" ]]
}
rebuild_source(){
local src_dir="$1"
local compose_file="$src_dir/docker-compose.yml"
if [ ! -f "$compose_file" ]; then
err "Source docker-compose.yml missing at $compose_file"
return 1
fi
info "Rebuilding AzerothCore source with modules (this may take a while)"
docker compose -f "$compose_file" down --remove-orphans >/dev/null 2>&1 || true
if (cd "$ROOT_DIR" && ./scripts/rebuild-with-modules.sh --yes); then
ok "Source rebuild completed"
else
err "Source rebuild failed"
return 1
fi
docker compose -f "$compose_file" down --remove-orphans >/dev/null 2>&1 || true
}
tag_module_images(){
local source_world="acore/ac-wotlk-worldserver:master"
local source_auth="acore/ac-wotlk-authserver:master"
local target_world
local target_auth
target_world="$(read_env AC_WORLDSERVER_IMAGE_MODULES "acore/ac-wotlk-worldserver:modules-latest")"
target_auth="$(read_env AC_AUTHSERVER_IMAGE_MODULES "acore/ac-wotlk-authserver:modules-latest")"
if docker image inspect "$source_world" >/dev/null 2>&1; then
docker tag "$source_world" "$target_world"
ok "Tagged $target_world from $source_world"
else
warn "Source image $source_world not found; skipping tag"
fi
if docker image inspect "$source_auth" >/dev/null 2>&1; then
docker tag "$source_auth" "$target_auth"
ok "Tagged $target_auth from $source_auth"
else
warn "Source image $source_auth not found; skipping tag"
fi
}
stage_runtime(){
local args=(--yes)
if [ -n "$TARGET_PROFILE" ]; then
args+=("$TARGET_PROFILE")
fi
info "Staging runtime environment via stage-modules.sh ${args[*]}"
(cd "$ROOT_DIR" && ./scripts/stage-modules.sh "${args[@]}")
}
tail_world_logs(){
info "Tailing worldserver logs (Ctrl+C to stop)"
compose logs -f ac-worldserver
}
main(){
local src_dir
src_dir="$(ensure_source_repo)"
if [ "$KEEP_RUNNING" -ne 1 ]; then
stop_runtime_stack
fi
sync_modules
if modules_need_rebuild; then
if [ "$SKIP_REBUILD" -eq 1 ]; then
warn "Modules require rebuild, but --skip-rebuild was provided."
else
rebuild_source "$src_dir"
tag_module_images
fi
else
info "No module rebuild required."
tag_module_images
fi
stage_runtime
if [ "$WATCH_LOGS" -eq 1 ]; then
tail_world_logs
else
ok "Deployment completed. Logs not tailed (--no-watch)."
fi
}
main