四个生产工作流改用同一条发布修订:最近一次代码门禁成功的提交可以发布,后面只多文档不再挡住。生产环境拒绝测试验证码。63 个还没上生产的迁移写了分级、演练脚本和首发步骤。没有点任何生产按钮。 自测:发布修订 7 通过,演练安全 3 通过,tsc 0 错,lint 0 error。本机空库演练在服务角色读人物表处按设计停止(退出码 4,其他人物已确认行数为 0)。 Co-Authored-By: Grok (agent loop)
66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
"""Safety checks for the disposable migration rehearsal. No production database."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SCRIPT = ROOT / "deploy" / "rehearse-production-migrations.sh"
|
|
GIT_BASH = Path(r"D:\Program Files\Git\bin\bash.exe")
|
|
BASH = str(GIT_BASH) if GIT_BASH.exists() else "bash"
|
|
|
|
|
|
def run(env: dict[str, str]) -> subprocess.CompletedProcess[str]:
|
|
full = os.environ.copy()
|
|
full.update(env)
|
|
return subprocess.run(
|
|
[BASH, str(SCRIPT)],
|
|
cwd=ROOT,
|
|
env=full,
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
errors="replace",
|
|
)
|
|
|
|
|
|
def test_refuses_a_non_production_path() -> None:
|
|
completed = run({"DEPLOY_PATH": "/tmp/not-production"})
|
|
assert completed.returncode == 1
|
|
assert "unexpected production path" in completed.stderr
|
|
|
|
|
|
def test_refuses_the_production_database_name() -> None:
|
|
completed = run(
|
|
{
|
|
"JYOTISHA_REHEARSAL_LOCAL": "1",
|
|
"JYOTISHA_REHEARSAL_DATABASE_URL": "postgresql://postgres:secret-value@127.0.0.1:1/jyotisha",
|
|
}
|
|
)
|
|
assert completed.returncode == 1
|
|
assert "refusing to touch the production database" in completed.stderr
|
|
assert "secret-value" not in completed.stdout
|
|
assert "secret-value" not in completed.stderr
|
|
|
|
|
|
def test_plan_keeps_the_stop_file_out_of_the_first_batch() -> None:
|
|
completed = run(
|
|
{
|
|
"JYOTISHA_REHEARSAL_LOCAL": "1",
|
|
"JYOTISHA_REHEARSAL_PLAN": "1",
|
|
"JYOTISHA_REHEARSAL_DATABASE_URL": "postgresql://postgres:secret-value@127.0.0.1:1/rehearse_plan",
|
|
}
|
|
)
|
|
assert completed.returncode == 0, completed.stderr
|
|
text = completed.stdout
|
|
assert "rehearsal_plan=1" in text
|
|
assert "database_name=rehearse_plan" in text
|
|
assert "stop_before=20260925030000_chart_subject_trust_and_limit.sql" in text
|
|
assert "stop_in_before=no" in text
|
|
values = dict(line.split("=", 1) for line in text.splitlines() if "=" in line)
|
|
assert int(values["batch_before"]) < int(values["batch_all"])
|
|
assert "secret-value" not in completed.stdout
|
|
assert "secret-value" not in completed.stderr
|