2a739dee17
CI/CD Pipeline / Check push changed paths (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 / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web 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 51s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m7s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m27s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m0s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m9s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 4m41s
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 5m0s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 10m11s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 18m38s
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 2s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
问题7(generate-copy 提速,目标 30-40s):
- 新增 doubao_fast_model 配置(默认 doubao-1-5-pro-32k-250115),结构化输出任务(意图解析/编导脚本/合规审核)改用快模型,不再使用慢推理模型 doubao-seed-1-6
- call_llm 扩展支持 model/max_tokens/system_prompt 参数;chat_completion 同步支持 model 覆盖
- 编导脚本 temperature 0.8 + max_tokens 2500(从 4096 收紧);意图解析 max_tokens 800;审核 max_tokens 500
- _SCRIPT_GENERATION_PROMPT 精简冗余描述(前导说明和关键要求章节从 ~70 行压到 ~30 行),减少输入/输出 token
- 合规审核异步后置:阶段2 generate-copy 只做关键字黑名单快速检查(不调用 LLM),LLM 深度审核移到阶段3 confirm-copy TTS 之前执行,不再阻塞前端展示脚本
- 新增 _quick_compliance_blacklist_check 处理常见广告法绝对化用语
问题8(细粒度 phase + phase_message):
- ViralVideoJob 新增 phase_message 字段(中文提示文案,前端轮询直接展示)
- SQLAlchemy ViralVideoJobModel 新增 current_stage/phase_message 列(current_stage 原已有但未持久化更新)
- repo 层 _to_domain/save/update 同步处理新字段
- alembic 090 迁移:幂等 ADD COLUMN phase_message VARCHAR(500)
- 新增 _set_stage 辅助:统一设置 current_stage + phase_message + Redis 推送 + DB 持久化
- 所有 celery task(analyze/generate-copy/render/one-click/resume)在关键节点调用 _set_stage 持久化阶段信息
- 阶段文案:analyzing_images→正在分析商品特征 / parsing_intent→正在解析文案意图 / generating_script→正在编排分镜脚本 / reviewing→合规审核中 / tts→正在合成AI配音 / rendering→正在生成视频 / uploading→正在上传视频
- ViralVideoJobResponse schema + _to_response 增加 current_stage/phase_message,前端轮询 GET /{job_id} 直接拿到
配套:
- .env.example + render_env.sh SHARED_SECRETS 补 DOUBAO_FAST_MODEL
- tests _FakeSettings/_make_job 同步新增字段
- _run_render_pipeline 兜底补生成分支不再同步调用 _step_review(由出片前统一审核处理)
143 lines
4.6 KiB
Bash
143 lines
4.6 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_FAST_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 包含敏感信息,请勿提交或打印到日志"
|