Release beta 1.1.2.1019
check / local-gate (push) Failing after 53s

This commit is contained in:
JWeBot Contributors
2026-10-19 16:56:59 +08:00
parent 522e349491
commit ddebe075d7
30 changed files with 1433 additions and 46 deletions
+87 -9
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Apply the mandatory post-release grant and group announcement."""
"""Apply the mandatory release lifecycle notices, grant, and announcement."""
from __future__ import annotations
@@ -39,6 +39,8 @@ PRIMOGEM_COMPENSATION_RELEASES = {
MAX_BALANCE = 1_000_000_000
MAX_SUMMARY_CHARS = 300
MAX_ANNOUNCEMENT_CHARS = 900
MAX_LIFECYCLE_CHARS = 300
LIFECYCLE_STAGES = frozenset({"shutdown", "startup"})
RELEASE_PATTERN = re.compile(
r"^beta (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.(?P<date>\d{4})$"
)
@@ -140,6 +142,24 @@ def build_announcement(release: str, summary: str) -> str:
return announcement
def build_lifecycle_message(release: str, stage: str) -> str:
if stage == "shutdown":
message = (
f"Taffy 准备停机更新到 {release},会短暂离线一下;"
"别慌,我很快回来喵"
)
elif stage == "startup":
message = (
f"Taffy 刚上线,正在做 {release} 的最后自检;"
"确认就绪后会发送更新内容和补偿说明喵"
)
else:
raise ReleaseUpdateError(f"unsupported lifecycle stage: {stage}")
if len(message) > MAX_LIFECYCLE_CHARS:
raise ReleaseUpdateError("release lifecycle message is too long")
return message
def compensation_key(release: str) -> str:
return f"release_compensation:{release}"
@@ -157,6 +177,23 @@ def release_slug(release: str) -> str:
return re.sub(r"[^a-zA-Z0-9]+", "-", release).strip("-").lower()
def release_groups(database_path: Path) -> list[str]:
connection = sqlite3.connect(f"file:{database_path}?mode=ro", uri=True)
try:
if connection.execute("PRAGMA quick_check").fetchone()[0] != "ok":
raise ReleaseUpdateError("Edge SQLite integrity check failed")
rows = connection.execute(
"""
SELECT DISTINCT group_fingerprint
FROM player_accounts
ORDER BY group_fingerprint
"""
).fetchall()
finally:
connection.close()
return [str(row[0]) for row in rows]
def checked_marker(raw: str, release: str) -> dict[str, Any]:
expected_primogems = primogem_compensation_amount(release)
try:
@@ -566,6 +603,34 @@ def run_release_update(
}
def run_release_lifecycle(
*,
release_file: Path,
database_path: Path,
delivery_helper: Path,
stage: str,
deliverer: Callable[[Path, str, str, str], None] = run_delivery_helper,
) -> dict[str, Any]:
if stage not in LIFECYCLE_STAGES:
raise ReleaseUpdateError(f"unsupported lifecycle stage: {stage}")
release = read_release(release_file)
message = build_lifecycle_message(release, stage)
groups = release_groups(database_path)
delivered = 0
for group in groups:
group_hash = hashlib.sha256(group.encode()).hexdigest()[:12]
event_id = f"release-{release_slug(release)}-{stage}-{group_hash}"
deliverer(delivery_helper, group, message, event_id)
delivered += 1
return {
"status": "ok",
"release": release,
"stage": stage,
"groups": len(groups),
"delivered": delivered,
}
def parse_args() -> argparse.Namespace:
home = Path.home()
parser = argparse.ArgumentParser(description=__doc__)
@@ -599,20 +664,33 @@ def parse_args() -> argparse.Namespace:
action="store_true",
help="retry only after visually confirming that the prior send did not land",
)
parser.add_argument(
"--lifecycle-stage",
choices=sorted(LIFECYCLE_STAGES),
help="send a guarded lifecycle notice instead of release settlement",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
try:
result = run_release_update(
release_file=args.release_file,
changelog=args.changelog,
database_path=args.database,
backup_dir=args.backup_dir,
delivery_helper=args.delivery_helper,
retry_uncertain=args.retry_uncertain_announcement,
)
if args.lifecycle_stage:
result = run_release_lifecycle(
release_file=args.release_file,
database_path=args.database,
delivery_helper=args.delivery_helper,
stage=args.lifecycle_stage,
)
else:
result = run_release_update(
release_file=args.release_file,
changelog=args.changelog,
database_path=args.database,
backup_dir=args.backup_dir,
delivery_helper=args.delivery_helper,
retry_uncertain=args.retry_uncertain_announcement,
)
except ReleaseUpdateError as error:
print(
json.dumps(