#!/usr/bin/env python3 """Expédie les alertes CI mises en file par le dashboard depuis l’hôte de recette.""" import json import subprocess import sys from email.message import EmailMessage from pathlib import Path OUTBOX = Path("/opt/manus-deploy/secrets/ci-alerts/outbox") ARCHIVE = Path("/var/log/manus-deploy/ci-alerts-email-sent.json") def send_alert(file_path: Path) -> None: payload = json.loads(file_path.read_text(encoding="utf-8")) recipient = str(payload.get("to", "")).strip() subject = str(payload.get("subject", "")).strip() text = str(payload.get("text", "")).strip() if not recipient or "@" not in recipient or not subject or not text: raise ValueError(f"Alerte CI invalide : {file_path.name}") message = EmailMessage() message["To"] = recipient message["From"] = "alertes-ci@itinova.org" message["Subject"] = subject message.set_content(text) subprocess.run(["/usr/sbin/sendmail", "-t", "-oi"], input=message.as_bytes(), check=True, timeout=30) ARCHIVE.parent.mkdir(parents=True, exist_ok=True) ARCHIVE.write_text(json.dumps({"id": payload.get("id"), "sentAt": payload.get("createdAt")}) + "\n", encoding="utf-8") file_path.unlink() def main() -> int: OUTBOX.mkdir(parents=True, exist_ok=True, mode=0o700) failures = [] for file_path in sorted(OUTBOX.glob("*.json")): try: send_alert(file_path) except Exception as error: # Le fichier reste en file pour réessai et investigation. print(f"CI_EMAIL_DISPATCH_FAILED {file_path.name}: {error}", file=sys.stderr) failures.append(file_path.name) if failures: return 1 print("CI_EMAIL_DISPATCH_OK") return 0 if __name__ == "__main__": raise SystemExit(main())