Compare commits
1 Commits
v202603100
...
v202603101
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
511a0ebac7 |
@@ -267,48 +267,6 @@ def run_export() -> None:
|
||||
send_alert(f"[export] {err}")
|
||||
|
||||
|
||||
_last_seen_head: str | None = None
|
||||
|
||||
|
||||
def web_code_changed() -> bool:
|
||||
"""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", "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(diff.stdout.strip())
|
||||
|
||||
|
||||
def current_deployed_tag() -> str | None:
|
||||
"""Return the highest-version tag pointing at HEAD, or None.
|
||||
|
||||
@@ -360,6 +318,15 @@ def git_pull_and_sync() -> None:
|
||||
run_shell("uv sync --all-packages")
|
||||
# Apply any model changes (FULL→INCREMENTAL, new models, etc.) before re-exec
|
||||
run_shell("uv run sqlmesh -p transform/sqlmesh_padelnomics plan prod --auto-apply")
|
||||
# Always redeploy the web app on new tag — blue/green swap is zero-downtime
|
||||
# and Docker layer caching makes no-op builds fast. Previous approach of
|
||||
# diffing HEAD~1 missed changes inside merge commits.
|
||||
logger.info("Deploying web app (blue/green swap)")
|
||||
ok, err = run_shell("./deploy.sh")
|
||||
if ok:
|
||||
send_alert(f"[deploy] {latest} ok")
|
||||
else:
|
||||
send_alert(f"[deploy] {latest} failed: {err}")
|
||||
# Re-exec so the new code is loaded. os.execv replaces this process in-place;
|
||||
# systemd sees it as the same PID and does not restart the unit.
|
||||
logger.info("Deploy complete — re-execing to load new code")
|
||||
@@ -408,14 +375,6 @@ def tick() -> None:
|
||||
# Export serving tables
|
||||
run_export()
|
||||
|
||||
# Deploy web app if code changed
|
||||
if os.getenv("SUPERVISOR_GIT_PULL") and web_code_changed():
|
||||
logger.info("Web code changed — deploying")
|
||||
ok, err = run_shell("./deploy.sh")
|
||||
if ok:
|
||||
send_alert("[deploy] ok")
|
||||
else:
|
||||
send_alert(f"[deploy] failed: {err}")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user