From 459cf6149579441ee16ae56ab46a5d8f4b01da35 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Wed, 2 Sep 2026 17:02:45 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(config):=20Phase=204=20=E2=80=94=20?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=A8=A1=E6=9D=BF=20+=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=20+=20CI=20=E9=83=A8=E7=BD=B2=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 第一部分:修正配置模板(7 处差异) - MINIO_BUCKET → MINIO_BUCKET_NAME(统一变量名) - 删除 DOUBAO_API_KEY 区块(两个环境都没在用) - 新增 DASHSCOPE_API_KEY(实际在用,模板漏了) - 新增 MediaKit 区块(3 个变量) - staging DEBUG=true(实际在用 true) - ENABLE_EMAIL_DELIVERY=false(邮件功能未上线) - SMTP 相关默认值改为空 第二部分:创建 env 渲染脚本 - scripts/render_env.sh:从模板 + Secrets 渲染 .env - 使用 Python 实现变量替换(CI runner 无 envsubst) - 支持 STAGING_xxx/PRODUCTION_xxx 前缀映射 - 自动校验所有必需变量已设置 - 输出文件权限 600,不打印到日志 第三部分:改造 CI 部署流程 - deploy-staging 新增 'Render .env from template' 步骤 - SSH deploy 前先 SCP 渲染后的 .env 到服务器 - 自动备份旧 .env(带时间戳) - 部署完成后清理 CI runner 上的渲染文件 - ci_staging_deploy.sh 改为显式检查 .env 来源 安全: .env.rendered 加入 .gitignore --- .gitea/workflows/ci-pipeline.yml | 38 +++++++++ .gitignore | 2 + deploy/configs/.env.production | 39 ++++----- deploy/configs/.env.staging | 45 ++++------- scripts/ci_staging_deploy.sh | 8 +- scripts/render_env.sh | 134 +++++++++++++++++++++++++++++++ 6 files changed, 212 insertions(+), 54 deletions(-) create mode 100644 scripts/render_env.sh diff --git a/.gitea/workflows/ci-pipeline.yml b/.gitea/workflows/ci-pipeline.yml index 2eec845f7..162e0a3d3 100755 --- a/.gitea/workflows/ci-pipeline.yml +++ b/.gitea/workflows/ci-pipeline.yml @@ -1169,6 +1169,31 @@ jobs: run: | set +e NOTIFY_MODE=start JOB_NAME="Deploy Staging" python3 scripts/ci_notify.py + - name: Render .env from template + shell: sh + env: + STAGING_DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }} + STAGING_REDIS_URL: ${{ secrets.STAGING_REDIS_URL }} + STAGING_CELERY_BROKER_URL: ${{ secrets.STAGING_CELERY_BROKER_URL }} + STAGING_CELERY_RESULT_BACKEND: ${{ secrets.STAGING_CELERY_RESULT_BACKEND }} + STAGING_JWT_SECRET_KEY: ${{ secrets.STAGING_JWT_SECRET_KEY }} + STAGING_MINIO_ENDPOINT: ${{ secrets.STAGING_MINIO_ENDPOINT }} + STAGING_MINIO_ACCESS_KEY: ${{ secrets.STAGING_MINIO_ACCESS_KEY }} + STAGING_MINIO_SECRET_KEY: ${{ secrets.STAGING_MINIO_SECRET_KEY }} + STAGING_MINIO_BUCKET_NAME: ${{ secrets.STAGING_MINIO_BUCKET_NAME }} + OSS_ACCESS_KEY_ID: ${{ secrets.OSS_ACCESS_KEY_ID }} + OSS_ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }} + COSYVOICE_API_KEY: ${{ secrets.COSYVOICE_API_KEY }} + DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }} + MEDIAKIT_API_KEY: ${{ secrets.MEDIAKIT_API_KEY }} + run: | + set -eu + echo "Rendering .env from template + secrets..." + bash scripts/render_env.sh staging + echo "✅ .env rendered (file contains secrets, not printed to log)" + # 验证文件存在且非空 + test -s .env.rendered + echo "✅ .env.rendered validated ($(wc -l < .env.rendered) lines)" - name: Docker login to Registry shell: sh env: @@ -1241,9 +1266,22 @@ jobs: ssh -p "$staging_port" -i "$key_path" -o StrictHostKeyChecking=no "${staging_user}@${staging_host}" "echo SSH_CONNECTION_OK && hostname" echo "SSH connection verified" + # 上传渲染后的 .env 到服务器(替代服务器上旧的 .env) + echo "Uploading rendered .env to staging server..." + # 备份旧 .env + ssh -p "$staging_port" -i "$key_path" -o StrictHostKeyChecking=no "${staging_user}@${staging_host}" \ + "cp -f /var/lib/xiaoxia-saas-staging/.env /var/lib/xiaoxia-saas-staging/.env.bak.\$(date +%Y%m%d%H%M%S) 2>/dev/null || true" + # 上传新 .env + scp -P "$staging_port" -i "$key_path" -o StrictHostKeyChecking=no .env.rendered \ + "${staging_user}@${staging_host}:/var/lib/xiaoxia-saas-staging/.env" + echo "✅ .env uploaded to staging server" + # 通过环境变量传递凭证,避免命令行引号转义问题 cat scripts/ci_staging_deploy.sh | ssh -p "$staging_port" -i "$key_path" -o StrictHostKeyChecking=no "${staging_user}@${staging_host}" "IMAGE_TAG=${GITHUB_SHA} ACR_USERNAME=${ACR_USERNAME} ACR_PASSWORD=${ACR_PASSWORD} sh" + # 清理 CI runner 上的渲染文件 + rm -f .env.rendered + - name: Staging health check + auto rollback if: success() shell: sh diff --git a/.gitignore b/.gitignore index 96705506e..72a62eb23 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ ruff_cache/ # 配置模板不受忽略规则限制 !deploy/configs/.env.staging !deploy/configs/.env.production +# 渲染后的 env 文件包含真实密钥,绝不能提交 +.env.rendered # OS / editor .DS_Store diff --git a/deploy/configs/.env.production b/deploy/configs/.env.production index 14d480e64..d4d1bf1f7 100644 --- a/deploy/configs/.env.production +++ b/deploy/configs/.env.production @@ -104,8 +104,8 @@ JWT_REFRESH_TOKEN_EXPIRE_DAYS=30 # ==================== 邮件配置 ==================== -# 启用邮件投递 -ENABLE_EMAIL_DELIVERY=true +# 邮件功能尚未上线,暂时关闭 +ENABLE_EMAIL_DELIVERY=false # SMTP 服务器地址 SMTP_HOST=smtp.gmail.com @@ -113,16 +113,14 @@ SMTP_HOST=smtp.gmail.com # SMTP 端口 SMTP_PORT=587 -# SMTP 用户名 -# ${SMTP_USER} — 替换为实际的 SMTP 用户名 -SMTP_USER=${SMTP_USER} +# SMTP 用户名(邮件功能上线后配置) +SMTP_USER= -# SMTP 密码 / 应用专用密码 -# ${SMTP_PASSWORD} — 替换为实际的 SMTP 密码 -SMTP_PASSWORD=${SMTP_PASSWORD} +# SMTP 密码(邮件功能上线后配置) +SMTP_PASSWORD= -# 发件人邮箱 -SMTP_FROM_EMAIL=noreply@xiaoxia-saas.com +# 发件人邮箱(邮件功能上线后配置) +SMTP_FROM_EMAIL= # 发件人显示名称 SMTP_FROM_NAME=小虾 SaaS @@ -202,24 +200,15 @@ COSYVOICE_FORMAT=mp3 # 音色克隆模型名(固定值) COSYVOICE_CLONE_MODEL=voice-enrollment +# DashScope 通用 API Key(与 CosyVoice 共用) +DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY} -# ==================== 豆包大模型(火山引擎方舟)==================== -# 豆包 API Key -# ${DOUBAO_API_KEY} — 替换为实际的豆包 API Key -DOUBAO_API_KEY=${DOUBAO_API_KEY} +# ==================== MediaKit 视频理解(火山引擎)==================== -# 模型名称 -DOUBAO_MODEL=doubao-seed-1-6-250615 - -# API 基础 URL -DOUBAO_BASE_URL=https://ark.cn-beijing.volces.com/api/v3 - -# 请求超时时间(秒) -DOUBAO_TIMEOUT=30 - -# 最大重试次数 -DOUBAO_MAX_RETRIES=2 +MEDIAKIT_API_KEY=${MEDIAKIT_API_KEY} +MEDIAKIT_BASE_URL=https://mediakit.cn-beijing.volces.com/api/v1 +MEDIAKIT_TIMEOUT=60 # ==================== 监控(可选)==================== diff --git a/deploy/configs/.env.staging b/deploy/configs/.env.staging index 423c7acb8..6c58cf85a 100644 --- a/deploy/configs/.env.staging +++ b/deploy/configs/.env.staging @@ -14,8 +14,8 @@ APP_NAME=xiaoxia-saas # 环境标识 APP_ENV=staging -# 关闭 Debug 模式 -DEBUG=false +# Staging 开启 Debug 模式便于排查问题 +DEBUG=true # 应用基础 URL(前端页面地址) APP_BASE_URL=https://staging.xiaoxiajianji.com @@ -104,8 +104,8 @@ JWT_REFRESH_TOKEN_EXPIRE_DAYS=30 # ==================== 邮件配置 ==================== -# 启用邮件投递 -ENABLE_EMAIL_DELIVERY=true +# 邮件功能尚未上线,暂时关闭 +ENABLE_EMAIL_DELIVERY=false # SMTP 服务器地址 SMTP_HOST=smtp.gmail.com @@ -113,16 +113,14 @@ SMTP_HOST=smtp.gmail.com # SMTP 端口 SMTP_PORT=587 -# SMTP 用户名 -# ${SMTP_USER} — 替换为实际的 SMTP 用户名 -SMTP_USER=${SMTP_USER} +# SMTP 用户名(邮件功能上线后配置) +SMTP_USER= -# SMTP 密码 / 应用专用密码 -# ${SMTP_PASSWORD} — 替换为实际的 SMTP 密码 -SMTP_PASSWORD=${SMTP_PASSWORD} +# SMTP 密码(邮件功能上线后配置) +SMTP_PASSWORD= -# 发件人邮箱 -SMTP_FROM_EMAIL=noreply@xiaoxia-saas.com +# 发件人邮箱(邮件功能上线后配置) +SMTP_FROM_EMAIL= # 发件人显示名称 SMTP_FROM_NAME=小虾 SaaS @@ -170,7 +168,7 @@ MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY} MINIO_SECRET_KEY=${MINIO_SECRET_KEY} # MinIO Bucket 名称 -MINIO_BUCKET=${MINIO_BUCKET} +MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME} # 是否使用 SSL 连接 MinIO MINIO_USE_SSL=false @@ -224,21 +222,12 @@ COSYVOICE_FORMAT=mp3 # 音色克隆模型名(固定值) COSYVOICE_CLONE_MODEL=voice-enrollment +# DashScope 通用 API Key(与 CosyVoice 共用) +DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY} -# ==================== 豆包大模型(火山引擎方舟)==================== -# 豆包 API Key -# ${DOUBAO_API_KEY} — 替换为实际的豆包 API Key -DOUBAO_API_KEY=${DOUBAO_API_KEY} +# ==================== MediaKit 视频理解(火山引擎)==================== -# 模型名称 -DOUBAO_MODEL=doubao-seed-1-6-250615 - -# API 基础 URL -DOUBAO_BASE_URL=https://ark.cn-beijing.volces.com/api/v3 - -# 请求超时时间(秒) -DOUBAO_TIMEOUT=30 - -# 最大重试次数 -DOUBAO_MAX_RETRIES=2 +MEDIAKIT_API_KEY=${MEDIAKIT_API_KEY} +MEDIAKIT_BASE_URL=https://mediakit.cn-beijing.volces.com/api/v1 +MEDIAKIT_TIMEOUT=60 diff --git a/scripts/ci_staging_deploy.sh b/scripts/ci_staging_deploy.sh index 70aa0955c..9d8cefc39 100755 --- a/scripts/ci_staging_deploy.sh +++ b/scripts/ci_staging_deploy.sh @@ -55,7 +55,13 @@ if [ -z "$IMAGE_TAG" ]; then exit 1 fi -test -f "$ENV_FILE" +# .env 文件由 CI 从模板 + Secrets 渲染后通过 SCP 上传到服务器 +# 如果文件不存在,说明 CI 渲染步骤失败或未执行 +if [ ! -f "$ENV_FILE" ]; then + echo "ERROR: $ENV_FILE 不存在。CI 应先在 render_env 步骤渲染并上传此文件" + exit 1 +fi +echo "✅ .env file found: $ENV_FILE ($(wc -l < "$ENV_FILE") lines)" mkdir -p "$GENERATED_DIR" mkdir -p "$LEGACY_ASSETS_DIR" diff --git a/scripts/render_env.sh b/scripts/render_env.sh new file mode 100644 index 000000000..84724325a --- /dev/null +++ b/scripts/render_env.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# =========================================================== +# render_env.sh — 从模板 + Secrets 渲染 .env 文件 +# =========================================================== +# 用法: scripts/render_env.sh +# +# 输入: deploy/configs/.env.staging 或 .env.production 模板 +# 输出: .env.rendered(包含真实密钥,切勿提交或打印) +# +# 环境变量映射规则: +# STAGING_xxx / PRODUCTION_xxx → xxx(去掉环境前缀) +# 共用 secrets 直接使用(如 OSS_ACCESS_KEY_ID) +# =========================================================== +set -eu + +TARGET_ENV="${1:-}" + +if [ -z "$TARGET_ENV" ] || { [ "$TARGET_ENV" != "staging" ] && [ "$TARGET_ENV" != "production" ]; }; then + echo "ERROR: 用法: $0 " >&2 + exit 1 +fi + +TEMPLATE_FILE="deploy/configs/.env.${TARGET_ENV}" +OUTPUT_FILE=".env.rendered" + +if [ ! -f "$TEMPLATE_FILE" ]; then + echo "ERROR: 模板文件不存在: $TEMPLATE_FILE" >&2 + exit 1 +fi + +# 构建环境变量映射(带环境前缀的 secrets → 模板变量名) +ENV_PREFIX=$(echo "$TARGET_ENV" | tr '[:lower:]' '[:upper:]') + +# 需要映射的带环境前缀变量 +MAPPED_VARS="DATABASE_URL REDIS_URL CELERY_BROKER_URL CELERY_RESULT_BACKEND JWT_SECRET_KEY" + +# Staging 独有的 MinIO 变量 +if [ "$TARGET_ENV" = "staging" ]; then + MAPPED_VARS="$MAPPED_VARS MINIO_ENDPOINT MINIO_ACCESS_KEY MINIO_SECRET_KEY MINIO_BUCKET_NAME" +fi + +# 将带前缀的 secrets 导出为无前缀的环境变量 +for var in $MAPPED_VARS; do + prefixed_var="${ENV_PREFIX}_${var}" + value="${!prefixed_var:-}" + if [ -n "$value" ]; then + export "$var=$value" + fi +done + +# 共用 secrets 直接导出(如果存在) +SHARED_SECRETS="OSS_ACCESS_KEY_ID OSS_ACCESS_KEY_SECRET COSYVOICE_API_KEY DASHSCOPE_API_KEY MEDIAKIT_API_KEY" +for var in $SHARED_SECRETS; do + value="${!var:-}" + # 已经在环境中了,无需额外操作 +done + +# 使用 Python 进行变量替换(Python 在 CI runner 中一定存在) +python3 - "$TEMPLATE_FILE" "$OUTPUT_FILE" "$ENV_PREFIX" "$MAPPED_VARS" "$SHARED_SECRETS" <<'PYTHON_SCRIPT' +import sys +import os +import re + +template_file = sys.argv[1] +output_file = sys.argv[2] +env_prefix = sys.argv[3] +mapped_vars_str = sys.argv[4] +shared_secrets_str = sys.argv[5] + +# 收集所有可用的替换变量 +all_vars = set() +for v in mapped_vars_str.split(): + all_vars.add(v) +for v in shared_secrets_str.split(): + all_vars.add(v) + +# 读取模板 +with open(template_file, 'r') as f: + template = f.read() + +# 找出模板中所有的 ${VAR} 占位符(仅检查非注释行) +pattern = re.compile(r'\$\{(\w+)\}') +placeholders = set() +for line in template.splitlines(): + stripped = line.strip() + if stripped.startswith('#'): + continue + placeholders.update(pattern.findall(line)) + +# 检查必需变量是否已设置 +missing = [] +for var in placeholders: + value = os.environ.get(var, '') + if not value: + missing.append(var) + +if missing: + print(f"ERROR: 以下变量未设置或为空: {', '.join(sorted(missing))}", file=sys.stderr) + print(f"请确认对应的 {env_prefix}_xxx 或共用 secrets 已在 Gitea Secrets 中配置", file=sys.stderr) + sys.exit(1) + +# 执行替换 +def replace_var(match): + var_name = match.group(1) + return os.environ.get(var_name, match.group(0)) + +rendered = pattern.sub(replace_var, template) + +# 写入输出文件 +with open(output_file, 'w') as f: + f.write(rendered) + +# 设置文件权限为仅 owner 可读写 +os.chmod(output_file, 0o600) + +print(f"✅ .env 渲染完成: {template_file} → {output_file}") +print(f" 替换了 {len(placeholders)} 个变量") +PYTHON_SCRIPT + +# 验证输出文件 +if [ ! -f "$OUTPUT_FILE" ]; then + echo "ERROR: 渲染失败,输出文件不存在" >&2 + exit 1 +fi + +# 检查输出文件中是否还有未替换的占位符(仅检查非注释行) +if grep -vE '^\s*#' "$OUTPUT_FILE" | grep -qE '\$\{[A-Z_]+\}'; then + echo "ERROR: 输出文件中仍有未替换的占位符:" >&2 + grep -nE '\$\{[A-Z_]+\}' "$OUTPUT_FILE" | grep -v '^\s*#' >&2 + exit 1 +fi + +echo "✅ 渲染文件校验通过,无残留占位符" +echo "⚠️ $OUTPUT_FILE 包含敏感信息,请勿提交或打印到日志" -- 2.54.0 From b8d3f3aa161c63e092c6f941be9d9b71c6961a4e Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Wed, 2 Sep 2026 17:12:59 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=20PR=20#1630=20?= =?UTF-8?q?=E4=B8=89=E5=A4=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Production 模板 SMTP_HOST 改为空值(与实际一致) 2. ci-pipeline.yml MinIO Bucket Secret 名称修正为 STAGING_MINIO_BUCKET - render_env.sh 增加特殊映射:STAGING_MINIO_BUCKET → MINIO_BUCKET_NAME 3. 修正模板中与实际运行不一致的配置值: Staging: JWT_ACCESS_TOKEN_EXPIRE_MINUTES=1440, COSYVOICE_VOICE=longxiaoxia_v3, COSYVOICE_FORMAT=wav, CORS_ORIGINS_RAW 使用 staging-api Production: COSYVOICE_VOICE=longxiaoxia_v3, COSYVOICE_FORMAT=wav, CORS_ORIGINS_RAW 使用 api(非 www) --- .gitea/workflows/ci-pipeline.yml | 2 +- deploy/configs/.env.production | 8 ++++---- deploy/configs/.env.staging | 8 ++++---- scripts/render_env.sh | 10 +++++++++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/ci-pipeline.yml b/.gitea/workflows/ci-pipeline.yml index 162e0a3d3..e34885632 100755 --- a/.gitea/workflows/ci-pipeline.yml +++ b/.gitea/workflows/ci-pipeline.yml @@ -1180,7 +1180,7 @@ jobs: STAGING_MINIO_ENDPOINT: ${{ secrets.STAGING_MINIO_ENDPOINT }} STAGING_MINIO_ACCESS_KEY: ${{ secrets.STAGING_MINIO_ACCESS_KEY }} STAGING_MINIO_SECRET_KEY: ${{ secrets.STAGING_MINIO_SECRET_KEY }} - STAGING_MINIO_BUCKET_NAME: ${{ secrets.STAGING_MINIO_BUCKET_NAME }} + STAGING_MINIO_BUCKET: ${{ secrets.STAGING_MINIO_BUCKET }} OSS_ACCESS_KEY_ID: ${{ secrets.OSS_ACCESS_KEY_ID }} OSS_ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }} COSYVOICE_API_KEY: ${{ secrets.COSYVOICE_API_KEY }} diff --git a/deploy/configs/.env.production b/deploy/configs/.env.production index d4d1bf1f7..55ab74ff3 100644 --- a/deploy/configs/.env.production +++ b/deploy/configs/.env.production @@ -108,7 +108,7 @@ JWT_REFRESH_TOKEN_EXPIRE_DAYS=30 ENABLE_EMAIL_DELIVERY=false # SMTP 服务器地址 -SMTP_HOST=smtp.gmail.com +SMTP_HOST= # SMTP 端口 SMTP_PORT=587 @@ -155,7 +155,7 @@ OSS_DIRECT_UPLOAD_EXPIRE_SECONDS=900 # ==================== CORS 配置 ==================== # 允许跨域的前端域名列表,逗号分隔 -CORS_ORIGINS_RAW=https://xiaoxiajianji.com,https://www.xiaoxiajianji.com +CORS_ORIGINS_RAW=https://xiaoxiajianji.com,https://api.xiaoxiajianji.com # ==================== 生成文件路径 ==================== @@ -189,13 +189,13 @@ COSYVOICE_BASE_URL=https://dashscope.aliyuncs.com/api/v1 COSYVOICE_MODEL=cosyvoice-v3-flash # 音色:v3 系列系统音色带 _v3 后缀 -COSYVOICE_VOICE=longxiaochun_v3 +COSYVOICE_VOICE=longxiaoxia_v3 # 采样率 COSYVOICE_SAMPLE_RATE=22050 # 输出格式 -COSYVOICE_FORMAT=mp3 +COSYVOICE_FORMAT=wav # 音色克隆模型名(固定值) COSYVOICE_CLONE_MODEL=voice-enrollment diff --git a/deploy/configs/.env.staging b/deploy/configs/.env.staging index 6c58cf85a..538417191 100644 --- a/deploy/configs/.env.staging +++ b/deploy/configs/.env.staging @@ -96,7 +96,7 @@ JWT_SECRET_KEY=${JWT_SECRET_KEY} JWT_ALGORITHM=HS256 # Access Token 过期时间(分钟) -JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 +JWT_ACCESS_TOKEN_EXPIRE_MINUTES=1440 # Refresh Token 过期时间(天) JWT_REFRESH_TOKEN_EXPIRE_DAYS=30 @@ -177,7 +177,7 @@ MINIO_USE_SSL=false # ==================== CORS 配置 ==================== # 允许跨域的前端域名列表,逗号分隔 -CORS_ORIGINS_RAW=https://staging.xiaoxiajianji.com,https://staging-web.xiaoxiajianji.com +CORS_ORIGINS_RAW=https://staging.xiaoxiajianji.com,https://staging-api.xiaoxiajianji.com # ==================== 生成文件路径 ==================== @@ -211,13 +211,13 @@ COSYVOICE_BASE_URL=https://dashscope.aliyuncs.com/api/v1 COSYVOICE_MODEL=cosyvoice-v3-flash # 音色:v3 系列系统音色带 _v3 后缀 -COSYVOICE_VOICE=longxiaochun_v3 +COSYVOICE_VOICE=longxiaoxia_v3 # 采样率 COSYVOICE_SAMPLE_RATE=22050 # 输出格式 -COSYVOICE_FORMAT=mp3 +COSYVOICE_FORMAT=wav # 音色克隆模型名(固定值) COSYVOICE_CLONE_MODEL=voice-enrollment diff --git a/scripts/render_env.sh b/scripts/render_env.sh index 84724325a..42930f6e1 100644 --- a/scripts/render_env.sh +++ b/scripts/render_env.sh @@ -36,7 +36,7 @@ MAPPED_VARS="DATABASE_URL REDIS_URL CELERY_BROKER_URL CELERY_RESULT_BACKEND JWT_ # Staging 独有的 MinIO 变量 if [ "$TARGET_ENV" = "staging" ]; then - MAPPED_VARS="$MAPPED_VARS MINIO_ENDPOINT MINIO_ACCESS_KEY MINIO_SECRET_KEY MINIO_BUCKET_NAME" + MAPPED_VARS="$MAPPED_VARS MINIO_ENDPOINT MINIO_ACCESS_KEY MINIO_SECRET_KEY" fi # 将带前缀的 secrets 导出为无前缀的环境变量 @@ -48,6 +48,14 @@ for var in $MAPPED_VARS; do fi done +# 特殊映射:CI secret 名称与模板占位符不一致的变量 +# STAGING_MINIO_BUCKET → MINIO_BUCKET_NAME +if [ "$TARGET_ENV" = "staging" ]; then + if [ -n "${STAGING_MINIO_BUCKET:-}" ]; then + export "MINIO_BUCKET_NAME=$STAGING_MINIO_BUCKET" + fi +fi + # 共用 secrets 直接导出(如果存在) SHARED_SECRETS="OSS_ACCESS_KEY_ID OSS_ACCESS_KEY_SECRET COSYVOICE_API_KEY DASHSCOPE_API_KEY MEDIAKIT_API_KEY" for var in $SHARED_SECRETS; do -- 2.54.0