diff --git a/src/padelnomics/supervisor.py b/src/padelnomics/supervisor.py index 080fa22..02ccfbe 100644 --- a/src/padelnomics/supervisor.py +++ b/src/padelnomics/supervisor.py @@ -17,14 +17,12 @@ Usage: """ import importlib -import json import logging import os import subprocess import sys import time import tomllib -import urllib.request from collections import defaultdict from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import UTC, datetime @@ -269,14 +267,46 @@ def run_export() -> None: send_alert(f"[export] {err}") +_last_seen_head: str | None = None + + def web_code_changed() -> bool: - """Check if web app code or secrets changed since last deploy (after git pull).""" + """True on the first tick after a commit that changed web app code or secrets. + + Compares the current HEAD to the HEAD from the previous tick. On first call + after process start (e.g. after os.execv reloads new code), falls back to + HEAD~1 so the just-deployed commit is evaluated exactly once. + + Records HEAD before returning so the same commit never triggers twice. + """ + global _last_seen_head result = subprocess.run( - ["git", "diff", "--name-only", "HEAD~1", "HEAD", "--", + ["git", "rev-parse", "HEAD"], capture_output=True, text=True, timeout=10, + ) + if result.returncode != 0: + return False + current_head = result.stdout.strip() + + if _last_seen_head is None: + # Fresh process — use HEAD~1 as base (evaluates the newly deployed tag). + base_result = subprocess.run( + ["git", "rev-parse", "HEAD~1"], capture_output=True, text=True, timeout=10, + ) + base = base_result.stdout.strip() if base_result.returncode == 0 else current_head + else: + base = _last_seen_head + + _last_seen_head = current_head # advance now — won't fire again for this HEAD + + if base == current_head: + return False + + diff = subprocess.run( + ["git", "diff", "--name-only", base, current_head, "--", "web/", "Dockerfile", ".env.prod.sops"], capture_output=True, text=True, timeout=30, ) - return bool(result.stdout.strip()) + return bool(diff.stdout.strip()) def current_deployed_tag() -> str | None: