Files
gongxue-base/scripts/deploy/bin/deploy.sh
2026-07-01 20:09:02 +08:00

141 lines
3.7 KiB
Bash

#!/usr/bin/env bash
set -Eeuo pipefail
CONFIG_FILE="${CONFIG_FILE:-/etc/tiku-saas/deploy.env}"
if [[ ! -r "$CONFIG_FILE" ]]; then
echo "Missing deploy config: $CONFIG_FILE" >&2
exit 1
fi
# shellcheck disable=SC1090
source "$CONFIG_FILE"
: "${GIT_REPO:?GIT_REPO is required}"
: "${GIT_BRANCH:=main}"
: "${APP_ROOT:=/opt/tiku-saas}"
: "${REPO_DIR:=$APP_ROOT/repo}"
: "${WWW_ROOT:=/srv/tiku-saas/www}"
: "${RUNTIME_CONFIG_DIR:=/etc/tiku-saas/runtime-config}"
: "${RUN_SECURITY_CHECKS:=true}"
: "${RUN_LAUNCH_GATE:=true}"
: "${RESTART_SERVICES:=true}"
LOCK_FILE="${LOCK_FILE:-/tmp/tiku-saas-deploy.lock}"
mkdir -p "$APP_ROOT" "$WWW_ROOT/student" "$WWW_ROOT/tenant-admin" "$WWW_ROOT/platform-admin"
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
echo "Another deployment is already running." >&2
exit 1
fi
log() {
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
cleanup() {
if [[ -n "${ASKPASS_FILE:-}" && -f "$ASKPASS_FILE" ]]; then
rm -f "$ASKPASS_FILE"
fi
}
trap cleanup EXIT
prepare_git_auth() {
if [[ -n "${GIT_SSH_COMMAND:-}" ]]; then
export GIT_SSH_COMMAND
return
fi
if [[ -z "${GIT_USERNAME:-}" || -z "${GITEA_TOKEN:-}" ]]; then
return
fi
ASKPASS_FILE="$(mktemp)"
chmod 700 "$ASKPASS_FILE"
cat > "$ASKPASS_FILE" <<'ASKPASS'
#!/usr/bin/env bash
case "$1" in
*Username*) printf '%s\n' "$GIT_USERNAME" ;;
*Password*) printf '%s\n' "$GITEA_TOKEN" ;;
*) printf '\n' ;;
esac
ASKPASS
export GIT_ASKPASS="$ASKPASS_FILE"
export GIT_TERMINAL_PROMPT=0
}
prepare_git_auth
if [[ ! -d "$REPO_DIR/.git" ]]; then
log "Cloning repository..."
git clone --branch "$GIT_BRANCH" "$GIT_REPO" "$REPO_DIR"
fi
cd "$REPO_DIR"
log "Fetching $GIT_BRANCH..."
git fetch origin "$GIT_BRANCH" --prune
git checkout "$GIT_BRANCH"
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "Repository has local changes. Refusing to deploy until the server checkout is clean." >&2
exit 1
fi
git merge --ff-only "origin/$GIT_BRANCH"
CURRENT_SHA="$(git rev-parse --short=12 HEAD)"
log "Deploying commit $CURRENT_SHA"
log "Installing dependencies with npm ci..."
npm ci
if [[ "$RUN_SECURITY_CHECKS" == "true" ]]; then
log "Running repository security scan..."
npm run security:repo
fi
if [[ "$RUN_LAUNCH_GATE" == "true" ]]; then
log "Running production launch gate test..."
node scripts/production-launch-gate-test.js
fi
log "Building API and worker..."
npm run build:api
npm run build:worker
log "Building H5 portals..."
npm run build:taro:h5:student
npm run build:taro:h5:tenant
npm run build:taro:h5:platform
log "Publishing H5 static assets..."
rsync -a --delete apps/taro/dist/h5-student/ "$WWW_ROOT/student/"
rsync -a --delete apps/taro/dist/h5-tenant-admin/ "$WWW_ROOT/tenant-admin/"
rsync -a --delete apps/taro/dist/h5-platform-admin/ "$WWW_ROOT/platform-admin/"
install_runtime_config() {
local source_file="$1"
local target_dir="$2"
if [[ ! -r "$source_file" ]]; then
echo "Missing runtime config: $source_file" >&2
exit 1
fi
install -m 0644 "$source_file" "$target_dir/runtime-config.json"
}
log "Installing H5 runtime config files..."
install_runtime_config "$RUNTIME_CONFIG_DIR/h5-student.runtime-config.json" "$WWW_ROOT/student"
install_runtime_config "$RUNTIME_CONFIG_DIR/h5-tenant-admin.runtime-config.json" "$WWW_ROOT/tenant-admin"
install_runtime_config "$RUNTIME_CONFIG_DIR/h5-platform-admin.runtime-config.json" "$WWW_ROOT/platform-admin"
if [[ "$RESTART_SERVICES" == "true" ]]; then
log "Restarting systemd services..."
systemctl restart tiku-api.service
systemctl restart tiku-worker.service
systemctl --no-pager --full status tiku-api.service tiku-worker.service >/dev/null
fi
log "Deployment finished: $CURRENT_SHA"