fix(deploy): .env 写入改成引号自适应(JSON 用单引号),并去掉 awk 的值截断隐患

两个真实问题:
1) upsert_env_key 一律用双引号包裹 → JSON 值(含双引号)会写成
   KEY={a:b} 这种坏行,docker compose 解析会崩/取到残缺值;
   现在:值里含双引号就用单引号包(JSON 不含单引号,安全)。
2) 原来用 awk 'BEGIN{FS=OFS==} =...' 重建行,会把值里 = 之后的内容丢掉
   (base64 密钥常带 = 填充)→ 改用 grep -v + 追加,值原样保留。

已用 Git Bash 对函数本身做单测(8 项断言全过):JSON 单引号包裹、带 = 的值不丢、
普通值双引号、重复更新不堆行、sed 取回后 JSON.parse 成功。
This commit is contained in:
2026-09-27 15:29:32 +08:00
parent 08a37e4e2f
commit 575e8b9f57
+15 -4
View File
@@ -961,15 +961,26 @@ jobs:
upsert_env_key() {
_K="$1"; _V="$2"
if [ -z "${_V}" ]; then return 0; fi
# 值的引号要自适应:JSON(含双引号)必须用**单引号**包,
# 否则 .env 会变成 KEY="{"a":"b"}" 这种坏行,docker compose 解析直接崩。
# 值里不可能同时出现两种引号(JSON 不含单引号),所以这样是安全的。
_Q='"'
case "${_V}" in
*'"'*) _Q="'" ;;
esac
_LINE="${_K}=${_Q}${_V}${_Q}"
if grep -q "^${_K}=" "${ENV_FILE}" 2>/dev/null; then
if command -v awk >/dev/null 2>&1; then
awk -v K="${_K}" -v V="${_V}" 'BEGIN{FS=OFS="="} $1==K{$2="\"" V "\""} 1' "${ENV_FILE}" > "${ENV_FILE}.tmp.$$" \
&& mv "${ENV_FILE}.tmp.$$" "${ENV_FILE}" || MERGE_OK=0
# 用 grep -v 重写而不是 awk 改字段:awk 的 FS="=" 会把值里 "=" 之后的内容丢掉
# (base64 密钥常带 "=" 填充,正好踩这个坑)
if grep -v "^${_K}=" "${ENV_FILE}" > "${ENV_FILE}.tmp.$$" 2>/dev/null; then
printf '%s\n' "${_LINE}" >> "${ENV_FILE}.tmp.$$"
mv "${ENV_FILE}.tmp.$$" "${ENV_FILE}" || { rm -f "${ENV_FILE}.tmp.$$"; MERGE_OK=0; }
else
rm -f "${ENV_FILE}.tmp.$$"
MERGE_OK=0
fi
else
printf '%s="%s"\n' "${_K}" "${_V}" >> "${ENV_FILE}"
printf '%s\n' "${_LINE}" >> "${ENV_FILE}"
fi
}
upsert_env_key OAUTH_REDIRECT_URI "${OAUTH_REDIRECT_URI}" || MERGE_OK=0