0cf7f14992
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m4s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m17s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 3m55s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m9s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 4m21s
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Has been cancelled
问题4:图片分析提速 - 新增 doubao_vision_lite_model 配置(默认 doubao-1-5-vision-lite-250915)+ doubao_vision_use_lite 开关 - call_vision 支持 model/max_tokens/temperature/timeout/system_prompt 参数覆盖 - _step_image_analysis 改 ThreadPoolExecutor 并行调用 VLM(max_workers=min(4,n_images)),lite 模型 timeout=30s,max_tokens=1024 - 图片直接传公网 OSS URL 给豆包视觉,无需本地下载-上传链路(原流程已是直传,保持) 问题5:VLM 商品描述增强(对齐竞品截图2粒度) - 新 _IMAGE_ANALYSIS_SYSTEM_PROMPT 要求输出 16 个字段:name/brand/category/spec/appearance/packaging/text_on_package/colors/material_or_texture/key_features/visual_style/scene/suitable_scenes/target_audience/selling_points/summary - appearance(外观80-150字)+packaging(包装80-150字)要求自然语言细节描述,summary(150-250字)直接给前端展示 - 严禁编造:看不清/没有的统一填「无法判断」,text_on_package 只 OCR 清晰可见的 - _build_products_summary 优先用 VLM 返回的 summary 段(自然段落给编导模型效果最好),兜底再拼结构化字段 - _analyze_single_image 独立函数,所有新字段都有 setdefault 防御,兼容旧字段名 问题6:爆款结构(copy_structure → viral_structure)透传 - 后端现有 schema 已支持 viral_structure 字段,STEP2 generate-copy 也已传,本次把 viral_structure 注入 _SCRIPT_GENERATION_PROMPT - prompt 新增「爆款结构」字段+关键要求第8条:必须严格按该结构节奏/段落顺序编排镜头台词 - 前端 STRUCTURES 从 4 个扩展到 19 个(按协调 Agent 提供的中文列表) - 一键路径 generateViralVideo 已传 viral_structure,无需改动 其它: - .env.example 补 DOUBAO_VISION_MODEL/LITE_MODEL/USE_LITE 三个配置项 - scripts/render_env.sh 把新变量加入 SHARED_SECRETS 白名单 验收:单图分析目标 10-15s(lite 模型+并行),VLM 返回 6 维度丰富描述+summary,copy_structure 影响文案结构
143 lines
4.5 KiB
Bash
143 lines
4.5 KiB
Bash
#!/usr/bin/env bash
|
||
# ===========================================================
|
||
# render_env.sh — 从模板 + Secrets 渲染 .env 文件
|
||
# ===========================================================
|
||
# 用法: scripts/render_env.sh <staging|production>
|
||
#
|
||
# 输入: 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 <staging|production>" >&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"
|
||
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
|
||
|
||
# 特殊映射: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 DOUBAO_API_KEY DOUBAO_MODEL DOUBAO_BASE_URL DOUBAO_VISION_MODEL DOUBAO_VISION_LITE_MODEL DOUBAO_VISION_USE_LITE WECHAT_APP_ID WECHAT_APP_SECRET TIKHUB_API_KEY APIZERO_API_KEY GPU_WORKER_TOKEN"
|
||
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 包含敏感信息,请勿提交或打印到日志"
|