forked from wangbo/easyai
feat(deploy): 增加受控更新与环境配置迁移
This commit is contained in:
Executable
+151
@@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ENV_FILE="${1:-.env}"
|
||||
PROJECT_ROOT="${2:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
||||
MIGRATIONS_DIR="${UPDATE_ENV_MIGRATIONS_DIR:-$PROJECT_ROOT/scripts/update-env.d}"
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "❌ 环境配置文件不存在: $ENV_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$MIGRATIONS_DIR" ]; then
|
||||
echo "ℹ️ 未发现环境配置迁移目录,跳过"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
read_env_value() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local value
|
||||
value="$(awk -v key="$key" 'index($0, key "=") == 1 { print substr($0, length(key) + 2); exit }' "$file")"
|
||||
value="$(printf '%s' "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||
case "$value" in
|
||||
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
||||
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
||||
esac
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
write_env_value() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
local temporary
|
||||
temporary="$(mktemp "${file}.tmp.XXXXXX")"
|
||||
awk -v key="$key" -v value="$value" '
|
||||
BEGIN { replaced = 0 }
|
||||
index($0, key "=") == 1 {
|
||||
if (!replaced) {
|
||||
print key "=" value
|
||||
replaced = 1
|
||||
}
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
END { if (!replaced) print key "=" value }
|
||||
' "$file" > "$temporary"
|
||||
chmod 600 "$temporary"
|
||||
mv "$temporary" "$file"
|
||||
}
|
||||
|
||||
apply_default() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "$(read_env_value "$ENV_FILE" "$key")" ]; then
|
||||
return 0
|
||||
fi
|
||||
write_env_value "$ENV_FILE" "$key" "$value"
|
||||
echo " ✓ 已补充环境配置: $key"
|
||||
}
|
||||
|
||||
ensure_list_item() {
|
||||
local key="$1"
|
||||
local item="$2"
|
||||
local current normalized
|
||||
current="$(read_env_value "$ENV_FILE" "$key")"
|
||||
normalized="$(printf '%s' "$current" | tr -d '[:space:]')"
|
||||
case ",${normalized}," in
|
||||
*",${item},"*) return 0 ;;
|
||||
esac
|
||||
if [ -n "$current" ]; then
|
||||
current="${current},${item}"
|
||||
else
|
||||
current="$item"
|
||||
fi
|
||||
write_env_value "$ENV_FILE" "$key" "$current"
|
||||
echo " ✓ 已补充环境配置项: $key"
|
||||
}
|
||||
|
||||
validate_manifest() {
|
||||
local manifest="$1"
|
||||
local line line_number=0
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
line_number=$((line_number + 1))
|
||||
line="${line%$'\r'}"
|
||||
case "$line" in
|
||||
""|'#'*) continue ;;
|
||||
esac
|
||||
if [[ "$line" =~ ^@skip-if[[:space:]]+[A-Z][A-Z0-9_]*=.+$ ]]; then
|
||||
continue
|
||||
fi
|
||||
if ! [[ "$line" =~ ^[A-Z][A-Z0-9_]*(\+)?=.+$ ]]; then
|
||||
echo "❌ 无效的环境配置迁移: ${manifest}:${line_number}" >&2
|
||||
return 1
|
||||
fi
|
||||
done < "$manifest"
|
||||
}
|
||||
|
||||
apply_manifest() {
|
||||
local manifest="$1"
|
||||
local line key value current
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
line="${line%$'\r'}"
|
||||
if [[ "$line" =~ ^@skip-if[[:space:]]+([A-Z][A-Z0-9_]*)=(.+)$ ]]; then
|
||||
key="${BASH_REMATCH[1]}"
|
||||
value="${BASH_REMATCH[2]}"
|
||||
current="$(read_env_value "$ENV_FILE" "$key")"
|
||||
if [ "$current" = "$value" ]; then
|
||||
echo "ℹ️ 保留现有更新模式,跳过环境配置迁移: $(basename "$manifest")"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done < "$manifest"
|
||||
echo "📝 应用环境配置迁移: $(basename "$manifest")"
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
line="${line%$'\r'}"
|
||||
case "$line" in
|
||||
""|'#'*) continue ;;
|
||||
esac
|
||||
if [[ "$line" == @skip-if* ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ "$line" == *'+='* ]]; then
|
||||
key="${line%%+=*}"
|
||||
value="${line#*+=}"
|
||||
ensure_list_item "$key" "$value"
|
||||
else
|
||||
key="${line%%=*}"
|
||||
value="${line#*=}"
|
||||
apply_default "$key" "$value"
|
||||
fi
|
||||
done < "$manifest"
|
||||
}
|
||||
|
||||
shopt -s nullglob
|
||||
manifests=("$MIGRATIONS_DIR"/*.env)
|
||||
if [ "${#manifests[@]}" -eq 0 ]; then
|
||||
echo "ℹ️ 未发现环境配置迁移文件,跳过"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for manifest in "${manifests[@]}"; do
|
||||
validate_manifest "$manifest"
|
||||
done
|
||||
for manifest in "${manifests[@]}"; do
|
||||
apply_manifest "$manifest"
|
||||
done
|
||||
|
||||
chmod 600 "$ENV_FILE"
|
||||
Reference in New Issue
Block a user