feat(config): Phase 4 — 修正模板 + 渲染脚本 + CI 部署改造 #1630

Merged
xiaoxia merged 2 commits from feat/config-phase4-env-render into develop 2026-09-02 17:42:42 +08:00
Owner

变更内容

第一部分:修正配置模板(7 处差异)

# 文件 修改
1 .env.staging MINIO_BUCKETMINIO_BUCKET_NAME(统一变量名)
2 两个文件 删除 DOUBAO_API_KEY 区块(两个环境都没在用)
3 两个文件 新增 DASHSCOPE_API_KEY(实际在用,模板漏了)
4 两个文件 新增 MediaKit 区块(3 个变量)
5 .env.staging DEBUG=true(staging 实际在用 true)
6 两个文件 ENABLE_EMAIL_DELIVERY=false(邮件功能未上线)
7 两个文件 SMTP 相关默认值改为空

第二部分:创建 env 渲染脚本

  • scripts/render_env.sh — 从模板 + Secrets 渲染 .env
  • 使用 Python 实现变量替换(CI runner 的 ci-base 镜像无 envsubst)
  • 支持 STAGING_xxx/PRODUCTION_xxx 前缀映射到模板变量
  • 自动校验所有必需变量已设置,缺一个就报错退出
  • 输出文件权限 600

第三部分:改造 CI 部署流程

  • deploy-staging job 新增 Render .env from template 步骤
    • 注入 19 个 Gitea Secrets 作为环境变量
    • 调用 render_env.sh staging 生成 .env.rendered
  • SSH deploy 前先 SCP .env.rendered 到服务器
    • 自动备份旧 .env(带时间戳)
  • 部署完成后清理 CI runner 上的渲染文件
  • ci_staging_deploy.sh 改为显式检查 .env 来源

安全

  • .env.rendered 加入 .gitignore
  • 渲染文件不打印到 CI 日志
  • CI 结束后清理临时文件
## 变更内容 ### 第一部分:修正配置模板(7 处差异) | # | 文件 | 修改 | |---|------|------| | 1 | .env.staging | `MINIO_BUCKET` → `MINIO_BUCKET_NAME`(统一变量名) | | 2 | 两个文件 | 删除 `DOUBAO_API_KEY` 区块(两个环境都没在用) | | 3 | 两个文件 | 新增 `DASHSCOPE_API_KEY`(实际在用,模板漏了) | | 4 | 两个文件 | 新增 MediaKit 区块(3 个变量) | | 5 | .env.staging | `DEBUG=true`(staging 实际在用 true) | | 6 | 两个文件 | `ENABLE_EMAIL_DELIVERY=false`(邮件功能未上线) | | 7 | 两个文件 | SMTP 相关默认值改为空 | ### 第二部分:创建 env 渲染脚本 - **scripts/render_env.sh** — 从模板 + Secrets 渲染 .env - 使用 Python 实现变量替换(CI runner 的 ci-base 镜像无 envsubst) - 支持 `STAGING_xxx`/`PRODUCTION_xxx` 前缀映射到模板变量 - 自动校验所有必需变量已设置,缺一个就报错退出 - 输出文件权限 600 ### 第三部分:改造 CI 部署流程 - deploy-staging job 新增 `Render .env from template` 步骤 - 注入 19 个 Gitea Secrets 作为环境变量 - 调用 `render_env.sh staging` 生成 `.env.rendered` - SSH deploy 前先 SCP `.env.rendered` 到服务器 - 自动备份旧 `.env`(带时间戳) - 部署完成后清理 CI runner 上的渲染文件 - `ci_staging_deploy.sh` 改为显式检查 `.env` 来源 ### 安全 - `.env.rendered` 加入 `.gitignore` - 渲染文件不打印到 CI 日志 - CI 结束后清理临时文件
xiaoxia added 1 commit 2026-09-02 17:03:38 +08:00
feat(config): Phase 4 — 修正模板 + 渲染脚本 + CI 部署改造
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 1s
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 / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (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 3m47s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m36s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 4m40s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 5m4s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 5m49s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 5m59s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 6m12s
AI Code Review / AI Code Review (pull_request) Successful in 6m38s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 6m43s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 9m22s
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
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
459cf61495
第一部分:修正配置模板(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

🚀 预览环境已部署

项目 详情
PR号 #1630
预览链接 https://pr-1630.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1630 | | 预览链接 | [https://pr-1630.preview.xiaoxiajianji.com](https://pr-1630.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia added 1 commit 2026-09-02 17:13:23 +08:00
fix: 修正 PR #1630 三处问题
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 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (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 / Retag skipped Staging 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 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 Worker Image (pull_request) Successful in 3m32s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m43s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 4m35s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m47s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m55s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m58s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 5m36s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 5m41s
AI Code Review / AI Code Review (pull_request) Successful in 9m59s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 10m41s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 21m53s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 3s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 3m34s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 6m14s
b8d3f3aa16
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)
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:否
  • 阻塞级问题数量:0 个

📊 审查概览

  • 整体评价:通过
  • 建议级问题数量:3 个

🔴 阻塞级问题(必须修复)

💡 改进建议(不阻塞合并)

  1. [deploy/configs/.env.staging: 19] Staging 环境开启 Debug 模式

    • 具体内容:DEBUG=true 在 Staging 环境中开启。虽然这有助于排查问题,但如果 Staging 环境对外暴露,Debug 模式可能会泄露详细的堆栈信息、配置信息等敏感数据。建议仅在必要时临时开启,或确保 Staging 环境有严格的访问控制。
  2. [deploy/configs/.env.staging: 180 & deploy/configs/.env.production: 162] CORS 配置包含 API 域名

    • 具体内容:CORS_ORIGINS_RAW 中包含了 staging-api.xiaoxiajianji.comapi.xiaoxiajianji.com。通常 CORS 用于配置允许访问的前端域名,API 域名自身通常不需要加入 CORS 列表(除非有特殊的前端服务部署在该子域下)。请确认这是否符合预期,防止配置过于宽松。
  3. [scripts/render_env.sh: 102] Python 脚本中存在未使用的变量

    • 具体内容:Python 脚本中定义了集合 all_vars 并向其中添加了元素,但后续代码中并未实际使用该集合进行任何逻辑判断或操作。虽然不影响功能,但属于无效代码,建议删除以保持代码整洁。

良好实践

  1. 安全性render_env.sh 脚本在生成包含敏感信息的文件后,立即使用 os.chmod(output_file, 0o600) 限制权限,且在 CI 流程结束后执行 rm -f .env.rendered 清理,有效防止了敏感信息在 CI Runner 上的残留。
  2. 健壮性:脚本使用了 set -eu,并在 Python 脚本中显式检查了所有模板中的占位符是否都被替换,如果存在未设置的变量会直接报错退出,避免了因配置缺失导致的服务运行时错误。
  3. 可维护性:通过引入模板渲染机制,将配置模板与真实 Secrets 分离,使得配置文件可以安全地提交到代码库中,提升了 CI/CD 流程的规范性和安全性。
  4. 容错性:在 ci-pipeline.yml 的上传步骤中,先对旧 .env 文件进行备份(cp ... .env.bak...),并在文件不存在时忽略错误,这是一个很好的回滚保护机制。

格式检查通过 | 逻辑审查通过 | 性能良好


🤖 由 AI 代码审查机器人自动生成 | 2026-09-02 09:23:17 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:否 - 阻塞级问题数量:0 个 ### 📊 审查概览 - 整体评价:通过 - 建议级问题数量:3 个 ### 🔴 阻塞级问题(必须修复) 无 ### 💡 改进建议(不阻塞合并) 1. **[deploy/configs/.env.staging: 19] Staging 环境开启 Debug 模式** - 具体内容:`DEBUG=true` 在 Staging 环境中开启。虽然这有助于排查问题,但如果 Staging 环境对外暴露,Debug 模式可能会泄露详细的堆栈信息、配置信息等敏感数据。建议仅在必要时临时开启,或确保 Staging 环境有严格的访问控制。 2. **[deploy/configs/.env.staging: 180 & deploy/configs/.env.production: 162] CORS 配置包含 API 域名** - 具体内容:`CORS_ORIGINS_RAW` 中包含了 `staging-api.xiaoxiajianji.com` 和 `api.xiaoxiajianji.com`。通常 CORS 用于配置允许访问的前端域名,API 域名自身通常不需要加入 CORS 列表(除非有特殊的前端服务部署在该子域下)。请确认这是否符合预期,防止配置过于宽松。 3. **[scripts/render_env.sh: 102] Python 脚本中存在未使用的变量** - 具体内容:Python 脚本中定义了集合 `all_vars` 并向其中添加了元素,但后续代码中并未实际使用该集合进行任何逻辑判断或操作。虽然不影响功能,但属于无效代码,建议删除以保持代码整洁。 ### ✅ 良好实践 1. **安全性**:`render_env.sh` 脚本在生成包含敏感信息的文件后,立即使用 `os.chmod(output_file, 0o600)` 限制权限,且在 CI 流程结束后执行 `rm -f .env.rendered` 清理,有效防止了敏感信息在 CI Runner 上的残留。 2. **健壮性**:脚本使用了 `set -eu`,并在 Python 脚本中显式检查了所有模板中的占位符是否都被替换,如果存在未设置的变量会直接报错退出,避免了因配置缺失导致的服务运行时错误。 3. **可维护性**:通过引入模板渲染机制,将配置模板与真实 Secrets 分离,使得配置文件可以安全地提交到代码库中,提升了 CI/CD 流程的规范性和安全性。 4. **容错性**:在 `ci-pipeline.yml` 的上传步骤中,先对旧 `.env` 文件进行备份(`cp ... .env.bak...`),并在文件不存在时忽略错误,这是一个很好的回滚保护机制。 --- ✅ 格式检查通过 | ✅ 逻辑审查通过 | ✅ 性能良好 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-09-02 09:23:17 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
auto-approve-bot approved these changes 2026-09-02 17:31:00 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-09-02 17:31:00 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
xiaoxia merged commit 77269802d0 into develop 2026-09-02 17:42:42 +08:00

🗑️ 预览环境已清理

PR #1630 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1630 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.