#!/usr/bin/env bash set -euo pipefail # 1. 只负责把当前 release 目录里的编排资产和镜像包应用到运行目录。 # 2. 不负责生成镜像,也不负责计算影响范围;这些工作由构建机和 impact-rules.sh 提前完成。 # 3. 如果 release-plan.env 缺失或格式错误,直接失败,避免在生产机上猜测要重启哪些服务。 runtime_dir="${SMARTFLOW_RUNTIME_DIR:-/root/smartflow}" release_dir="${SMARTFLOW_RELEASE_DIR:?SMARTFLOW_RELEASE_DIR is required}" release_id="${SMARTFLOW_RELEASE_ID:?SMARTFLOW_RELEASE_ID is required}" plan_file="${release_dir}/deploy/release-plan.env" runtime_env="${runtime_dir}/.env" if [[ ! -f "${plan_file}" ]]; then echo "release plan not found: ${plan_file}" >&2 exit 66 fi if [[ ! -f "${runtime_env}" ]]; then echo "runtime env not found: ${runtime_env}" >&2 exit 67 fi source "${plan_file}" if [[ "${SMARTFLOW_NOOP:-0}" == "1" ]]; then echo "release ${release_id} resolved to no-op" exit 0 fi set_env_var() { local key="$1" local value="$2" local file="$3" local tmp tmp="$(mktemp)" awk -v key="${key}" -v value="${value}" ' BEGIN { updated = 0 } $0 ~ ("^" key "=") { print key "=" value updated = 1 next } { print } END { if (updated == 0) { print key "=" value } } ' "${file}" > "${tmp}" mv "${tmp}" "${file}" } mkdir -p "${runtime_dir}/deploy/nginx" install -m 0644 "${release_dir}/docker-compose.full.yml" "${runtime_dir}/docker-compose.full.yml" install -m 0644 "${release_dir}/deploy/nginx/default.conf" "${runtime_dir}/deploy/nginx/default.conf" if compgen -G "${release_dir}/.docker-bundles/*.tar" >/dev/null 2>&1; then bash "${release_dir}/deploy/docker-load.sh" "${release_dir}/.docker-bundles" fi if [[ "${SMARTFLOW_BUILD_BACKEND:-0}" == "1" ]]; then set_env_var "SMARTFLOW_BACKEND_IMAGE" "${SMARTFLOW_BACKEND_IMAGE}" "${runtime_env}" fi if [[ "${SMARTFLOW_BUILD_FRONTEND:-0}" == "1" ]]; then set_env_var "SMARTFLOW_FRONTEND_IMAGE" "${SMARTFLOW_FRONTEND_IMAGE}" "${runtime_env}" fi services=() IFS=',' read -r -a raw_services <<< "${SMARTFLOW_RESTART_SERVICES:-}" for service in "${raw_services[@]}"; do if [[ -n "${service}" ]]; then services+=("${service}") fi done if [[ "${#services[@]}" -eq 0 ]]; then echo "release ${release_id} has no target services" exit 0 fi # 1. 使用 --no-deps 只重建命中的服务,避免后端小改动把整套依赖链一起拉起来。 # 2. 如果后续服务新增或删减,只要 release-plan.env 给出的服务名同步更新,这里无需改脚本。 # 3. 失败时直接退出,由上层薄封装决定是否切回旧 release。 ( cd "${runtime_dir}" docker compose -f docker-compose.full.yml up -d --no-deps "${services[@]}" ) if [[ "${SMARTFLOW_BUILD_BACKEND:-0}" == "1" || " ${services[*]} " == *" api "* ]]; then curl -fsS http://127.0.0.1:8080/api/v1/health >/dev/null fi if [[ " ${services[*]} " == *" frontend "* ]]; then curl -k -fsS https://smartmate.lecspace.com/ >/dev/null curl -k -fsS https://git.lecspace.com/ >/dev/null fi printf '%s\n' "${release_id}" > "${SMARTFLOW_RELEASE_ROOT}/last_successful_release" ln -sfn "${release_dir}" "${SMARTFLOW_CURRENT_LINK}" echo "release ${release_id} deployed successfully"