fix deploy env bom handling

This commit is contained in:
2026-04-26 00:07:12 +08:00
parent c9a59f9edb
commit c4b9b8173f
6 changed files with 117 additions and 12 deletions

View File

@@ -57,6 +57,19 @@ copy_required_file() {
cp "${source_path}" "${target_path}"
}
normalize_env_file() {
local env_file="$1"
local temp_file="${env_file}.tmp.$$"
if [[ ! -f "${env_file}" ]]; then
return
fi
# 发布环境文件可能由 Windows 编辑器保存,启动脚本只接受无 BOM、无 CRLF 的 KEY=value 文本。
LC_ALL=C sed $'1s/^\xef\xbb\xbf//;s/\r$//' "${env_file}" >"${temp_file}"
mv "${temp_file}" "${env_file}"
}
copy_optional_file() {
local source_path="$1"
local target_path_a="$2"
@@ -70,6 +83,8 @@ copy_optional_file() {
cp "${source_path}" "${target_path_a}"
cp "${source_path}" "${target_path_b}"
normalize_env_file "${target_path_a}"
normalize_env_file "${target_path_b}"
echo "[deploy:rust] 已复制 ${label} -> ${target_path_a}${target_path_b}"
}
@@ -426,17 +441,47 @@ cd "${SCRIPT_DIR}"
load_env_file() {
local env_file="$1"
local line=""
local line_number=0
local key=""
local value=""
local utf8_bom=$'\xef\xbb\xbf'
if [[ ! -f "${env_file}" ]]; then
return
fi
echo "[start] 加载环境文件: ${env_file}"
set -a
# 发布包内环境文件由当前构建脚本生成,允许在启动时作为默认环境源加载
# shellcheck disable=SC1090
source "${env_file}"
set +a
# 环境文件按 dotenv 的 KEY=value 子集解析,避免 BOM 被 shell 当成命令名执行
while IFS= read -r line || [[ -n "${line}" ]]; do
line_number=$((line_number + 1))
if [[ "${line_number}" -eq 1 ]]; then
line="${line#"${utf8_bom}"}"
fi
line="${line%$'\r'}"
if [[ "${line}" =~ ^[[:space:]]*$ || "${line}" =~ ^[[:space:]]*# ]]; then
continue
fi
if [[ ! "${line}" =~ ^[[:space:]]*(export[[:space:]]+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
echo "[start] 跳过不符合 KEY=value 的环境行: ${env_file}:${line_number}" >&2
continue
fi
key="${BASH_REMATCH[2]}"
value="${BASH_REMATCH[3]}"
if [[ "${#value}" -ge 2 && "${value:0:1}" == '"' && "${value: -1}" == '"' ]]; then
value="${value:1:${#value}-2}"
value="${value//\\\"/\"}"
elif [[ "${#value}" -ge 2 && "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
value="${value:1:${#value}-2}"
fi
printf -v "${key}" '%s' "${value}"
export "${key}"
done <"${env_file}"
}
usage() {
@@ -655,6 +700,7 @@ cat >"${TARGET_DIR}/README.md" <<EOF
## 环境变量
- 启动时会先加载发布目录根部的 \`.env\` 与 \`.env.local\`,再回退到脚本内默认值。
- 环境文件复制进发布包时会移除 UTF-8 BOM 与 CRLF启动时也会按 \`KEY=value\` 子集解析,跳过不合法行。
- 脚本内默认值来自构建时的 `--database`、`--api-port`、`--web-port`、`--spacetime-host`、`--spacetime-port` 参数。
- 默认导出 \`NO_COLOR=1\` 与 \`CARGO_TERM_COLOR=never\`,避免 ANSI 颜色控制码写入日志文件;如确有需要可在启动前显式覆盖。
- \`GENARRATIVE_WEB_HOST\` / \`GENARRATIVE_WEB_PORT\`

View File

@@ -32,6 +32,28 @@ require_argument() {
fi
}
normalize_env_file() {
local env_file="$1"
local temp_file="${env_file}.tmp.$$"
if [[ ! -f "${env_file}" ]]; then
return
fi
# 兼容由 Windows 编辑器或 Jenkins 参数落盘产生的 BOM/CRLF避免 start.sh 加载时报命令不存在。
LC_ALL=C sed $'1s/^\xef\xbb\xbf//;s/\r$//' "${env_file}" >"${temp_file}"
mv "${temp_file}" "${env_file}"
}
normalize_release_env_files() {
local release_dir="$1"
normalize_env_file "${release_dir}/.env"
normalize_env_file "${release_dir}/.env.local"
normalize_env_file "${release_dir}/web/.env"
normalize_env_file "${release_dir}/web/.env.local"
}
SOURCE_DIR=""
DEPLOY_DIR=""
CLEAR_DATABASE="0"
@@ -125,6 +147,8 @@ if [[ ! -f "${SOURCE_DIR}/start.sh" ]]; then
exit 1
fi
normalize_release_env_files "${SOURCE_DIR}"
if [[ -x "${DEPLOY_DIR}/stop.sh" ]]; then
echo "[jenkins-deploy] 先停止旧版本: ${DEPLOY_DIR}"
run_hook "${DEPLOY_DIR}" "stop.sh"
@@ -154,6 +178,8 @@ if [[ -f "${DEPLOY_DIR}/stop.sh" ]]; then
chmod +x "${DEPLOY_DIR}/stop.sh"
fi
normalize_release_env_files "${DEPLOY_DIR}"
echo "[jenkins-deploy] 启动新版本: ${DEPLOY_DIR}"
if [[ "${CLEAR_DATABASE}" == "1" ]]; then
echo "[jenkins-deploy] 以清库模式启动新版本"