Files

157 lines
5.2 KiB
Bash
Raw Permalink Normal View History

2026-05-11 10:41:36 +08:00
#!/usr/bin/env bash
# datahub 更新脚本:git pull + 智能重建 + 滚动重启
#
# 用法:bash update.sh [选项]
# --force-rebuild 不看 git diff,强制重建所有镜像
# --skip-migrate 检测到新迁移时不提示,直接跳过
set -euo pipefail
B='\033[34m'; G='\033[32m'; Y='\033[33m'; R='\033[31m'; N='\033[0m'
step() { echo -e "\n${B}=> $*${N}"; }
ok() { echo -e "${G}[OK]${N} $*"; }
warn() { echo -e "${Y}[!]${N} $*"; }
err() { echo -e "${R}[ERR]${N} $*" >&2; }
FORCE_REBUILD=false
SKIP_MIGRATE=false
for arg in "$@"; do
case "$arg" in
--force-rebuild) FORCE_REBUILD=true ;;
--skip-migrate) SKIP_MIGRATE=true ;;
-h|--help)
sed -n '2,7p' "$0"
exit 0
;;
*) echo "未知参数: $arg" >&2; exit 1 ;;
esac
done
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
REPO_ROOT=$(cd "$SCRIPT_DIR/../../.." && pwd)
QUADLET_DIR="$HOME/.config/containers/systemd"
cd "$REPO_ROOT"
# 1. 必须是 git 仓库且工作区干净
if [ ! -d .git ]; then
err "$REPO_ROOT 不是 git 仓库"
exit 1
fi
if ! git diff --quiet || ! git diff --cached --quiet; then
err "工作区有未提交的变更,先 stash 或 commit"
git status --short
exit 1
fi
# 2. git pull
step "git pull"
OLD_HEAD=$(git rev-parse HEAD)
git pull --ff-only
NEW_HEAD=$(git rev-parse HEAD)
if [ "$OLD_HEAD" = "$NEW_HEAD" ] && [ "$FORCE_REBUILD" = false ]; then
ok "代码已是最新,无需更新(如需强制重建请加 --force-rebuild"
exit 0
fi
# 3. 检测变更范围
if [ "$FORCE_REBUILD" = true ]; then
CH_BACKEND=true; CH_FRONTEND=true; CH_QUADLET=true
CH_PG_IMAGE=true; CH_MIGRATIONS=true
warn "强制重建:忽略 git diff"
else
DIFF=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD")
matches() { echo "$DIFF" | grep -qE "$1"; }
CH_BACKEND=$(matches '^backend/' && echo true || echo false)
CH_FRONTEND=$(matches '^(frontend/|deploy/podman/images/frontend/)' && echo true || echo false)
CH_QUADLET=$(matches '^deploy/podman/quadlet/' && echo true || echo false)
CH_PG_IMAGE=$(matches '^deploy/podman/images/postgres/' && echo true || echo false)
CH_MIGRATIONS=$(matches '^backend/migrations/' && echo true || echo false)
fi
echo
echo "变更检测:"
printf " %-20s %s\n" "backend image:" "$CH_BACKEND"
printf " %-20s %s\n" "frontend image:" "$CH_FRONTEND"
printf " %-20s %s\n" "postgres image:" "$CH_PG_IMAGE"
printf " %-20s %s\n" "quadlet files:" "$CH_QUADLET"
printf " %-20s %s\n" "migrations:" "$CH_MIGRATIONS"
# 4. 重建镜像
if [ "$CH_PG_IMAGE" = "true" ]; then
step "重建 postgres 镜像"
podman build -t localhost/datahub-postgres:latest \
-f deploy/podman/images/postgres/Dockerfile .
fi
if [ "$CH_BACKEND" = "true" ]; then
step "重建 backend 镜像"
podman build -t localhost/datahub-backend:latest \
-f backend/Dockerfile backend/
fi
if [ "$CH_FRONTEND" = "true" ]; then
step "重建 frontend 镜像"
podman build -t localhost/datahub-frontend:latest \
-f deploy/podman/images/frontend/Dockerfile .
fi
# 5. 同步 Quadlet(任何 quadlet 改动或强制时)
if [ "$CH_QUADLET" = "true" ] || [ "$FORCE_REBUILD" = true ]; then
step "同步 Quadlet 单元"
cp deploy/podman/quadlet/* "$QUADLET_DIR/"
systemctl --user daemon-reload
ok "Quadlet 已更新"
fi
# 6. 滚动重启受影响的服务
step "重启受影响的服务"
restart_svc() {
local svc=$1
echo " 重启 $svc.service"
systemctl --user restart "$svc.service"
sleep 2
if ! systemctl --user is-active --quiet "$svc.service"; then
err "$svc 重启失败"
journalctl --user -u "$svc.service" -n 40 --no-pager
exit 1
fi
}
[ "$CH_PG_IMAGE" = "true" ] && restart_svc datahub-postgres
[ "$CH_BACKEND" = "true" ] && restart_svc datahub-backend
[ "$CH_FRONTEND" = "true" ] && restart_svc datahub-frontend
# Quadlet 改了但镜像没改时,仍需重启对应服务
if [ "$CH_QUADLET" = "true" ]; then
DIFF_Q=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- deploy/podman/quadlet/ 2>/dev/null || true)
[ "$CH_PG_IMAGE" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-postgres" && restart_svc datahub-postgres
[ "$CH_BACKEND" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-backend" && restart_svc datahub-backend
[ "$CH_FRONTEND" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-frontend" && restart_svc datahub-frontend
echo "$DIFF_Q" | grep -q "datahub-rabbitmq" && restart_svc datahub-rabbitmq
fi
# 7. 迁移提示
if [ "$CH_MIGRATIONS" = "true" ] && [ "$SKIP_MIGRATE" = false ]; then
echo
warn "检测到新迁移文件:"
git diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- backend/migrations/ | sed 's/^/ /'
read -rp "立即执行迁移?(Y/n): " ans
ans="${ans,,}"
if [[ -z "$ans" || "$ans" == "y" ]]; then
podman exec -it datahub-backend php bin/hyperf.php migrate
ok "迁移完成"
else
warn "跳过。后续可手动执行:podman exec -it datahub-backend php bin/hyperf.php migrate"
fi
elif [ "$CH_MIGRATIONS" = "true" ]; then
warn "检测到新迁移但已 --skip-migrate,请手动执行"
fi
echo
ok "更新完成"
echo " $OLD_HEAD"
echo "$NEW_HEAD"