From f9c012098f7322984c1d623d451b46b10cd2255c Mon Sep 17 00:00:00 2001 From: Xiaoxia AI Date: Sun, 21 Jun 2026 14:09:29 +0800 Subject: [PATCH] chore(release): allow smtp skip in strict smoke --- docs/PRODUCTION-RELEASE-CHECKLIST.md | 10 +++++----- scripts/smoke_external_services.py | 22 +++++++++++++++++----- tests/unit/test_smoke_external_services.py | 11 +++++++++++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/docs/PRODUCTION-RELEASE-CHECKLIST.md b/docs/PRODUCTION-RELEASE-CHECKLIST.md index 3956a20fb..2d742db2a 100644 --- a/docs/PRODUCTION-RELEASE-CHECKLIST.md +++ b/docs/PRODUCTION-RELEASE-CHECKLIST.md @@ -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 生命周期与生成文件保留 diff --git a/scripts/smoke_external_services.py b/scripts/smoke_external_services.py index c8787828d..a21176b95 100644 --- a/scripts/smoke_external_services.py +++ b/scripts/smoke_external_services.py @@ -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 diff --git a/tests/unit/test_smoke_external_services.py b/tests/unit/test_smoke_external_services.py index 92400bac6..4c1de4012 100644 --- a/tests/unit/test_smoke_external_services.py +++ b/tests/unit/test_smoke_external_services.py @@ -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 = []