chore(release): allow smtp skip in strict smoke

This commit is contained in:
Xiaoxia AI
2026-06-21 14:09:29 +08:00
parent 2a9585054c
commit f9c012098f
3 changed files with 33 additions and 10 deletions
+5 -5
View File
@@ -23,8 +23,8 @@
- `GENERATED_FILES_HOST_DIR` 生产环境不得指向 staging 目录。
- 本地校验文件:`python scripts/validate_release_env.py /var/lib/xiaoxia-saas-production/.env --strict-external`。
- 容器内校验已注入环境:`docker exec xiaoxia-api-production python /app/scripts/validate_release_env.py --from-environ --strict-external`。
- 外部服务 smoke:`docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict`。
- SMTP 真发信 smoke:`docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict --send-email-to <测试邮箱>`。
- 外部服务 smoke:`docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict --skip-smtp`(SMTP 未启用时)。
- SMTP 真发信 smoke(启用邮件前必须执行):`docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict --send-email-to <测试邮箱>`。
- 如开启邮件/session:
- `ENABLE_EMAIL_DELIVERY=true` 前先验证 SMTP 凭证。
- `ENABLE_REDIS_SESSIONS=true` 前先验证 Redis 连通性。
@@ -88,17 +88,17 @@ docker exec xiaoxia-postgres psql -U xiaoxia -d xiaoxia_saas -Atc "select count(
```bash
docker exec xiaoxia-api-production python /app/scripts/validate_release_env.py --from-environ --strict-external
docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict
docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict --skip-smtp
docker exec xiaoxia-api-production python /app/scripts/smoke_external_services.py --strict --send-email-to <测试邮箱>
```
Staging 当前验证状态(2026-06-21):
- Redis session smoke:通过。
- SMTP strict smoke:阻塞,缺少 SMTP 环境变量/真实凭证。
- SMTP strict smoke:MVP 阶段允许 `--skip-smtp`,但启用 `ENABLE_EMAIL_DELIVERY=true` 前必须补真实 SMTP 凭证和真发信 smoke。
- OSS strict smoke:阻塞,缺少 OSS 环境变量/真实凭证。
缺少真实凭证时不得把 `ENABLE_EMAIL_DELIVERY=true` 或 OSS 生产上传作为已验收项。
缺少真实 OSS 凭证时不得把生产上传作为已验收项。SMTP 若暂不启用,必须保持 `ENABLE_EMAIL_DELIVERY=false` 并在 strict smoke 中显式使用 `--skip-smtp`。
## 6. OSS 生命周期与生成文件保留
+17 -5
View File
@@ -110,17 +110,29 @@ def smoke_oss(strict: bool) -> None:
print("OK oss upload/download/delete")
def main() -> int:
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--strict", action="store_true", help="Fail when disabled/unconfigured services are missing.")
parser.add_argument("--skip-smtp", action="store_true", help="Skip SMTP smoke when email delivery is intentionally disabled.")
parser.add_argument("--skip-redis", action="store_true", help="Skip Redis session smoke when sessions are intentionally disabled.")
parser.add_argument("--skip-oss", action="store_true", help="Skip OSS smoke when object storage is intentionally disabled.")
parser.add_argument(
"--send-email-to", help="Actually send a test email to this address. Otherwise SMTP only connects/logs in."
)
args = parser.parse_args()
args = parser.parse_args(argv)
smoke_redis(args.strict)
smoke_smtp(args.strict, args.send_email_to)
smoke_oss(args.strict)
if args.skip_redis:
print("SKIP redis sessions: explicitly skipped")
else:
smoke_redis(args.strict)
if args.skip_smtp:
print("SKIP smtp: explicitly skipped")
else:
smoke_smtp(args.strict, args.send_email_to)
if args.skip_oss:
print("SKIP oss: explicitly skipped")
else:
smoke_oss(args.strict)
print("OK external service smoke complete")
return 0
@@ -62,6 +62,17 @@ def test_external_smoke_redis_round_trip(monkeypatch, capsys):
assert "OK redis sessions" in capsys.readouterr().out
def test_external_smoke_can_skip_smtp_in_strict_mode(monkeypatch, capsys):
monkeypatch.setattr(smoke, "smoke_redis", lambda strict: print("OK redis sessions"))
monkeypatch.setattr(smoke, "smoke_oss", lambda strict: print("OK oss upload/download/delete"))
assert smoke.main(["--strict", "--skip-smtp"]) == 0
output = capsys.readouterr().out
assert "SKIP smtp: explicitly skipped" in output
assert "OK oss upload/download/delete" in output
def test_external_smoke_smtp_connect_login(monkeypatch, capsys):
actions = []